Commit cd7a73b1 by 张乐 Committed by GitHub

Merge pull request #420 from nobodyiam/apollo-client-refactor

Refactor apollo client, add tooling support and add helper methods for Date, Enum, Duration.
parents 68bc2e16 1cf492cb
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>apollo</artifactId>
<groupId>com.ctrip.framework.apollo</groupId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apollo-biz</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
package com.ctrip.framework.apollo;
import java.util.Date;
import java.util.Locale;
import java.util.Set;
/**
......@@ -10,7 +12,7 @@ public interface Config {
* Return the property value with the given key, or {@code defaultValue} if the key doesn't exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value
*/
public String getProperty(String key, String defaultValue);
......@@ -20,9 +22,8 @@ public interface Config {
* doesn't exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as integer
* @throws NumberFormatException if the property value is invalid
*/
public Integer getIntProperty(String key, Integer defaultValue);
......@@ -31,9 +32,8 @@ public interface Config {
* exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as long
* @throws NumberFormatException if the property value is invalid
*/
public Long getLongProperty(String key, Long defaultValue);
......@@ -42,9 +42,8 @@ public interface Config {
* exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as short
* @throws NumberFormatException if the property value is invalid
*/
public Short getShortProperty(String key, Short defaultValue);
......@@ -53,9 +52,8 @@ public interface Config {
* exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as float
* @throws NumberFormatException if the property value is invalid
*/
public Float getFloatProperty(String key, Float defaultValue);
......@@ -64,9 +62,8 @@ public interface Config {
* exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as double
* @throws NumberFormatException if the property value is invalid
*/
public Double getDoubleProperty(String key, Double defaultValue);
......@@ -75,9 +72,8 @@ public interface Config {
* exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as byte
* @throws NumberFormatException if the property value is invalid
*/
public Byte getByteProperty(String key, Byte defaultValue);
......@@ -86,22 +82,86 @@ public interface Config {
* doesn't exist.
*
* @param key the property name
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
* @return the property value as boolean
*/
public Boolean getBooleanProperty(String key, Boolean defaultValue);
/**
* Return the array property value with the given key, or {@code defaultValue} if the key doesn't
* exist.
* Return the array property value with the given key, or {@code defaultValue} if the key doesn't exist.
*
* @param key the property name
* @param delimiter the delimiter regex
* @param defaultValue the default value when key is not found
* @param defaultValue the default value when key is not found or any error occurred
*/
public String[] getArrayProperty(String key, String delimiter, String[] defaultValue);
/**
* Return the Date property value with the given name, or {@code defaultValue} if the name doesn't exist.
* Will try to parse the date with Locale.US and formats as follows: yyyy-MM-dd HH:mm:ss.SSS,
* yyyy-MM-dd HH:mm:ss and yyyy-MM-dd
*
* @param key the property name
* @param defaultValue the default value when name is not found or any error occurred
* @return the property value
*/
public Date getDateProperty(String key, Date defaultValue);
/**
* Return the Date property value with the given name, or {@code defaultValue} if the name doesn't exist.
* Will parse the date with the format specified and Locale.US
*
* @param key the property name
* @param format the date format, see {@link java.text.SimpleDateFormat} for more
* information
* @param defaultValue the default value when name is not found or any error occurred
* @return the property value
*/
public Date getDateProperty(String key, String format, Date defaultValue);
/**
* Return the Date property value with the given name, or {@code defaultValue} if the name doesn't exist.
*
* @param key the property name
* @param format the date format, see {@link java.text.SimpleDateFormat} for more
* information
* @param locale the locale to use
* @param defaultValue the default value when name is not found or any error occurred
* @return the property value
*/
public Date getDateProperty(String key, String format, Locale locale, Date defaultValue);
/**
* Return the Enum property value with the given key, or {@code defaultValue} if the key doesn't exist.
*
* @param key the property name
* @param enumType the enum class
* @param defaultValue the default value when key is not found or any error occurred
* @param <T> the enum
* @return the property value
*/
public <T extends Enum<T>> T getEnumProperty(String key, Class<T> enumType, T defaultValue);
/**
* Return the duration property value(in milliseconds) with the given name, or {@code
* defaultValue} if the name doesn't exist. Please note the format should comply with the follow
* example (case insensitive). Examples:
* <pre>
* "123MS" -- parses as "123 milliseconds"
* "20S" -- parses as "20 seconds"
* "15M" -- parses as "15 minutes" (where a minute is 60 seconds)
* "10H" -- parses as "10 hours" (where an hour is 3600 seconds)
* "2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
* "2D3H4M5S123MS" -- parses as "2 days, 3 hours, 4 minutes, 5 seconds and 123 milliseconds"
* </pre>
*
* @param key the property name
* @param defaultValue the default value when name is not found or any error occurred
* @return the parsed property value(in milliseconds)
*/
public long getDurationProperty(String key, long defaultValue);
/**
* Add change listener to this config instance.
*
* @param listener the config change listener
......
package com.ctrip.framework.apollo.exceptions;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ApolloConfigStatusCodeException extends RuntimeException{
private final int m_statusCode;
public ApolloConfigStatusCodeException(int statusCode, String message) {
super(String.format("[status code: %d] %s", statusCode, message));
this.m_statusCode = statusCode;
}
public int getStatusCode() {
return m_statusCode;
}
}
......@@ -8,8 +8,10 @@ import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.enums.PropertyChangeType;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.util.parser.Parsers;
import com.dianping.cat.Cat;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
......@@ -17,7 +19,9 @@ import com.dianping.cat.message.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutorService;
......@@ -28,6 +32,12 @@ import java.util.concurrent.Executors;
*/
public abstract class AbstractConfig implements Config {
private static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
private static final String LONG_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
private static final String MEDIUM_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String SHORT_DATE_FORMAT = "yyyy-MM-dd";
private static final String[] DATE_FORMATS = {LONG_DATE_FORMAT, MEDIUM_DATE_FORMAT,
SHORT_DATE_FORMAT};
private static ExecutorService m_executorService;
private List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
......@@ -46,50 +56,214 @@ public abstract class AbstractConfig implements Config {
@Override
public Integer getIntProperty(String key, Integer defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Integer.parseInt(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Integer.parseInt(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getIntProperty for %s failed, return default value %d", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Long getLongProperty(String key, Long defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Long.parseLong(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Long.parseLong(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getLongProperty for %s failed, return default value %d", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Short getShortProperty(String key, Short defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Short.parseShort(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Short.parseShort(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getShortProperty for %s failed, return default value %d", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Float getFloatProperty(String key, Float defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Float.parseFloat(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Float.parseFloat(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getFloatProperty for %s failed, return default value %f", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Double getDoubleProperty(String key, Double defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Double.parseDouble(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Double.parseDouble(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getDoubleProperty for %s failed, return default value %f", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Byte getByteProperty(String key, Byte defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Byte.parseByte(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Byte.parseByte(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getByteProperty for %s failed, return default value %d", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Boolean getBooleanProperty(String key, Boolean defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : Boolean.parseBoolean(value);
try {
String value = getProperty(key, null);
if (value != null) {
return Boolean.parseBoolean(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getBooleanProperty for %s failed, return default value %b", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public String[] getArrayProperty(String key, String delimiter, String[] defaultValue) {
String value = getProperty(key, null);
return value == null ? defaultValue : value.split(delimiter);
try {
String value = getProperty(key, null);
if (value != null) {
return value.split(delimiter);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getArrayProperty for %s failed, return default value", key), ex));
}
return defaultValue;
}
@Override
public <T extends Enum<T>> T getEnumProperty(String key, Class<T> enumType, T defaultValue) {
try {
String value = getProperty(key, null);
if (value != null) {
return Enum.valueOf(enumType, value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getEnumProperty for %s failed, return default value %s", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Date getDateProperty(String key, Date defaultValue) {
try {
String value = getProperty(key, null);
if (value != null) {
return Parsers.forDate().parse(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getDateProperty for %s failed, return default value %s", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Date getDateProperty(String key, String format, Date defaultValue) {
try {
String value = getProperty(key, null);
if (value != null) {
return Parsers.forDate().parse(value, format);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getDateProperty for %s failed, return default value %s", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public Date getDateProperty(String key, String format, Locale locale, Date defaultValue) {
try {
String value = getProperty(key, null);
if (value != null) {
return Parsers.forDate().parse(value, format, locale);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getDateProperty for %s failed, return default value %s", key,
defaultValue), ex));
}
return defaultValue;
}
@Override
public long getDurationProperty(String key, long defaultValue) {
try {
String value = getProperty(key, null);
if (value != null) {
return Parsers.forDuration().parseToMillis(value);
}
} catch (Throwable ex) {
Cat.logError(new ApolloConfigException(
String.format("getDurationProperty for %s failed, return default value %d", key,
defaultValue), ex));
}
return defaultValue;
}
protected void fireConfigChange(final ConfigChangeEvent changeEvent) {
......
......@@ -86,7 +86,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
}
if (value == null && m_configProperties.get() == null) {
logger.warn("Could not load config from Apollo, always return default value!");
logger.warn("Could not load config from Apollo, please check whether the configs are released in Apollo! Return default value now!");
}
return value == null ? defaultValue : value;
......
......@@ -14,6 +14,7 @@ import com.ctrip.framework.apollo.core.dto.ApolloConfig;
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.exceptions.ApolloConfigStatusCodeException;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.apollo.util.http.HttpRequest;
import com.ctrip.framework.apollo.util.http.HttpResponse;
......@@ -202,6 +203,20 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
logger.debug("Loaded config for {}: {}", m_namespace, result);
return result;
} catch (ApolloConfigStatusCodeException ex) {
ApolloConfigStatusCodeException statusCodeException = ex;
//config not found
if (ex.getStatusCode() == 404) {
String message = String.format(
"Could not find config for namespace - appId: %s, cluster: %s, namespace: %s, " +
"please check whether the configs are released in Apollo!",
appId, cluster, m_namespace);
statusCodeException = new ApolloConfigStatusCodeException(ex.getStatusCode(),
message);
}
Cat.logError(statusCodeException);
transaction.setStatus(statusCodeException);
exception = statusCodeException;
} catch (Throwable ex) {
Cat.logError(ex);
transaction.setStatus(ex);
......@@ -219,8 +234,8 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
}
}
String message = String.format(
"Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s, services: %s",
appId, cluster, m_namespace, configServices);
"Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s",
appId, cluster, m_namespace);
throw new ApolloConfigException(message, exception);
}
......
package com.ctrip.framework.apollo.util;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.MetaDomainConsts;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.enums.EnvUtils;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.foundation.Foundation;
import org.slf4j.Logger;
......@@ -82,10 +82,8 @@ public class ConfigUtil {
}
private boolean isToolingZone() {
if ("true".equalsIgnoreCase(Foundation.server().getProperty("tooling", "false").trim())) {
return true;
}
return false;
//do not use the new isTooling method since it might not be available in the client side
return "true".equalsIgnoreCase(Foundation.server().getProperty("tooling", "false").trim());
}
/**
......@@ -101,11 +99,17 @@ public class ConfigUtil {
* Get the current environment.
*
* @return the env
* @throws IllegalStateException if env is set
* @throws ApolloConfigException if env is set
*/
public Env getApolloEnv() {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType());
Preconditions.checkState(env != null, "env is not set");
if (env == null) {
String path = isOSWindows() ? "C:\\opt\\settings\\server.properties" :
"/opt/settings/server.properties";
String message = String.format("env is not set, please make sure it is set in %s!", path);
logger.error(message);
throw new ApolloConfigException(message);
}
return env;
}
......
......@@ -6,6 +6,7 @@ import com.google.common.io.BaseEncoding;
import com.google.gson.Gson;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.exceptions.ApolloConfigStatusCodeException;
import com.ctrip.framework.apollo.util.ConfigUtil;
import org.unidal.helper.Files;
......@@ -127,8 +128,9 @@ public class HttpUtil {
}
}
}
throw new ApolloConfigException(String.format("Get operation failed for %s, status code - %d",
httpRequest.getUrl(), statusCode));
throw new ApolloConfigStatusCodeException(statusCode,
String.format("Get operation failed for %s", httpRequest.getUrl()));
}
}
package com.ctrip.framework.apollo.util.parser;
public class ParserException extends Exception {
public ParserException(String message) {
super(message);
}
public ParserException(String message, Throwable cause) {
super(message, cause);
}
}
package com.ctrip.framework.apollo.util.parser;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Parsers {
public static DateParser forDate() {
return DateParser.INSTANCE;
}
public static DurationParser forDuration() {
return DurationParser.INSTANCE;
}
public enum DateParser {
INSTANCE;
private static final String LONG_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
private static final String MEDIUM_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String SHORT_DATE_FORMAT = "yyyy-MM-dd";
/**
* Will try to parse the date with Locale.US and formats as follows:
* yyyy-MM-dd HH:mm:ss.SSS, yyyy-MM-dd HH:mm:ss and yyyy-MM-dd
*
* @param text the text to parse
* @return the parsed date
* @throws ParserException if the text cannot be parsed
*/
public Date parse(String text) throws ParserException {
text = text.trim();
int length = text.length();
if (length == LONG_DATE_FORMAT.length()) {
return parse(text, LONG_DATE_FORMAT);
}
if (length == MEDIUM_DATE_FORMAT.length()) {
return parse(text, MEDIUM_DATE_FORMAT);
}
return parse(text, SHORT_DATE_FORMAT);
}
/**
* Parse the text with the format specified and Locale.US
*
* @param text the text to parse
* @param format the date format, see {@link java.text.SimpleDateFormat} for more information
* @return the parsed date
* @throws ParserException if the text cannot be parsed
*/
public Date parse(String text, String format) throws ParserException {
return parse(text, format, Locale.US);
}
/**
* Parse the text with the format and locale specified
*
* @param text the text to parse
* @param format the date format, see {@link java.text.SimpleDateFormat} for more information
* @param locale the locale
* @return the parsed date
* @throws ParserException if the text cannot be parsed
*/
public Date parse(String text, String format, Locale locale) throws ParserException {
SimpleDateFormat dateFormat = getDateFormat(format, locale);
try {
return dateFormat.parse(text.trim());
} catch (ParseException e) {
throw new ParserException("Error when parsing date(" + dateFormat.toPattern() + ") from " + text, e);
}
}
private SimpleDateFormat getDateFormat(String format, Locale locale) {
return new SimpleDateFormat(format, locale);
}
}
public enum DurationParser {
INSTANCE;
private static final Pattern PATTERN =
Pattern.compile("(?:([0-9]+)D)?(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+)S)?(?:([0-9]+)(?:MS)?)?",
Pattern.CASE_INSENSITIVE);
private static final int HOURS_PER_DAY = 24;
private static final int MINUTES_PER_HOUR = 60;
private static final int SECONDS_PER_MINUTE = 60;
private static final int MILLIS_PER_SECOND = 1000;
private static final int MILLIS_PER_MINUTE = MILLIS_PER_SECOND * SECONDS_PER_MINUTE;
private static final int MILLIS_PER_HOUR = MILLIS_PER_MINUTE * MINUTES_PER_HOUR;
private static final int MILLIS_PER_DAY = MILLIS_PER_HOUR * HOURS_PER_DAY;
public long parseToMillis(String text) throws ParserException {
Matcher matcher = PATTERN.matcher(text);
if (matcher.matches()) {
String dayMatch = matcher.group(1);
String hourMatch = matcher.group(2);
String minuteMatch = matcher.group(3);
String secondMatch = matcher.group(4);
String fractionMatch = matcher.group(5);
if (dayMatch != null || hourMatch != null || minuteMatch != null || secondMatch != null || fractionMatch != null) {
int daysAsMilliSecs = parseNumber(dayMatch, MILLIS_PER_DAY);
int hoursAsMilliSecs = parseNumber(hourMatch, MILLIS_PER_HOUR);
int minutesAsMilliSecs = parseNumber(minuteMatch, MILLIS_PER_MINUTE);
int secondsAsMilliSecs = parseNumber(secondMatch, MILLIS_PER_SECOND);
int milliseconds = parseNumber(fractionMatch, 1);
return daysAsMilliSecs + hoursAsMilliSecs + minutesAsMilliSecs + secondsAsMilliSecs + milliseconds;
}
}
throw new ParserException(String.format("Text %s cannot be parsed to duration)", text));
}
private static int parseNumber(String parsed, int multiplier) {
// regex limits to [0-9]+
if (parsed == null || parsed.trim().isEmpty()) {
return 0;
}
return Integer.parseInt(parsed) * multiplier;
}
}
}
......@@ -14,6 +14,8 @@ import com.ctrip.framework.apollo.spi.DefaultConfigFactoryManagerTest;
import com.ctrip.framework.apollo.spi.DefaultConfigFactoryTest;
import com.ctrip.framework.apollo.spi.DefaultConfigRegistryTest;
import com.ctrip.framework.apollo.util.ExceptionUtilTest;
import com.ctrip.framework.apollo.util.parser.DateParserTest;
import com.ctrip.framework.apollo.util.parser.DurationParserTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
......@@ -25,7 +27,8 @@ import org.junit.runners.Suite.SuiteClasses;
DefaultConfigManagerTest.class, DefaultConfigTest.class, LocalFileConfigRepositoryTest.class,
RemoteConfigRepositoryTest.class, SimpleConfigTest.class, DefaultConfigFactoryTest.class,
ConfigIntegrationTest.class, ExceptionUtilTest.class, XmlConfigFileTest.class,
PropertiesConfigFileTest.class, RemoteConfigLongPollServiceTest.class
PropertiesConfigFileTest.class, RemoteConfigLongPollServiceTest.class, DateParserTest.class,
DurationParserTest.class
})
public class AllTests {
......
package com.ctrip.framework.apollo.util.parser;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import static org.junit.Assert.assertEquals;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class DateParserTest {
private Parsers.DateParser dateParser = Parsers.forDate();
private String shortDateText = "2016-09-28";
private String mediumDateText = "2016-09-28 15:10:10";
private String longDateText = "2016-09-28 15:10:10.123";
@Test
public void testParseShortFormat() throws Exception {
String format = "yyyy-MM-dd";
Date expected = assembleDate(2016, 9, 28, 0, 0, 0, 0);
checkWithFormat(expected, shortDateText, format);
checkWithFormat(expected, mediumDateText, format);
checkWithFormat(expected, longDateText, format);
}
@Test
public void testParseMediumFormat() throws Exception {
String format = "yyyy-MM-dd HH:mm:ss";
Date expected = assembleDate(2016, 9, 28, 15, 10, 10, 0);
checkWithFormat(expected, mediumDateText, format);
checkWithFormat(expected, longDateText, format);
}
@Test
public void testParseLongFormat() throws Exception {
String format = "yyyy-MM-dd HH:mm:ss.SSS";
Date expected = assembleDate(2016, 9, 28, 15, 10, 10, 123);
checkWithFormat(expected, longDateText, format);
}
@Test
public void testParseWithNoFormat() throws Exception {
Date shortDate = assembleDate(2016, 9, 28, 0, 0, 0, 0);
Date mediumDate = assembleDate(2016, 9, 28, 15, 10, 10, 0);
Date longDate = assembleDate(2016, 9, 28, 15, 10, 10, 123);
check(shortDate, shortDateText);
check(mediumDate, mediumDateText);
check(longDate, longDateText);
}
@Test
public void testParseWithFormatAndLocale() throws Exception {
Date someDate = assembleDate(2016, 9, 28, 15, 10, 10, 123);
Locale someLocale = Locale.FRENCH;
String someFormat = "EEE, d MMM yyyy HH:mm:ss.SSS Z";
SimpleDateFormat someDateFormat = new SimpleDateFormat(someFormat, someLocale);
String dateText = someDateFormat.format(someDate);
checkWithFormatAndLocale(someDate, dateText, someFormat, someLocale);
}
@Test(expected = ParserException.class)
public void testParseError() throws Exception {
String someInvalidDate = "someInvalidDate";
String format = "yyyy-MM-dd";
dateParser.parse(someInvalidDate, format);
}
private void check(Date expected, String text) throws Exception {
assertEquals(expected, dateParser.parse(text));
}
private void checkWithFormat(Date expected, String text, String format) throws Exception {
assertEquals(expected, dateParser.parse(text, format));
}
private void checkWithFormatAndLocale(Date expected, String text, String format, Locale locale) throws Exception {
assertEquals(expected, dateParser.parse(text, format, locale));
}
private Date assembleDate(int year, int month, int day, int hour, int minute, int second, int millisecond) {
Calendar date = Calendar.getInstance();
date.set(year, month - 1, day, hour, minute, second); //Month in Calendar is 0 based
date.set(Calendar.MILLISECOND, millisecond);
return date.getTime();
}
}
\ No newline at end of file
package com.ctrip.framework.apollo.util.parser;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class DurationParserTest {
private Parsers.DurationParser durationParser = Parsers.forDuration();
@Test
public void testParseMilliSeconds() throws Exception {
String text = "345MS";
long expected = 345;
checkParseToMillis(expected, text);
}
@Test
public void testParseMilliSecondsWithNoSuffix() throws Exception {
String text = "123";
long expected = 123;
checkParseToMillis(expected, text);
}
@Test
public void testParseSeconds() throws Exception {
String text = "20S";
long expected = 20 * 1000;
checkParseToMillis(expected, text);
}
@Test
public void testParseMinutes() throws Exception {
String text = "15M";
long expected = 15 * 60 * 1000;
checkParseToMillis(expected, text);
}
@Test
public void testParseHours() throws Exception {
String text = "10H";
long expected = 10 * 3600 * 1000;
checkParseToMillis(expected, text);
}
@Test
public void testParseDays() throws Exception {
String text = "2D";
long expected = 2 * 24 * 3600 * 1000;
checkParseToMillis(expected, text);
}
@Test
public void testParseFullText() throws Exception {
String text = "2D3H4M5S123MS";
long expected = 2 * 24 * 3600 * 1000 + 3 * 3600 * 1000 + 4 * 60 * 1000 + 5 * 1000 + 123;
checkParseToMillis(expected, text);
}
@Test
public void testParseFullTextWithLowerCase() throws Exception {
String text = "2d3h4m5s123ms";
long expected = 2 * 24 * 3600 * 1000 + 3 * 3600 * 1000 + 4 * 60 * 1000 + 5 * 1000 + 123;
checkParseToMillis(expected, text);
}
@Test
public void testParseFullTextWithNoMS() throws Exception {
String text = "2D3H4M5S123";
long expected = 2 * 24 * 3600 * 1000 + 3 * 3600 * 1000 + 4 * 60 * 1000 + 5 * 1000 + 123;
checkParseToMillis(expected, text);
}
@Test(expected = ParserException.class)
public void testParseException() throws Exception {
String text = "someInvalidText";
durationParser.parseToMillis(text);
}
private void checkParseToMillis(long expected, String text) throws Exception {
assertEquals(expected, durationParser.parseToMillis(text));
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>apollo</artifactId>
<groupId>com.ctrip.framework.apollo</groupId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apollo-demo</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<name>Apollo</name>
<packaging>pom</packaging>
<description>Ctrip Configuration Center</description>
......@@ -139,7 +139,7 @@
<dependency>
<groupId>com.ctrip.framework</groupId>
<artifactId>framework-foundation</artifactId>
<version>1.1.7</version>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.dianping.cat</groupId>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment