Search in sources :

Example 21 with ReleaseMessage

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;
}
Also used : ReleaseMessage(com.ctrip.framework.apollo.biz.entity.ReleaseMessage)

Example 22 with ReleaseMessage

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;
}
Also used : ResponseEntity(org.springframework.http.ResponseEntity) ReleaseMessage(com.ctrip.framework.apollo.biz.entity.ReleaseMessage) ApolloConfigNotification(com.ctrip.framework.apollo.core.dto.ApolloConfigNotification) DeferredResult(org.springframework.web.context.request.async.DeferredResult) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 23 with ReleaseMessage

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());
}
Also used : ReleaseMessage(com.ctrip.framework.apollo.biz.entity.ReleaseMessage) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Cache(com.google.common.cache.Cache) Test(org.junit.Test)

Example 24 with ReleaseMessage

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());
}
Also used : ResponseEntity(org.springframework.http.ResponseEntity) ReleaseMessage(com.ctrip.framework.apollo.biz.entity.ReleaseMessage) ApolloNotificationMessages(com.ctrip.framework.apollo.core.dto.ApolloNotificationMessages) ApolloConfigNotification(com.ctrip.framework.apollo.core.dto.ApolloConfigNotification) List(java.util.List) Test(org.junit.Test)

Example 25 with ReleaseMessage

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()));
}
Also used : ResponseEntity(org.springframework.http.ResponseEntity) ReleaseMessage(com.ctrip.framework.apollo.biz.entity.ReleaseMessage) ApolloConfigNotification(com.ctrip.framework.apollo.core.dto.ApolloConfigNotification) Test(org.junit.Test)

Aggregations

ReleaseMessage (com.ctrip.framework.apollo.biz.entity.ReleaseMessage)30 Test (org.junit.Test)16 ApolloConfigNotification (com.ctrip.framework.apollo.core.dto.ApolloConfigNotification)9 ResponseEntity (org.springframework.http.ResponseEntity)7 AbstractUnitTest (com.ctrip.framework.apollo.biz.AbstractUnitTest)3 Release (com.ctrip.framework.apollo.biz.entity.Release)3 ApolloNotificationMessages (com.ctrip.framework.apollo.core.dto.ApolloNotificationMessages)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 BizConfig (com.ctrip.framework.apollo.biz.config.BizConfig)2 ReleaseMessageRepository (com.ctrip.framework.apollo.biz.repository.ReleaseMessageRepository)2 Transaction (com.ctrip.framework.apollo.tracer.spi.Transaction)2 Lists (com.google.common.collect.Lists)2 Sets (com.google.common.collect.Sets)2 SettableFuture (com.google.common.util.concurrent.SettableFuture)2 TimeUnit (java.util.concurrent.TimeUnit)2 Awaitility (org.awaitility.Awaitility)2 Awaitility.await (org.awaitility.Awaitility.await)2 Assert.assertEquals (org.junit.Assert.assertEquals)2 Assert.assertSame (org.junit.Assert.assertSame)2