use of com.ctrip.framework.apollo.util.http.HttpRequest in project apollo by ctripcorp.
the class RemoteConfigLongPollServiceTest method testSubmitLongPollMultipleNamespaces.
@Test
public void testSubmitLongPollMultipleNamespaces() throws Exception {
RemoteConfigRepository someRepository = mock(RemoteConfigRepository.class);
RemoteConfigRepository anotherRepository = mock(RemoteConfigRepository.class);
final String someNamespace = "someNamespace";
final String anotherNamespace = "anotherNamespace";
final ApolloConfigNotification someNotification = mock(ApolloConfigNotification.class);
when(someNotification.getNamespaceName()).thenReturn(someNamespace);
final ApolloConfigNotification anotherNotification = mock(ApolloConfigNotification.class);
when(anotherNotification.getNamespaceName()).thenReturn(anotherNamespace);
final SettableFuture<Boolean> submitAnotherNamespaceStart = SettableFuture.create();
final SettableFuture<Boolean> submitAnotherNamespaceFinish = SettableFuture.create();
doAnswer(new Answer<HttpResponse<List<ApolloConfigNotification>>>() {
final AtomicInteger counter = new AtomicInteger();
@Override
public HttpResponse<List<ApolloConfigNotification>> answer(InvocationOnMock invocation) throws Throwable {
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
}
// the first time
if (counter.incrementAndGet() == 1) {
HttpRequest request = invocation.getArgument(0, HttpRequest.class);
assertTrue(request.getUrl().contains("notifications="));
assertTrue(request.getUrl().contains(someNamespace));
submitAnotherNamespaceStart.set(true);
when(pollResponse.getStatusCode()).thenReturn(HttpServletResponse.SC_OK);
when(pollResponse.getBody()).thenReturn(Lists.newArrayList(someNotification));
} else if (submitAnotherNamespaceFinish.get()) {
HttpRequest request = invocation.getArgument(0, HttpRequest.class);
assertTrue(request.getUrl().contains("notifications="));
assertTrue(request.getUrl().contains(someNamespace));
assertTrue(request.getUrl().contains(anotherNamespace));
when(pollResponse.getStatusCode()).thenReturn(HttpServletResponse.SC_OK);
when(pollResponse.getBody()).thenReturn(Lists.newArrayList(anotherNotification));
} else {
when(pollResponse.getStatusCode()).thenReturn(HttpServletResponse.SC_NOT_MODIFIED);
when(pollResponse.getBody()).thenReturn(null);
}
return pollResponse;
}
}).when(httpClient).doGet(any(HttpRequest.class), eq(responseType));
final SettableFuture<Boolean> onAnotherRepositoryNotified = SettableFuture.create();
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
onAnotherRepositoryNotified.set(true);
return null;
}
}).when(anotherRepository).onLongPollNotified(Mockito.any(ServiceDTO.class), Mockito.nullable(ApolloNotificationMessages.class));
remoteConfigLongPollService.submit(someNamespace, someRepository);
submitAnotherNamespaceStart.get(5000, TimeUnit.MILLISECONDS);
remoteConfigLongPollService.submit(anotherNamespace, anotherRepository);
submitAnotherNamespaceFinish.set(true);
onAnotherRepositoryNotified.get(5000, TimeUnit.MILLISECONDS);
remoteConfigLongPollService.stopLongPollingRefresh();
verify(someRepository, times(1)).onLongPollNotified(Mockito.any(ServiceDTO.class), Mockito.nullable(ApolloNotificationMessages.class));
verify(anotherRepository, times(1)).onLongPollNotified(Mockito.any(ServiceDTO.class), Mockito.nullable(ApolloNotificationMessages.class));
}
use of com.ctrip.framework.apollo.util.http.HttpRequest in project apollo by ctripcorp.
the class RemoteConfigRepositoryTest method testLoadConfigWithAccessKeySecret.
@Test
public void testLoadConfigWithAccessKeySecret() throws Exception {
someSecret = "someSecret";
String someKey = "someKey";
String someValue = "someValue";
Map<String, String> configurations = Maps.newHashMap();
configurations.put(someKey, someValue);
ApolloConfig someApolloConfig = assembleApolloConfig(configurations);
when(someResponse.getStatusCode()).thenReturn(200);
when(someResponse.getBody()).thenReturn(someApolloConfig);
doAnswer(new Answer<HttpResponse<ApolloConfig>>() {
@Override
public HttpResponse<ApolloConfig> answer(InvocationOnMock invocation) throws Throwable {
HttpRequest request = invocation.getArgument(0, HttpRequest.class);
Map<String, String> headers = request.getHeaders();
assertNotNull(headers);
assertTrue(headers.containsKey(Signature.HTTP_HEADER_TIMESTAMP));
assertTrue(headers.containsKey(HttpHeaders.AUTHORIZATION));
return someResponse;
}
}).when(httpClient).doGet(any(HttpRequest.class), any(Class.class));
RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace);
Properties config = remoteConfigRepository.getConfig();
assertEquals(configurations, config);
assertEquals(ConfigSourceType.REMOTE, remoteConfigRepository.getSourceType());
remoteConfigLongPollService.stopLongPollingRefresh();
}
use of com.ctrip.framework.apollo.util.http.HttpRequest in project apollo by ctripcorp.
the class RemoteConfigRepository method loadApolloConfig.
private ApolloConfig loadApolloConfig() {
if (!m_loadConfigRateLimiter.tryAcquire(5, TimeUnit.SECONDS)) {
// wait at most 5 seconds
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
}
String appId = m_configUtil.getAppId();
String cluster = m_configUtil.getCluster();
String dataCenter = m_configUtil.getDataCenter();
String secret = m_configUtil.getAccessKeySecret();
Tracer.logEvent("Apollo.Client.ConfigMeta", STRING_JOINER.join(appId, cluster, m_namespace));
int maxRetries = m_configNeedForceRefresh.get() ? 2 : 1;
// 0 means no sleep
long onErrorSleepTime = 0;
Throwable exception = null;
List<ServiceDTO> configServices = getConfigServices();
String url = null;
retryLoopLabel: for (int i = 0; i < maxRetries; i++) {
List<ServiceDTO> randomConfigServices = Lists.newLinkedList(configServices);
Collections.shuffle(randomConfigServices);
// Access the server which notifies the client first
if (m_longPollServiceDto.get() != null) {
randomConfigServices.add(0, m_longPollServiceDto.getAndSet(null));
}
for (ServiceDTO configService : randomConfigServices) {
if (onErrorSleepTime > 0) {
logger.warn("Load config failed, will retry in {} {}. appId: {}, cluster: {}, namespaces: {}", onErrorSleepTime, m_configUtil.getOnErrorRetryIntervalTimeUnit(), appId, cluster, m_namespace);
try {
m_configUtil.getOnErrorRetryIntervalTimeUnit().sleep(onErrorSleepTime);
} catch (InterruptedException e) {
// ignore
}
}
url = assembleQueryConfigUrl(configService.getHomepageUrl(), appId, cluster, m_namespace, dataCenter, m_remoteMessages.get(), m_configCache.get());
logger.debug("Loading config from {}", url);
HttpRequest request = new HttpRequest(url);
if (!StringUtils.isBlank(secret)) {
Map<String, String> headers = Signature.buildHttpHeaders(url, appId, secret);
request.setHeaders(headers);
}
Transaction transaction = Tracer.newTransaction("Apollo.ConfigService", "queryConfig");
transaction.addData("Url", url);
try {
HttpResponse<ApolloConfig> response = m_httpClient.doGet(request, ApolloConfig.class);
m_configNeedForceRefresh.set(false);
m_loadConfigFailSchedulePolicy.success();
transaction.addData("StatusCode", response.getStatusCode());
transaction.setStatus(Transaction.SUCCESS);
if (response.getStatusCode() == 304) {
logger.debug("Config server responds with 304 HTTP status code.");
return m_configCache.get();
}
ApolloConfig result = response.getBody();
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);
}
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(statusCodeException));
transaction.setStatus(statusCodeException);
exception = statusCodeException;
if (ex.getStatusCode() == 404) {
break retryLoopLabel;
}
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
transaction.setStatus(ex);
exception = ex;
} finally {
transaction.complete();
}
// if force refresh, do normal sleep, if normal config load, do exponential sleep
onErrorSleepTime = m_configNeedForceRefresh.get() ? m_configUtil.getOnErrorRetryInterval() : m_loadConfigFailSchedulePolicy.fail();
}
}
String message = String.format("Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s, url: %s", appId, cluster, m_namespace, url);
throw new ApolloConfigException(message, exception);
}
use of com.ctrip.framework.apollo.util.http.HttpRequest in project apollo by ctripcorp.
the class RemoteConfigLongPollService method doLongPollingRefresh.
private void doLongPollingRefresh(String appId, String cluster, String dataCenter, String secret) {
final Random random = new Random();
ServiceDTO lastServiceDto = null;
while (!m_longPollingStopped.get() && !Thread.currentThread().isInterrupted()) {
if (!m_longPollRateLimiter.tryAcquire(5, TimeUnit.SECONDS)) {
// wait at most 5 seconds
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
}
Transaction transaction = Tracer.newTransaction("Apollo.ConfigService", "pollNotification");
String url = null;
try {
if (lastServiceDto == null) {
List<ServiceDTO> configServices = getConfigServices();
lastServiceDto = configServices.get(random.nextInt(configServices.size()));
}
url = assembleLongPollRefreshUrl(lastServiceDto.getHomepageUrl(), appId, cluster, dataCenter, m_notifications);
logger.debug("Long polling from {}", url);
HttpRequest request = new HttpRequest(url);
request.setReadTimeout(LONG_POLLING_READ_TIMEOUT);
if (!StringUtils.isBlank(secret)) {
Map<String, String> headers = Signature.buildHttpHeaders(url, appId, secret);
request.setHeaders(headers);
}
transaction.addData("Url", url);
final HttpResponse<List<ApolloConfigNotification>> response = m_httpClient.doGet(request, m_responseType);
logger.debug("Long polling response: {}, url: {}", response.getStatusCode(), url);
if (response.getStatusCode() == 200 && response.getBody() != null) {
updateNotifications(response.getBody());
updateRemoteNotifications(response.getBody());
transaction.addData("Result", response.getBody().toString());
notify(lastServiceDto, response.getBody());
}
// try to load balance
if (response.getStatusCode() == 304 && random.nextBoolean()) {
lastServiceDto = null;
}
m_longPollFailSchedulePolicyInSecond.success();
transaction.addData("StatusCode", response.getStatusCode());
transaction.setStatus(Transaction.SUCCESS);
} catch (Throwable ex) {
lastServiceDto = null;
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
transaction.setStatus(ex);
long sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.fail();
logger.warn("Long polling failed, will retry in {} seconds. appId: {}, cluster: {}, namespaces: {}, long polling url: {}, reason: {}", sleepTimeInSecond, appId, cluster, assembleNamespaces(), url, ExceptionUtil.getDetailMessage(ex));
try {
TimeUnit.SECONDS.sleep(sleepTimeInSecond);
} catch (InterruptedException ie) {
// ignore
}
} finally {
transaction.complete();
}
}
}
use of com.ctrip.framework.apollo.util.http.HttpRequest in project apollo by ctripcorp.
the class ConfigServiceLocator method updateConfigServices.
private synchronized void updateConfigServices() {
String url = assembleMetaServiceUrl();
HttpRequest request = new HttpRequest(url);
int maxRetries = 2;
Throwable exception = null;
for (int i = 0; i < maxRetries; i++) {
Transaction transaction = Tracer.newTransaction("Apollo.MetaService", "getConfigService");
transaction.addData("Url", url);
try {
HttpResponse<List<ServiceDTO>> response = m_httpClient.doGet(request, m_responseType);
transaction.setStatus(Transaction.SUCCESS);
List<ServiceDTO> services = response.getBody();
if (services == null || services.isEmpty()) {
logConfigService("Empty response!");
continue;
}
setConfigServices(services);
return;
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
transaction.setStatus(ex);
exception = ex;
} finally {
transaction.complete();
}
try {
m_configUtil.getOnErrorRetryIntervalTimeUnit().sleep(m_configUtil.getOnErrorRetryInterval());
} catch (InterruptedException ex) {
// ignore
}
}
throw new ApolloConfigException(String.format("Get config services failed from %s", url), exception);
}
Aggregations