提交 d0d412c4 编写于 作者: J Jason Song

Merge pull request #159 from nobodyiam/release-readable-number-merge

Release key generator, eureka url config to db.
......@@ -29,5 +29,5 @@ INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (1, 'k2', 'v2', 'co
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (2, 'k3', 'v3', 'comment3');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (5, 'k3', 'v4', 'comment4');
INSERT INTO RELEASE (Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('REV1','First Release','100003171', 'default', 'application', '{"k1":"v1"}');
INSERT INTO RELEASE (ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('TEST-RELEASE-KEY', 'REV1','First Release','100003171', 'default', 'application', '{"k1":"v1"}');
......@@ -16,6 +16,8 @@ import javax.persistence.Table;
@SQLDelete(sql = "Update Release set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class Release extends BaseEntity {
@Column(name = "ReleaseKey", nullable = false)
private String releaseKey;
@Column(name = "Name", nullable = false)
private String name;
......@@ -36,6 +38,10 @@ public class Release extends BaseEntity {
@Column(name = "Comment", nullable = false)
private String comment;
public String getReleaseKey() {
return releaseKey;
}
public String getAppId() {
return appId;
}
......@@ -60,6 +66,10 @@ public class Release extends BaseEntity {
return name;
}
public void setReleaseKey(String releaseKey) {
this.releaseKey = releaseKey;
}
public void setAppId(String appId) {
this.appId = appId;
}
......
package com.ctrip.apollo.biz.entity;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Entity
@Table(name = "ServerConfig")
@SQLDelete(sql = "Update ServerConfig set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class ServerConfig extends BaseEntity {
@Column(name = "Key", nullable = false)
private String key;
@Column(name = "Value", nullable = false)
private String value;
@Column(name = "Comment", nullable = false)
private String comment;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String toString() {
return toStringHelper().add("key", key).add("value", value).add("comment", comment).toString();
}
}
package com.ctrip.apollo.biz.eureka;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.ctrip.apollo.biz.entity.ServerConfig;
import com.ctrip.apollo.biz.repository.ServerConfigRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
@Component
public class ApolloEurekaClientConfig extends EurekaClientConfigBean {
static final String EUREKA_URL_CONFIG = "eureka.service.url";
private static final Splitter URL_SPLITTER = Splitter.on(",").omitEmptyStrings();
@Autowired
private ServerConfigRepository serverConfigRepository;
@Autowired
private Environment environment;
/**
* Assert only one zone: defaultZone, but multiple environments.
*/
public List<String> getEurekaServerServiceUrls(String myZone) {
//First check if there is any system property override
if (!Strings.isNullOrEmpty(environment.getProperty(EUREKA_URL_CONFIG))) {
return URL_SPLITTER.splitToList(environment.getProperty(EUREKA_URL_CONFIG));
}
//Second check if it is configured in database
ServerConfig eurekaUrl = serverConfigRepository.findByKey(EUREKA_URL_CONFIG);
if (!Objects.isNull(eurekaUrl) && !Strings.isNullOrEmpty(eurekaUrl.getValue())) {
return URL_SPLITTER.splitToList(eurekaUrl.getValue());
}
//fallback to default
return super.getEurekaServerServiceUrls(myZone);
}
}
package com.ctrip.apollo.biz.eureka;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.stereotype.Component;
@Component
public class CtripEurekaClientConfig extends EurekaClientConfigBean {
@Autowired
private CtripEurekaSettings eurekaSettings;
/**
* Assert only one zone: defaultZone, but multiple environments.
*/
public List<String> getEurekaServerServiceUrls(String myZone) {
String serviceUrls = eurekaSettings.getDefaultEurekaUrl(myZone);
if (serviceUrls != null) {
return Arrays.asList(serviceUrls.split(","));
}else{
return super.getEurekaServerServiceUrls(myZone);
}
}
}
package com.ctrip.apollo.biz.eureka;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.ctrip.apollo.core.enums.Env;
import com.ctrip.apollo.core.enums.EnvUtils;
import com.ctrip.framework.foundation.Foundation;
@Component
public class CtripEurekaSettings {
@Value("${ctrip.eureka.dev:http://localhost:8080/eureka}")
private String devEureka;
@Value("${ctrip.eureka.fat:http://localhost:8080/eureka}")
private String fatEureka;
@Value("${ctrip.eureka.uat:http://localhost:8080/eureka}")
private String uatEureka;
@Value("${ctrip.eureka.pro:http://localhost:8080/eureka}")
private String proEureka;
public String getDefaultEurekaUrl(String zone) {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType());
if (env == null) {
return null;
}
switch (env) {
case LOCAL:
return null;
case DEV:
return devEureka;
case FAT:
case FWS:
return fatEureka;
case UAT:
return uatEureka;
case TOOLS:
case PRO:
return proEureka;
default:
return null;
}
}
}
package com.ctrip.apollo.biz.repository;
import com.ctrip.apollo.biz.entity.ServerConfig;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public interface ServerConfigRepository extends PagingAndSortingRepository<ServerConfig, Long> {
ServerConfig findByKey(String key);
}
package com.ctrip.apollo.biz.service;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.google.gson.Gson;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Item;
......@@ -16,8 +8,18 @@ import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.repository.ItemRepository;
import com.ctrip.apollo.biz.repository.ReleaseRepository;
import com.ctrip.apollo.biz.utils.ReleaseKeyGenerator;
import com.ctrip.apollo.core.utils.StringUtils;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -62,6 +64,7 @@ public class ReleaseService {
}
Release release = new Release();
release.setReleaseKey(ReleaseKeyGenerator.generateReleaseKey(namespace));
release.setDataChangeCreatedTime(new Date());
release.setDataChangeCreatedBy(owner);
release.setName(name);
......
package com.ctrip.apollo.biz.utils;
import com.google.common.base.Joiner;
import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.core.utils.ByteUtil;
import com.ctrip.apollo.core.utils.MachineUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ReleaseKeyGenerator {
private static final DateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
private static final AtomicInteger releaseCounter = new AtomicInteger();
private static final Joiner KEY_JOINER = Joiner.on("-");
/**
* Generate the release key in the format: timestamp+appId+cluster+namespace+hash(ipAsInt+counter)
*
* @param namespace the namespace of the release
* @return the unique release key
*/
public static String generateReleaseKey(Namespace namespace) {
String hexIdString =
ByteUtil.toHexString(
toByteArray(Objects.hash(namespace.getAppId(), namespace.getClusterName(),
namespace.getNamespaceName()), MachineUtil.getMachineIdentifier(),
releaseCounter.incrementAndGet()));
return KEY_JOINER.join(TIMESTAMP_FORMAT.format(new Date()), hexIdString);
}
/**
* Concat machine id, counter and key to byte array
* Only retrieve lower 3 bytes of the id and counter and 2 bytes of the keyHashCode
*/
private static byte[] toByteArray(int keyHashCode, int machineIdentifier, int counter) {
byte[] bytes = new byte[8];
bytes[0] = ByteUtil.int1(keyHashCode);
bytes[1] = ByteUtil.int0(keyHashCode);
bytes[2] = ByteUtil.int2(machineIdentifier);
bytes[3] = ByteUtil.int1(machineIdentifier);
bytes[4] = ByteUtil.int0(machineIdentifier);
bytes[5] = ByteUtil.int2(counter);
bytes[6] = ByteUtil.int1(counter);
bytes[7] = ByteUtil.int0(counter);
return bytes;
}
}
package com.ctrip.apollo.biz.eureka;
import com.ctrip.apollo.biz.entity.ServerConfig;
import com.ctrip.apollo.biz.repository.ServerConfigRepository;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.core.env.Environment;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.List;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class ApolloEurekaClientConfigTest {
private ApolloEurekaClientConfig eurekaClientConfig;
@Mock
private ServerConfigRepository serverConfigRepository;
@Mock
private Environment environment;
@Before
public void setUp() throws Exception {
eurekaClientConfig = new ApolloEurekaClientConfig();
ReflectionTestUtils.setField(eurekaClientConfig, "serverConfigRepository", serverConfigRepository);
ReflectionTestUtils.setField(eurekaClientConfig, "environment", environment);
}
@Test
public void testGetEurekaServerServiceUrlsFromDB() throws Exception {
String someEurekaUrl = "http://xxx,http://yyy";
String myZone = "xx";
when(serverConfigRepository.findByKey(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(assembleServerConfig(ApolloEurekaClientConfig.EUREKA_URL_CONFIG, someEurekaUrl));
List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone);
String[] expected = someEurekaUrl.split(",");
assertEquals(expected.length, eurekaUrls.size());
for (String url : expected) {
assertTrue(eurekaUrls.contains(url));
}
}
@Test
public void testGetEurekaServiceUrlsFromSystemProperty() throws Exception {
String someEurekaUrl = "http://xxx,http://yyy";
String myZone = "xx";
String someEurekaUrlFromSystemProperty = "http://zzz";
when(environment.getProperty(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(someEurekaUrlFromSystemProperty);
when(serverConfigRepository.findByKey(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(assembleServerConfig(ApolloEurekaClientConfig.EUREKA_URL_CONFIG, someEurekaUrl));
List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone);
String[] expected = someEurekaUrlFromSystemProperty.split(",");
assertEquals(expected.length, eurekaUrls.size());
for (String url : expected) {
assertTrue(eurekaUrls.contains(url));
}
}
private ServerConfig assembleServerConfig(String key, String value) {
ServerConfig config = new ServerConfig();
config.setKey(key);
config.setValue(value);
return config;
}
}
package com.ctrip.apollo.biz.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.repository.ReleaseRepository;
import org.junit.Before;
import org.junit.Test;
......@@ -13,8 +10,11 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.repository.ReleaseRepository;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -37,10 +37,14 @@ public class ConfigServiceTest {
String someAppId = "1";
String someClusterName = "someClusterName";
String someNamespaceName = "someNamespaceName";
String someReleaseId = "1";
long someReleaseId = 1;
String someReleaseKey = "someKey";
String someValidConfiguration = "{\"apollo.bar\": \"foo\"}";
Release someRelease = assembleRelease(someReleaseId, someAppId, someClusterName, someNamespaceName,
Release
someRelease =
assembleRelease(someReleaseId, someReleaseKey, someAppId, someClusterName,
someNamespaceName,
someValidConfiguration);
when(releaseRepository.findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(someAppId,
......@@ -53,7 +57,8 @@ public class ConfigServiceTest {
someNamespaceName);
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getClusterName());
assertEquals(someReleaseId, String.valueOf(result.getId()));
assertEquals(someReleaseId, result.getId());
assertEquals(someReleaseKey, result.getReleaseKey());
assertEquals(someValidConfiguration, result.getConfigurations());
}
......@@ -73,10 +78,12 @@ public class ConfigServiceTest {
someAppId, someClusterName, someNamespaceName);
}
private Release assembleRelease(String releaseId, String appId, String clusterName,
private Release assembleRelease(long releaseId, String releaseKey, String appId,
String clusterName,
String groupName, String configurations) {
Release release = new Release();
release.setId(Long.valueOf(releaseId));
release.setId(releaseId);
release.setReleaseKey(releaseKey);
release.setAppId(appId);
release.setClusterName(clusterName);
release.setNamespaceName(groupName);
......
package com.ctrip.apollo.biz.utils;
import com.google.common.collect.Sets;
import com.ctrip.apollo.biz.entity.Namespace;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ReleaseKeyGeneratorTest {
private static final Logger logger = LoggerFactory.getLogger(ReleaseKeyGeneratorTest.class);
@Test
public void testGenerateReleaseKey() throws Exception {
String someAppId = "someAppId";
String someCluster = "someCluster";
String someNamespace = "someNamespace";
String anotherAppId = "anotherAppId";
Namespace namespace = assembleNamespace(someAppId, someCluster, someNamespace);
Namespace anotherNamespace = assembleNamespace(anotherAppId, someCluster, someNamespace);
int generateTimes = 50000;
Set<String> releaseKeys = Sets.newConcurrentHashSet();
ExecutorService executorService = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
executorService.submit(generateReleaseKeysTask(namespace, releaseKeys, generateTimes, latch));
executorService.submit(generateReleaseKeysTask(anotherNamespace, releaseKeys, generateTimes, latch));
latch.countDown();
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
//make sure keys are unique
assertEquals(generateTimes * 2, releaseKeys.size());
}
private Runnable generateReleaseKeysTask(Namespace namespace, Set<String> releaseKeys,
int generateTimes, CountDownLatch latch) {
return () -> {
try {
latch.await();
} catch (InterruptedException e) {
//ignore
}
for (int i = 0; i < generateTimes; i++) {
releaseKeys.add(ReleaseKeyGenerator.generateReleaseKey(namespace));
}
};
}
private Namespace assembleNamespace(String appId, String cluster, String namespaceName) {
Namespace namespace = new Namespace();
namespace.setAppId(appId);
namespace.setClusterName(cluster);
namespace.setNamespaceName(namespaceName);
return namespace;
}
}
......@@ -11,6 +11,8 @@ import com.ctrip.apollo.core.ConfigConsts;
import com.ctrip.apollo.core.dto.ApolloConfig;
import com.ctrip.apollo.core.dto.ApolloConfigNotification;
import com.ctrip.apollo.core.dto.ServiceDTO;
import com.ctrip.apollo.core.schedule.ExponentialSchedulePolicy;
import com.ctrip.apollo.core.schedule.SchedulePolicy;
import com.ctrip.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.apollo.util.ConfigUtil;
import com.ctrip.apollo.util.ExceptionUtil;
......@@ -54,6 +56,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
private final String m_namespace;
private final ScheduledExecutorService m_executorService;
private final AtomicBoolean m_longPollingStopped;
private SchedulePolicy m_longPollSchedulePolicy;
/**
* Constructor.
......@@ -72,8 +75,9 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
Cat.logError(ex);
throw new IllegalStateException("Unable to load component!", ex);
}
this.m_longPollingStopped = new AtomicBoolean(false);
this.m_executorService = Executors.newScheduledThreadPool(1,
m_longPollSchedulePolicy = new ExponentialSchedulePolicy(1, 120);
m_longPollingStopped = new AtomicBoolean(false);
m_executorService = Executors.newScheduledThreadPool(1,
ApolloThreadFactory.create("RemoteConfigRepository", true));
this.trySync();
this.schedulePeriodicRefresh();
......@@ -206,7 +210,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
}
if (previousConfig != null) {
queryParams.put("releaseId", escaper.escape(String.valueOf(previousConfig.getReleaseId())));
queryParams.put("releaseKey", escaper.escape(String.valueOf(previousConfig.getReleaseKey())));
}
if (!Strings.isNullOrEmpty(dataCenter)) {
......@@ -253,7 +257,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
String url =
assembleLongPollRefreshUrl(lastServiceDto.getHomepageUrl(), appId, cluster,
m_namespace, dataCenter, m_configCache.get());
m_namespace, dataCenter);
logger.debug("Long polling from {}", url);
HttpRequest request = new HttpRequest(url);
......@@ -275,18 +279,21 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
}
});
}
m_longPollSchedulePolicy.success();
transaction.addData("StatusCode", response.getStatusCode());
transaction.setStatus(Message.SUCCESS);
} catch (Throwable ex) {
logger.warn("Long polling failed, will retry. appId: {}, cluster: {}, namespace: {}, reason: {}",
appId, cluster, m_namespace, ExceptionUtil.getDetailMessage(ex));
lastServiceDto = null;
Cat.logError(ex);
if (transaction != null) {
transaction.setStatus(ex);
}
long sleepTime = m_longPollSchedulePolicy.fail();
logger.warn(
"Long polling failed, will retry in {} seconds. appId: {}, cluster: {}, namespace: {}, reason: {}",
sleepTime, appId, cluster, m_namespace, ExceptionUtil.getDetailMessage(ex));
try {
TimeUnit.SECONDS.sleep(5);
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException ie) {
//ignore
}
......@@ -299,8 +306,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
}
private String assembleLongPollRefreshUrl(String uri, String appId, String cluster,
String namespace, String dataCenter,
ApolloConfig previousConfig) {
String namespace, String dataCenter) {
Escaper escaper = UrlEscapers.urlPathSegmentEscaper();
Map<String, String> queryParams = Maps.newHashMap();
queryParams.put("appId", escaper.escape(appId));
......@@ -312,9 +318,6 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
if (!Strings.isNullOrEmpty(dataCenter)) {
queryParams.put("dataCenter", escaper.escape(dataCenter));
}
if (previousConfig != null) {
queryParams.put("releaseId", escaper.escape(previousConfig.getReleaseId()));
}
String params = MAP_JOINER.join(queryParams);
if (!uri.endsWith("/")) {
......
......@@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
* @author Jason Song(song_s@ctrip.com)
*/
public class ConfigIntegrationTest extends BaseIntegrationTest {
private String someReleaseId;
private String someReleaseKey;
private File configDir;
private String defaultNamespace;
......@@ -55,7 +55,7 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
super.setUp();
defaultNamespace = ConfigConsts.NAMESPACE_DEFAULT;
someReleaseId = "1";
someReleaseKey = "1";
configDir = new File(ClassLoaderUtil.getClassPath() + "config-cache");
configDir.mkdirs();
}
......@@ -329,7 +329,7 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
private ApolloConfig assembleApolloConfig(Map<String, String> configurations) {
ApolloConfig apolloConfig =
new ApolloConfig(someAppId, someClusterName, defaultNamespace, someReleaseId);
new ApolloConfig(someAppId, someClusterName, defaultNamespace, someReleaseKey);
apolloConfig.setConfigurations(configurations);
......
......@@ -167,9 +167,9 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase {
private ApolloConfig assembleApolloConfig(Map<String, String> configurations) {
String someAppId = "appId";
String someClusterName = "cluster";
String someReleaseId = "1";
String someReleaseKey = "1";
ApolloConfig apolloConfig =
new ApolloConfig(someAppId, someClusterName, someNamespace, someReleaseId);
new ApolloConfig(someAppId, someClusterName, someNamespace, someReleaseKey);
apolloConfig.setConfigurations(configurations);
......
......@@ -51,17 +51,17 @@ public class ConfigController {
@RequestMapping(value = "/{appId}/{clusterName}", method = RequestMethod.GET)
public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String clusterName,
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "releaseId", defaultValue = "-1") String clientSideReleaseId,
@RequestParam(value = "releaseKey", defaultValue = "-1") String clientSideReleaseKey,
HttpServletResponse response) throws IOException {
return this.queryConfig(appId, clusterName, ConfigConsts.NAMESPACE_DEFAULT, dataCenter,
clientSideReleaseId, response);
clientSideReleaseKey, response);
}
@RequestMapping(value = "/{appId}/{clusterName}/{namespace}", method = RequestMethod.GET)
public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String clusterName,
@PathVariable String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "releaseId", defaultValue = "-1") String clientSideReleaseId,
@RequestParam(value = "releaseKey", defaultValue = "-1") String clientSideReleaseKey,
HttpServletResponse response) throws IOException {
List<Release> releases = Lists.newLinkedList();
......@@ -89,10 +89,10 @@ public class ConfigController {
return null;
}
String mergedReleaseId = FluentIterable.from(releases).transform(
input -> String.valueOf(input.getId())).join(STRING_JOINER);
String mergedReleaseKey = FluentIterable.from(releases).transform(
input -> String.valueOf(input.getReleaseKey())).join(STRING_JOINER);
if (mergedReleaseId.equals(clientSideReleaseId)) {
if (mergedReleaseKey.equals(clientSideReleaseKey)) {
// Client side configuration is the same with server side, return 304
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
Cat.logEvent("Apollo.Config.NotModified",
......@@ -100,7 +100,7 @@ public class ConfigController {
return null;
}
ApolloConfig apolloConfig = new ApolloConfig(appId, clusterName, namespace, mergedReleaseId);
ApolloConfig apolloConfig = new ApolloConfig(appId, clusterName, namespace, mergedReleaseKey);
apolloConfig.setConfigurations(mergeReleaseConfigurations(releases));
Cat.logEvent("Apollo.Config.Found", assembleKey(appId, clusterName, namespace, dataCenter));
......
......@@ -45,7 +45,7 @@ public class NotificationController implements MessageListener {
NOT_MODIFIED_RESPONSE = new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
private static final Splitter STRING_SPLITTER =
Splitter.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
Splitter.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).omitEmptyStrings();
@Autowired
private AppNamespaceService appNamespaceService;
......@@ -55,8 +55,7 @@ public class NotificationController implements MessageListener {
@RequestParam(value = "appId") String appId,
@RequestParam(value = "cluster") String cluster,
@RequestParam(value = "namespace", defaultValue = ConfigConsts.NAMESPACE_DEFAULT) String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "releaseId", defaultValue = "-1") String clientSideReleaseId) {
@RequestParam(value = "dataCenter", required = false) String dataCenter) {
List<String> watchedKeys = Lists.newArrayList(assembleKey(appId, cluster, namespace));
//Listen on more namespaces, since it's not the default namespace
......
......@@ -73,36 +73,36 @@ public class ConfigControllerTest {
@Test
public void testQueryConfig() throws Exception {
long someClientSideReleaseId = 1;
long someServerSideNewReleaseId = 2;
String someClientSideReleaseKey = "1";
String someServerSideNewReleaseKey = "2";
HttpServletResponse someResponse = mock(HttpServletResponse.class);
when(configService.findRelease(someAppId, someClusterName, defaultNamespaceName))
.thenReturn(someRelease);
when(someRelease.getId()).thenReturn(someServerSideNewReleaseId);
when(someRelease.getReleaseKey()).thenReturn(someServerSideNewReleaseKey);
ApolloConfig result = configController.queryConfig(someAppId, someClusterName,
defaultNamespaceName, someDataCenter, String.valueOf(someClientSideReleaseId),
defaultNamespaceName, someDataCenter, someClientSideReleaseKey,
someResponse);
verify(configService, times(1)).findRelease(someAppId, someClusterName, defaultNamespaceName);
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getCluster());
assertEquals(defaultNamespaceName, result.getNamespace());
assertEquals(String.valueOf(someServerSideNewReleaseId), result.getReleaseId());
assertEquals(someServerSideNewReleaseKey, result.getReleaseKey());
}
@Test
public void testQueryConfigWithReleaseNotFound() throws Exception {
long someClientSideReleaseId = 1;
String someClientSideReleaseKey = "1";
HttpServletResponse someResponse = mock(HttpServletResponse.class);
when(configService.findRelease(someAppId, someClusterName, defaultNamespaceName))
.thenReturn(null);
ApolloConfig result = configController.queryConfig(someAppId, someClusterName,
defaultNamespaceName, someDataCenter, String.valueOf(someClientSideReleaseId),
defaultNamespaceName, someDataCenter, someClientSideReleaseKey,
someResponse);
assertNull(result);
......@@ -111,18 +111,18 @@ public class ConfigControllerTest {
@Test
public void testQueryConfigWithApolloConfigNotModified() throws Exception {
long someClientSideReleaseId = 1;
long someServerSideReleaseId = someClientSideReleaseId;
String someClientSideReleaseKey = "1";
String someServerSideReleaseKey = someClientSideReleaseKey;
HttpServletResponse someResponse = mock(HttpServletResponse.class);
when(configService.findRelease(someAppId, someClusterName, defaultNamespaceName))
.thenReturn(someRelease);
when(someRelease.getId()).thenReturn(someServerSideReleaseId);
when(someRelease.getReleaseKey()).thenReturn(someServerSideReleaseKey);
ApolloConfig
result =
configController.queryConfig(someAppId, someClusterName, defaultNamespaceName,
someDataCenter, String.valueOf(someClientSideReleaseId), someResponse);
someDataCenter, String.valueOf(someClientSideReleaseKey), someResponse);
assertNull(result);
verify(someResponse, times(1)).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
......@@ -130,8 +130,8 @@ public class ConfigControllerTest {
@Test
public void testQueryConfigWithAppOwnNamespace() throws Exception {
String someClientSideReleaseId = "1";
String someServerSideReleaseId = "2";
String someClientSideReleaseKey = "1";
String someServerSideReleaseKey = "2";
String someAppOwnNamespaceName = "someAppOwn";
HttpServletResponse someResponse = mock(HttpServletResponse.class);
AppNamespace someAppOwnNamespace =
......@@ -141,14 +141,14 @@ public class ConfigControllerTest {
.thenReturn(someRelease);
when(appNamespaceService.findByNamespaceName(someAppOwnNamespaceName))
.thenReturn(someAppOwnNamespace);
when(someRelease.getId()).thenReturn(Long.valueOf(someServerSideReleaseId));
when(someRelease.getReleaseKey()).thenReturn(someServerSideReleaseKey);
ApolloConfig result =
configController
.queryConfig(someAppId, someClusterName, someAppOwnNamespaceName, someDataCenter,
someClientSideReleaseId, someResponse);
someClientSideReleaseKey, someResponse);
assertEquals(someServerSideReleaseId, result.getReleaseId());
assertEquals(someServerSideReleaseKey, result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getCluster());
assertEquals(someAppOwnNamespaceName, result.getNamespace());
......@@ -157,8 +157,8 @@ public class ConfigControllerTest {
@Test
public void testQueryConfigWithPubicNamespaceAndNoAppOverride() throws Exception {
String someClientSideReleaseId = "1";
String someServerSideReleaseId = "2";
String someClientSideReleaseKey = "1";
String someServerSideReleaseKey = "2";
HttpServletResponse someResponse = mock(HttpServletResponse.class);
String somePublicAppId = "somePublicAppId";
AppNamespace somePublicAppNamespace =
......@@ -170,14 +170,14 @@ public class ConfigControllerTest {
.thenReturn(somePublicAppNamespace);
when(configService.findRelease(somePublicAppId, someDataCenter, somePublicNamespaceName))
.thenReturn(somePublicRelease);
when(somePublicRelease.getId()).thenReturn(Long.valueOf(someServerSideReleaseId));
when(somePublicRelease.getReleaseKey()).thenReturn(someServerSideReleaseKey);
ApolloConfig result =
configController
.queryConfig(someAppId, someClusterName, somePublicNamespaceName, someDataCenter,
someClientSideReleaseId, someResponse);
someClientSideReleaseKey, someResponse);
assertEquals(someServerSideReleaseId, result.getReleaseId());
assertEquals(someServerSideReleaseKey, result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getCluster());
assertEquals(somePublicNamespaceName, result.getNamespace());
......@@ -186,8 +186,8 @@ public class ConfigControllerTest {
@Test
public void testQueryConfigWithPublicNamespaceAndNoAppOverrideAndNoDataCenter() throws Exception {
String someClientSideReleaseId = "1";
String someServerSideReleaseId = "2";
String someClientSideReleaseKey = "1";
String someServerSideReleaseKey = "2";
HttpServletResponse someResponse = mock(HttpServletResponse.class);
String somePublicAppId = "somePublicAppId";
AppNamespace somePublicAppNamespace =
......@@ -202,14 +202,14 @@ public class ConfigControllerTest {
when(configService
.findRelease(somePublicAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, somePublicNamespaceName))
.thenReturn(somePublicRelease);
when(somePublicRelease.getId()).thenReturn(Long.valueOf(someServerSideReleaseId));
when(somePublicRelease.getReleaseKey()).thenReturn(someServerSideReleaseKey);
ApolloConfig result =
configController
.queryConfig(someAppId, someClusterName, somePublicNamespaceName, someDataCenter,
someClientSideReleaseId, someResponse);
someClientSideReleaseKey, someResponse);
assertEquals(someServerSideReleaseId, result.getReleaseId());
assertEquals(someServerSideReleaseKey, result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getCluster());
assertEquals(somePublicNamespaceName, result.getNamespace());
......@@ -218,8 +218,8 @@ public class ConfigControllerTest {
@Test
public void testQueryConfigWithPublicNamespaceAndAppOverride() throws Exception {
String someAppSideReleaseId = "1";
String somePublicAppSideReleaseId = "2";
String someAppSideReleaseKey = "1";
String somePublicAppSideReleaseKey = "2";
HttpServletResponse someResponse = mock(HttpServletResponse.class);
String somePublicAppId = "somePublicAppId";
......@@ -232,21 +232,21 @@ public class ConfigControllerTest {
when(configService.findRelease(someAppId, someClusterName, somePublicNamespaceName))
.thenReturn(someRelease);
when(someRelease.getId()).thenReturn(Long.valueOf(someAppSideReleaseId));
when(someRelease.getReleaseKey()).thenReturn(someAppSideReleaseKey);
when(appNamespaceService.findByNamespaceName(somePublicNamespaceName))
.thenReturn(somePublicAppNamespace);
when(configService.findRelease(somePublicAppId, someDataCenter, somePublicNamespaceName))
.thenReturn(somePublicRelease);
when(somePublicRelease.getId()).thenReturn(Long.valueOf(somePublicAppSideReleaseId));
when(somePublicRelease.getReleaseKey()).thenReturn(somePublicAppSideReleaseKey);
ApolloConfig result =
configController
.queryConfig(someAppId, someClusterName, somePublicNamespaceName, someDataCenter,
someAppSideReleaseId, someResponse);
someAppSideReleaseKey, someResponse);
assertEquals(Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
.join(someAppSideReleaseId, somePublicAppSideReleaseId),
result.getReleaseId());
.join(someAppSideReleaseKey, somePublicAppSideReleaseKey),
result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getCluster());
assertEquals(somePublicNamespaceName, result.getNamespace());
......
......@@ -22,8 +22,6 @@ import org.springframework.web.context.request.async.DeferredResult;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
......@@ -39,7 +37,6 @@ public class NotificationControllerTest {
private String defaultNamespace;
private String somePublicNamespace;
private String someDataCenter;
private String someReleaseId;
@Mock
private AppNamespaceService appNamespaceService;
private Multimap<String, DeferredResult<ResponseEntity<ApolloConfigNotification>>>
......@@ -55,7 +52,6 @@ public class NotificationControllerTest {
defaultNamespace = ConfigConsts.NAMESPACE_DEFAULT;
somePublicNamespace = "somePublicNamespace";
someDataCenter = "someDC";
someReleaseId = "someRelease";
deferredResults =
(Multimap<String, DeferredResult<ResponseEntity<ApolloConfigNotification>>>) ReflectionTestUtils
......@@ -66,7 +62,7 @@ public class NotificationControllerTest {
public void testPollNotificationWithDefaultNamespace() throws Exception {
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter, someReleaseId);
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter);
String key =
Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
......@@ -86,8 +82,7 @@ public class NotificationControllerTest {
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, somePublicNamespace, someDataCenter,
someReleaseId);
.pollNotification(someAppId, someCluster, somePublicNamespace, someDataCenter);
List<String> publicClusters =
Lists.newArrayList(someDataCenter, ConfigConsts.CLUSTER_NAME_DEFAULT);
......@@ -110,7 +105,7 @@ public class NotificationControllerTest {
public void testPollNotificationWithDefaultNamespaceAndHandleMessage() throws Exception {
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter, someReleaseId);
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter);
String key =
Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
......@@ -137,8 +132,7 @@ public class NotificationControllerTest {
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, somePublicNamespace, someDataCenter,
someReleaseId);
.pollNotification(someAppId, someCluster, somePublicNamespace, someDataCenter);
String key =
Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
......
......@@ -43,7 +43,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(String.valueOf(990), result.getReleaseId());
assertEquals("TEST-RELEASE-KEY1", result.getReleaseKey());
assertEquals("v1", result.getConfigurations().get("k1"));
}
......@@ -57,7 +57,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(String.valueOf(991), result.getReleaseId());
assertEquals("TEST-RELEASE-KEY2", result.getReleaseKey());
assertEquals("v2", result.getConfigurations().get("k2"));
}
......@@ -81,11 +81,11 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
@Sql(scripts = "/integration-test/test-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryConfigNotModified() throws Exception {
String releaseId = String.valueOf(991);
String releaseKey = "TEST-RELEASE-KEY2";
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?releaseId={releaseId}",
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?releaseKey={releaseKey}",
ApolloConfig.class,
getHostUrl(), someAppId, someCluster, someNamespace, releaseId);
getHostUrl(), someAppId, someCluster, someNamespace, releaseKey);
assertEquals(HttpStatus.NOT_MODIFIED, response.getStatusCode());
}
......@@ -100,7 +100,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
getHostUrl(), someAppId, someCluster, somePublicNamespace, someDC);
ApolloConfig result = response.getBody();
assertEquals("993", result.getReleaseId());
assertEquals("TEST-RELEASE-KEY4", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespace());
......@@ -118,7 +118,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
getHostUrl(), someAppId, someDefaultCluster, somePublicNamespace, someDC);
ApolloConfig result = response.getBody();
assertEquals("994" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "993", result.getReleaseId());
assertEquals("TEST-RELEASE-KEY5" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "TEST-RELEASE-KEY4", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someDefaultCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespace());
......@@ -137,7 +137,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
getHostUrl(), someAppId, someCluster, somePublicNamespace, someDCNotFound);
ApolloConfig result = response.getBody();
assertEquals("992", result.getReleaseId());
assertEquals("TEST-RELEASE-KEY3", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespace());
......@@ -156,7 +156,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
getHostUrl(), someAppId, someDefaultCluster, somePublicNamespace, someDCNotFound);
ApolloConfig result = response.getBody();
assertEquals("994" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "992", result.getReleaseId());
assertEquals("TEST-RELEASE-KEY5" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "TEST-RELEASE-KEY3", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someDefaultCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespace());
......
......@@ -30,5 +30,5 @@ INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (1, 'k2', 'v2', 'co
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (2, 'k3', 'v3', 'comment3');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (5, 'k3', 'v4', 'comment4');
INSERT INTO RELEASE (Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('REV1','First Release','100003171', 'default', 'application', '{"k1":"v1"}');
INSERT INTO RELEASE (ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('TEST-RELEASE-KEY', 'REV1','First Release','100003171', 'default', 'application', '{"k1":"v1"}');
......@@ -17,13 +17,13 @@ INSERT INTO Namespace (AppId, ClusterName, NamespaceName) VALUES ('somePublicApp
INSERT INTO Namespace (AppId, ClusterName, NamespaceName) VALUES ('somePublicAppId', 'someDC', 'somePublicNamespace');
INSERT INTO Namespace (AppId, ClusterName, NamespaceName) VALUES ('someAppId', 'default', 'somePublicNamespace');
INSERT INTO RELEASE (id, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (990, 'INTEGRATION-TEST-DEFAULT','First Release','someAppId', 'default', 'application', '{"k1":"v1"}');
INSERT INTO RELEASE (id, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (991, 'INTEGRATION-TEST-NAMESPACE','First Release','someAppId', 'someCluster', 'someNamespace', '{"k2":"v2"}');
INSERT INTO RELEASE (id, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (992, 'INTEGRATION-TEST-PUBLIC-DEFAULT','First Release','somePublicAppId', 'default', 'somePublicNamespace', '{"k1":"default-v1", "k2":"default-v2"}');
INSERT INTO RELEASE (id, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (993, 'INTEGRATION-TEST-PUBLIC-NAMESPACE','First Release','somePublicAppId', 'someDC', 'somePublicNamespace', '{"k1":"someDC-v1", "k2":"someDC-v2"}');
INSERT INTO RELEASE (id, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (994, 'INTEGRATION-TEST-DEFAULT-OVERRIDE-PUBLIC','First Release','someAppId', 'default', 'somePublicNamespace', '{"k1":"override-v1"}');
INSERT INTO RELEASE (id, ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (990, 'TEST-RELEASE-KEY1', 'INTEGRATION-TEST-DEFAULT','First Release','someAppId', 'default', 'application', '{"k1":"v1"}');
INSERT INTO RELEASE (id, ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (991, 'TEST-RELEASE-KEY2', 'INTEGRATION-TEST-NAMESPACE','First Release','someAppId', 'someCluster', 'someNamespace', '{"k2":"v2"}');
INSERT INTO RELEASE (id, ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (992, 'TEST-RELEASE-KEY3', 'INTEGRATION-TEST-PUBLIC-DEFAULT','First Release','somePublicAppId', 'default', 'somePublicNamespace', '{"k1":"default-v1", "k2":"default-v2"}');
INSERT INTO RELEASE (id, ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (993, 'TEST-RELEASE-KEY4', 'INTEGRATION-TEST-PUBLIC-NAMESPACE','First Release','somePublicAppId', 'someDC', 'somePublicNamespace', '{"k1":"someDC-v1", "k2":"someDC-v2"}');
INSERT INTO RELEASE (id, ReleaseKey, Name, Comment, AppId, ClusterName, NamespaceName, Configurations)
VALUES (994, 'TEST-RELEASE-KEY5', 'INTEGRATION-TEST-DEFAULT-OVERRIDE-PUBLIC','First Release','someAppId', 'default', 'somePublicNamespace', '{"k1":"override-v1"}');
......@@ -17,7 +17,7 @@ public class ApolloConfig {
private Map<String, String> configurations;
private String releaseId;
private String releaseKey;
public ApolloConfig() {
}
......@@ -25,11 +25,11 @@ public class ApolloConfig {
public ApolloConfig(String appId,
String cluster,
String namespace,
String releaseId) {
String releaseKey) {
this.appId = appId;
this.cluster = cluster;
this.namespace = namespace;
this.releaseId = releaseId;
this.releaseKey = releaseKey;
}
public String getAppId() {
......@@ -44,8 +44,8 @@ public class ApolloConfig {
return namespace;
}
public String getReleaseId() {
return releaseId;
public String getReleaseKey() {
return releaseKey;
}
public Map<String, String> getConfigurations() {
......@@ -64,8 +64,8 @@ public class ApolloConfig {
this.namespace = namespace;
}
public void setReleaseId(String releaseId) {
this.releaseId = releaseId;
public void setReleaseKey(String releaseKey) {
this.releaseKey = releaseKey;
}
public void setConfigurations(Map<String, String> configurations) {
......@@ -79,7 +79,7 @@ public class ApolloConfig {
.add("appId", appId)
.add("cluster", cluster)
.add("namespace", namespace)
.add("releaseId", releaseId)
.add("releaseKey", releaseKey)
.add("configurations", configurations)
.toString();
}
......
......@@ -3,6 +3,8 @@ package com.ctrip.apollo.core.dto;
public class ReleaseDTO{
private long id;
private String releaseKey;
private String name;
private String appId;
......@@ -23,6 +25,14 @@ public class ReleaseDTO{
this.id = id;
}
public String getReleaseKey() {
return releaseKey;
}
public void setReleaseKey(String releaseKey) {
this.releaseKey = releaseKey;
}
public String getAppId() {
return appId;
}
......
package com.ctrip.apollo.core.schedule;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ExponentialSchedulePolicy implements SchedulePolicy {
private final long delayTimeLowerBound;
private final long delayTimeUpperBound;
private long lastDelayTime;
public ExponentialSchedulePolicy(long delayTimeLowerBound, long delayTimeUpperBound) {
this.delayTimeLowerBound = delayTimeLowerBound;
this.delayTimeUpperBound = delayTimeUpperBound;
}
@Override
public long fail() {
long delayTime = lastDelayTime;
if (delayTime == 0) {
delayTime = delayTimeLowerBound;
} else {
delayTime = Math.min(lastDelayTime << 1, delayTimeUpperBound);
}
lastDelayTime = delayTime;
return delayTime;
}
@Override
public void success() {
lastDelayTime = 0;
}
}
package com.ctrip.apollo.core.schedule;
/**
* Schedule policy
* @author Jason Song(song_s@ctrip.com)
*/
public interface SchedulePolicy {
long fail();
void success();
}
package com.ctrip.apollo.core.utils;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ByteUtil {
private static final char[] HEX_CHARS = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static byte int3(final int x) {
return (byte) (x >> 24);
}
public static byte int2(final int x) {
return (byte) (x >> 16);
}
public static byte int1(final int x) {
return (byte) (x >> 8);
}
public static byte int0(final int x) {
return (byte) (x);
}
public static String toHexString(byte[] bytes) {
char[] chars = new char[bytes.length * 2];
int i = 0;
for (byte b : bytes) {
chars[i++] = HEX_CHARS[b >> 4 & 0xF];
chars[i++] = HEX_CHARS[b & 0xF];
}
return new String(chars);
}
}
package com.ctrip.apollo.core.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.NetworkInterface;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.Enumeration;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class MachineUtil {
private static final Logger logger = LoggerFactory.getLogger(MachineUtil.class);
private static final int MACHINE_IDENTIFIER = createMachineIdentifier();
public static int getMachineIdentifier() {
return MACHINE_IDENTIFIER;
}
/**
* Get the machine identifier from mac address
*
* @see <a href=https://github.com/mongodb/mongo-java-driver/blob/master/bson/src/main/org/bson/types/ObjectId.java>ObjectId.java</a>
*/
private static int createMachineIdentifier() {
// build a 2-byte machine piece based on NICs info
int machinePiece;
try {
StringBuilder sb = new StringBuilder();
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
NetworkInterface ni = e.nextElement();
sb.append(ni.toString());
byte[] mac = ni.getHardwareAddress();
if (mac != null) {
ByteBuffer bb = ByteBuffer.wrap(mac);
try {
sb.append(bb.getChar());
sb.append(bb.getChar());
sb.append(bb.getChar());
} catch (BufferUnderflowException shortHardwareAddressException) { //NOPMD
// mac with less than 6 bytes. continue
}
}
}
machinePiece = sb.toString().hashCode();
} catch (Throwable ex) {
// exception sometimes happens with IBM JVM, use random
machinePiece = (new SecureRandom().nextInt());
logger.warn(
"Failed to get machine identifier from network interface, using random number instead",
ex);
}
return machinePiece;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册