use of com.ctrip.framework.apollo.biz.entity.ReleaseMessage in project apollo by ctripcorp.
the class ReleaseMessageServiceWithCache method findLatestReleaseMessageForMessages.
public ReleaseMessage findLatestReleaseMessageForMessages(Set<String> messages) {
if (CollectionUtils.isEmpty(messages)) {
return null;
}
long maxReleaseMessageId = 0;
ReleaseMessage result = null;
for (String message : messages) {
ReleaseMessage releaseMessage = releaseMessageCache.get(message);
if (releaseMessage != null && releaseMessage.getId() > maxReleaseMessageId) {
maxReleaseMessageId = releaseMessage.getId();
result = releaseMessage;
}
}
return result;
}
use of com.ctrip.framework.apollo.biz.entity.ReleaseMessage in project apollo by ctripcorp.
the class NotificationController method pollNotification.
/**
* For single namespace notification, reserved for older version of apollo clients
*
* @param appId the appId
* @param cluster the cluster
* @param namespace the namespace name
* @param dataCenter the datacenter
* @param notificationId the notification id for the namespace
* @param clientIp the client side ip
* @return a deferred result
*/
@GetMapping
public DeferredResult<ResponseEntity<ApolloConfigNotification>> pollNotification(@RequestParam(value = "appId") String appId, @RequestParam(value = "cluster") String cluster, @RequestParam(value = "namespace", defaultValue = ConfigConsts.NAMESPACE_APPLICATION) String namespace, @RequestParam(value = "dataCenter", required = false) String dataCenter, @RequestParam(value = "notificationId", defaultValue = "-1") long notificationId, @RequestParam(value = "ip", required = false) String clientIp) {
// strip out .properties suffix
namespace = namespaceUtil.filterNamespaceName(namespace);
Set<String> watchedKeys = watchKeysUtil.assembleAllWatchKeys(appId, cluster, namespace, dataCenter);
DeferredResult<ResponseEntity<ApolloConfigNotification>> deferredResult = new DeferredResult<>(TIMEOUT, NOT_MODIFIED_RESPONSE);
// check whether client is out-dated
ReleaseMessage latest = releaseMessageService.findLatestReleaseMessageForMessages(watchedKeys);
/**
* Manually close the entity manager.
* Since for async request, Spring won't do so until the request is finished,
* which is unacceptable since we are doing long polling - means the db connection would be hold
* for a very long time
*/
entityManagerUtil.closeEntityManager();
if (latest != null && latest.getId() != notificationId) {
deferredResult.setResult(new ResponseEntity<>(new ApolloConfigNotification(namespace, latest.getId()), HttpStatus.OK));
} else {
// register all keys
for (String key : watchedKeys) {
this.deferredResults.put(key, deferredResult);
}
deferredResult.onTimeout(() -> logWatchedKeys(watchedKeys, "Apollo.LongPoll.TimeOutKeys"));
deferredResult.onCompletion(() -> {
// unregister all keys
for (String key : watchedKeys) {
deferredResults.remove(key, deferredResult);
}
logWatchedKeys(watchedKeys, "Apollo.LongPoll.CompletedKeys");
});
logWatchedKeys(watchedKeys, "Apollo.LongPoll.RegisteredKeys");
logger.debug("Listening {} from appId: {}, cluster: {}, namespace: {}, datacenter: {}", watchedKeys, appId, cluster, namespace, dataCenter);
}
return deferredResult;
}
use of com.ctrip.framework.apollo.biz.entity.ReleaseMessage in project apollo by ctripcorp.
the class ConfigFileControllerTest method testHandleMessage.
@Test
public void testHandleMessage() throws Exception {
String someWatchKey = "someWatchKey";
String anotherWatchKey = "anotherWatchKey";
String someCacheKey = "someCacheKey";
String anotherCacheKey = "anotherCacheKey";
String someValue = "someValue";
ReleaseMessage someReleaseMessage = mock(ReleaseMessage.class);
when(someReleaseMessage.getMessage()).thenReturn(someWatchKey);
Cache<String, String> cache = (Cache<String, String>) ReflectionTestUtils.getField(configFileController, "localCache");
cache.put(someCacheKey, someValue);
cache.put(anotherCacheKey, someValue);
watchedKeys2CacheKey.putAll(someWatchKey, Lists.newArrayList(someCacheKey, anotherCacheKey));
watchedKeys2CacheKey.putAll(anotherWatchKey, Lists.newArrayList(someCacheKey, anotherCacheKey));
cacheKey2WatchedKeys.putAll(someCacheKey, Lists.newArrayList(someWatchKey, anotherWatchKey));
cacheKey2WatchedKeys.putAll(anotherCacheKey, Lists.newArrayList(someWatchKey, anotherWatchKey));
configFileController.handleMessage(someReleaseMessage, Topics.APOLLO_RELEASE_TOPIC);
assertTrue(watchedKeys2CacheKey.isEmpty());
assertTrue(cacheKey2WatchedKeys.isEmpty());
}
use of com.ctrip.framework.apollo.biz.entity.ReleaseMessage in project apollo by ctripcorp.
the class NotificationControllerV2Test method testPollNotificationWithIncorrectCase.
@Test
public void testPollNotificationWithIncorrectCase() throws Exception {
String appIdWithIncorrectCase = someAppId.toUpperCase();
String namespaceWithIncorrectCase = defaultNamespace.toUpperCase();
String someMessage = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).join(someAppId, someCluster, defaultNamespace);
String someWatchKey = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).join(appIdWithIncorrectCase, someCluster, defaultNamespace);
Multimap<String, String> watchKeysMap = assembleMultiMap(defaultNamespace, Lists.newArrayList(someWatchKey));
String notificationAsString = transformApolloConfigNotificationsToString(defaultNamespace.toUpperCase(), someNotificationId);
when(namespaceUtil.filterNamespaceName(namespaceWithIncorrectCase)).thenReturn(namespaceWithIncorrectCase);
when(namespaceUtil.normalizeNamespace(appIdWithIncorrectCase, namespaceWithIncorrectCase)).thenReturn(defaultNamespace);
when(watchKeysUtil.assembleAllWatchKeys(appIdWithIncorrectCase, someCluster, Sets.newHashSet(defaultNamespace), someDataCenter)).thenReturn(watchKeysMap);
DeferredResult<ResponseEntity<List<ApolloConfigNotification>>> deferredResult = controller.pollNotification(appIdWithIncorrectCase, someCluster, notificationAsString, someDataCenter, someClientIp);
long someId = 1;
ReleaseMessage someReleaseMessage = new ReleaseMessage(someMessage);
someReleaseMessage.setId(someId);
controller.handleMessage(someReleaseMessage, Topics.APOLLO_RELEASE_TOPIC);
assertTrue(deferredResult.hasResult());
ResponseEntity<List<ApolloConfigNotification>> response = (ResponseEntity<List<ApolloConfigNotification>>) deferredResult.getResult();
assertEquals(1, response.getBody().size());
ApolloConfigNotification notification = response.getBody().get(0);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(namespaceWithIncorrectCase, notification.getNamespaceName());
assertEquals(someId, notification.getNotificationId());
ApolloNotificationMessages notificationMessages = notification.getMessages();
assertEquals(1, notificationMessages.getDetails().size());
assertEquals(someId, notificationMessages.get(someMessage).longValue());
}
use of com.ctrip.framework.apollo.biz.entity.ReleaseMessage in project apollo by ctripcorp.
the class NotificationControllerV2Test method testPollNotificationWithHandleMessageInBatch.
@Test
public void testPollNotificationWithHandleMessageInBatch() throws Exception {
String someWatchKey = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).join(someAppId, someCluster, defaultNamespace);
int someBatch = 1;
int someBatchInterval = 10;
Multimap<String, String> watchKeysMap = assembleMultiMap(defaultNamespace, Lists.newArrayList(someWatchKey));
String notificationAsString = transformApolloConfigNotificationsToString(defaultNamespace, someNotificationId);
when(watchKeysUtil.assembleAllWatchKeys(someAppId, someCluster, Sets.newHashSet(defaultNamespace), someDataCenter)).thenReturn(watchKeysMap);
when(bizConfig.releaseMessageNotificationBatch()).thenReturn(someBatch);
when(bizConfig.releaseMessageNotificationBatchIntervalInMilli()).thenReturn(someBatchInterval);
DeferredResult<ResponseEntity<List<ApolloConfigNotification>>> deferredResult = controller.pollNotification(someAppId, someCluster, notificationAsString, someDataCenter, someClientIp);
DeferredResult<ResponseEntity<List<ApolloConfigNotification>>> anotherDeferredResult = controller.pollNotification(someAppId, someCluster, notificationAsString, someDataCenter, someClientIp);
long someId = 1;
ReleaseMessage someReleaseMessage = new ReleaseMessage(someWatchKey);
someReleaseMessage.setId(someId);
controller.handleMessage(someReleaseMessage, Topics.APOLLO_RELEASE_TOPIC);
// in batch mode, at most one of them should have result
assertFalse(deferredResult.hasResult() && anotherDeferredResult.hasResult());
// now both of them should have result
await().atMost(someBatchInterval * 500, TimeUnit.MILLISECONDS).untilAsserted(() -> assertTrue(deferredResult.hasResult() && anotherDeferredResult.hasResult()));
}
Aggregations