package com.ctrip.framework.apollo.configservice.integration;
import com.google.common.base.Joiner;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.dto.ApolloConfig;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.web.client.HttpStatusCodeException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest {
private String someAppId;
private String somePublicAppId;
private String someCluster;
private String someNamespace;
private String somePublicNamespace;
private String someDC;
private String someDefaultCluster;
private String someClientIp;
private ExecutorService executorService;
@Before
public void setUp() throws Exception {
someAppId = "someAppId";
someCluster = "someCluster";
someNamespace = "someNamespace";
somePublicAppId = "somePublicAppId";
somePublicNamespace = "somePublicNamespace";
someDC = "someDC";
someDefaultCluster = ConfigConsts.CLUSTER_NAME_DEFAULT;
someClientIp = "1.1.1.1";
executorService = Executors.newSingleThreadExecutor();
}
@Test
@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 testQueryConfigWithDefaultClusterAndDefaultNamespaceOK() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION);
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("TEST-RELEASE-KEY1", result.getReleaseKey());
assertEquals("v1", result.getConfigurations().get("k1"));
}
@Test
@Sql(scripts = "/integration-test/test-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/test-gray-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryGrayConfigWithDefaultClusterAndDefaultNamespaceOK() throws Exception {
AtomicBoolean stop = new AtomicBoolean();
periodicSendMessage(executorService, assembleKey(someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION),
stop);
TimeUnit.MILLISECONDS.sleep(500);
stop.set(true);
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?ip={clientIp}", ApolloConfig.class,
getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION, someClientIp);
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("TEST-GRAY-RELEASE-KEY1", result.getReleaseKey());
assertEquals("v1-gray", result.getConfigurations().get("k1"));
}
@Test
@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 testQueryConfigFileWithDefaultClusterAndDefaultNamespaceOK() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION + ".properties");
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("TEST-RELEASE-KEY1", result.getReleaseKey());
assertEquals("v1", result.getConfigurations().get("k1"));
}
@Test
@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 testQueryConfigWithNamespaceOK() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), someAppId, someCluster, someNamespace);
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("TEST-RELEASE-KEY2", result.getReleaseKey());
assertEquals("v2", result.getConfigurations().get("k2"));
}
@Test
@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 testQueryConfigFileWithNamespaceOK() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, someNamespace + ".xml");
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("TEST-RELEASE-KEY5", result.getReleaseKey());
assertEquals("v1-file", result.getConfigurations().get("k1"));
assertEquals("v2-file", result.getConfigurations().get("k2"));
}
@Test
public void testQueryConfigError() throws Exception {
String someNamespaceNotExists = "someNamespaceNotExists";
HttpStatusCodeException httpException = null;
try {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), someAppId, someCluster, someNamespaceNotExists);
} catch (HttpStatusCodeException ex) {
httpException = ex;
}
assertEquals(HttpStatus.NOT_FOUND, httpException.getStatusCode());
}
@Test
@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 releaseKey = "TEST-RELEASE-KEY2";
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?releaseKey={releaseKey}",
ApolloConfig.class,
getHostUrl(), someAppId, someCluster, someNamespace, releaseKey);
assertEquals(HttpStatus.NOT_MODIFIED, response.getStatusCode());
}
@Test
@Sql(scripts = "/integration-test/test-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/test-gray-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryPublicGrayConfigWithNoOverride() throws Exception {
AtomicBoolean stop = new AtomicBoolean();
periodicSendMessage(executorService, assembleKey(somePublicAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, somePublicNamespace),
stop);
TimeUnit.MILLISECONDS.sleep(500);
stop.set(true);
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?ip={clientIp}", ApolloConfig.class,
getHostUrl(), someAppId, someCluster, somePublicNamespace, someClientIp);
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("TEST-GRAY-RELEASE-KEY2", result.getReleaseKey());
assertEquals("gray-v1", result.getConfigurations().get("k1"));
assertEquals("gray-v2", result.getConfigurations().get("k2"));
}
@Test
@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 testQueryPublicConfigWithDataCenterFoundAndNoOverride() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}",
ApolloConfig.class,
getHostUrl(), someAppId, someCluster, somePublicNamespace, someDC);
ApolloConfig result = response.getBody();
assertEquals("TEST-RELEASE-KEY4", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespaceName());
assertEquals("someDC-v1", result.getConfigurations().get("k1"));
assertEquals("someDC-v2", result.getConfigurations().get("k2"));
}
@Test
@Sql(scripts = "/integration-test/test-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/test-release-public-dc-override.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryPublicConfigWithDataCenterFoundAndOverride() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}",
ApolloConfig.class,
getHostUrl(), someAppId, someDefaultCluster, somePublicNamespace, someDC);
ApolloConfig result = response.getBody();
assertEquals(
"TEST-RELEASE-KEY6" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "TEST-RELEASE-KEY4",
result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someDC, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespaceName());
assertEquals("override-someDC-v1", result.getConfigurations().get("k1"));
assertEquals("someDC-v2", result.getConfigurations().get("k2"));
}
@Test
@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 testQueryPublicConfigWithDataCenterNotFoundAndNoOverride() throws Exception {
String someDCNotFound = "someDCNotFound";
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}",
ApolloConfig.class,
getHostUrl(), someAppId, someCluster, somePublicNamespace, someDCNotFound);
ApolloConfig result = response.getBody();
assertEquals("TEST-RELEASE-KEY3", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespaceName());
assertEquals("default-v1", result.getConfigurations().get("k1"));
assertEquals("default-v2", result.getConfigurations().get("k2"));
}
@Test
@Sql(scripts = "/integration-test/test-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/test-release-public-default-override.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryPublicConfigWithDataCenterNotFoundAndOverride() throws Exception {
String someDCNotFound = "someDCNotFound";
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}",
ApolloConfig.class,
getHostUrl(), someAppId, someDefaultCluster, somePublicNamespace, someDCNotFound);
ApolloConfig result = response.getBody();
assertEquals(
"TEST-RELEASE-KEY5" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "TEST-RELEASE-KEY3",
result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(someDefaultCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespaceName());
assertEquals("override-v1", result.getConfigurations().get("k1"));
assertEquals("default-v2", result.getConfigurations().get("k2"));
}
@Test
@Sql(scripts = "/integration-test/test-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/test-release-public-default-override.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/test-gray-release.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/integration-test/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryPublicGrayConfigWithOverride() throws Exception {
AtomicBoolean stop = new AtomicBoolean();
periodicSendMessage(executorService, assembleKey(somePublicAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, somePublicNamespace),
stop);
TimeUnit.MILLISECONDS.sleep(500);
stop.set(true);
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?ip={clientIp}", ApolloConfig.class,
getHostUrl(), someAppId, someDefaultCluster, somePublicNamespace, someClientIp);
ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(
"TEST-RELEASE-KEY5" + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + "TEST-GRAY-RELEASE-KEY2",
result.getReleaseKey());
assertEquals("override-v1", result.getConfigurations().get("k1"));
assertEquals("gray-v2", result.getConfigurations().get("k2"));
}
@Test
@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 testQueryPrivateConfigFileWithPublicNamespaceExists() throws Exception {
String namespaceName = "anotherNamespace";
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}",
ApolloConfig.class,
getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, namespaceName);
ApolloConfig result = response.getBody();
assertEquals("TEST-RELEASE-KEY6", result.getReleaseKey());
assertEquals(someAppId, result.getAppId());
assertEquals(ConfigConsts.CLUSTER_NAME_DEFAULT, result.getCluster());
assertEquals(namespaceName, result.getNamespaceName());
assertEquals("v1-file", result.getConfigurations().get("k1"));
assertEquals(null, result.getConfigurations().get("k2"));
}
@Test
public void testQueryConfigForNoAppIdPlaceHolderWithPrivateNamespace() throws Exception {
HttpStatusCodeException httpException = null;
try {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), ConfigConsts.NO_APPID_PLACEHOLDER, someCluster, ConfigConsts.NAMESPACE_APPLICATION);
} catch (HttpStatusCodeException ex) {
httpException = ex;
}
assertEquals(HttpStatus.NOT_FOUND, httpException.getStatusCode());
}
@Test
@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 testQueryPublicConfigForNoAppIdPlaceHolder() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}",
ApolloConfig.class,
getHostUrl(), ConfigConsts.NO_APPID_PLACEHOLDER, someCluster, somePublicNamespace, someDC);
ApolloConfig result = response.getBody();
assertEquals("TEST-RELEASE-KEY4", result.getReleaseKey());
assertEquals(ConfigConsts.NO_APPID_PLACEHOLDER, result.getAppId());
assertEquals(someCluster, result.getCluster());
assertEquals(somePublicNamespace, result.getNamespaceName());
assertEquals("someDC-v1", result.getConfigurations().get("k1"));
assertEquals("someDC-v2", result.getConfigurations().get("k2"));
}
private String assembleKey(String appId, String cluster, String namespace) {
return Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).join(appId, cluster, namespace);
}
}