package com.ctrip.framework.apollo.configservice.controller;
import com.google.common.base.Joiner;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.biz.entity.ReleaseMessage;
import com.ctrip.framework.apollo.biz.message.Topics;
import com.ctrip.framework.apollo.biz.utils.EntityManagerUtil;
import com.ctrip.framework.apollo.configservice.service.ReleaseMessageServiceWithCache;
import com.ctrip.framework.apollo.configservice.util.NamespaceUtil;
import com.ctrip.framework.apollo.configservice.util.WatchKeysUtil;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification;
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.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class NotificationControllerTest {
private NotificationController controller;
private String someAppId;
private String someCluster;
private String defaultCluster;
private String defaultNamespace;
private String somePublicNamespace;
private String someDataCenter;
private long someNotificationId;
private String someClientIp;
@Mock
private ReleaseMessageServiceWithCache releaseMessageService;
@Mock
private EntityManagerUtil entityManagerUtil;
@Mock
private NamespaceUtil namespaceUtil;
@Mock
private WatchKeysUtil watchKeysUtil;
private Multimap<String, DeferredResult<ResponseEntity<ApolloConfigNotification>>>
deferredResults;
@Before
public void setUp() throws Exception {
controller = new NotificationController();
ReflectionTestUtils.setField(controller, "releaseMessageService", releaseMessageService);
ReflectionTestUtils.setField(controller, "entityManagerUtil", entityManagerUtil);
ReflectionTestUtils.setField(controller, "namespaceUtil", namespaceUtil);
ReflectionTestUtils.setField(controller, "watchKeysUtil", watchKeysUtil);
someAppId = "someAppId";
someCluster = "someCluster";
defaultCluster = ConfigConsts.CLUSTER_NAME_DEFAULT;
defaultNamespace = ConfigConsts.NAMESPACE_APPLICATION;
somePublicNamespace = "somePublicNamespace";
someDataCenter = "someDC";
someNotificationId = 1;
someClientIp = "someClientIp";
when(namespaceUtil.filterNamespaceName(defaultNamespace)).thenReturn(defaultNamespace);
when(namespaceUtil.filterNamespaceName(somePublicNamespace)).thenReturn(somePublicNamespace);
deferredResults =
(Multimap<String, DeferredResult<ResponseEntity<ApolloConfigNotification>>>) ReflectionTestUtils
.getField(controller, "deferredResults");
}
@Test
public void testPollNotificationWithDefaultNamespace() throws Exception {
String someWatchKey = "someKey";
String anotherWatchKey = "anotherKey";
Set<String> watchKeys = Sets.newHashSet(someWatchKey, anotherWatchKey);
when(watchKeysUtil
.assembleAllWatchKeys(someAppId, someCluster, defaultNamespace,
someDataCenter)).thenReturn(
watchKeys);
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter,
someNotificationId, someClientIp);
assertEquals(watchKeys.size(), deferredResults.size());
for (String watchKey : watchKeys) {
assertTrue(deferredResults.get(watchKey).contains(deferredResult));
}
}
@Test
public void testPollNotificationWithDefaultNamespaceAsFile() throws Exception {
String namespace = String.format("%s.%s", defaultNamespace, "properties");
when(namespaceUtil.filterNamespaceName(namespace)).thenReturn(defaultNamespace);
String someWatchKey = "someKey";
String anotherWatchKey = "anotherKey";
Set<String> watchKeys = Sets.newHashSet(someWatchKey, anotherWatchKey);
when(watchKeysUtil
.assembleAllWatchKeys(someAppId, someCluster, defaultNamespace,
someDataCenter)).thenReturn(
watchKeys);
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, namespace, someDataCenter,
someNotificationId, someClientIp);
assertEquals(watchKeys.size(), deferredResults.size());
for (String watchKey : watchKeys) {
assertTrue(deferredResults.get(watchKey).contains(deferredResult));
}
}
@Test
public void testPollNotificationWithSomeNamespaceAsFile() throws Exception {
String namespace = String.format("someNamespace.xml");
when(namespaceUtil.filterNamespaceName(namespace)).thenReturn(namespace);
String someWatchKey = "someKey";
Set<String> watchKeys = Sets.newHashSet(someWatchKey);
when(watchKeysUtil
.assembleAllWatchKeys(someAppId, someCluster, namespace, someDataCenter))
.thenReturn(
watchKeys);
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, namespace, someDataCenter,
someNotificationId, someClientIp);
assertEquals(watchKeys.size(), deferredResults.size());
for (String watchKey : watchKeys) {
assertTrue(deferredResults.get(watchKey).contains(deferredResult));
}
}
@Test
public void testPollNotificationWithDefaultNamespaceWithNotificationIdOutDated()
throws Exception {
long notificationId = someNotificationId + 1;
String releaseMessage = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
.join(someAppId, someCluster, defaultNamespace);
ReleaseMessage someReleaseMessage = mock(ReleaseMessage.class);
String someWatchKey = "someKey";
Set<String> watchKeys = Sets.newHashSet(someWatchKey);
when(watchKeysUtil
.assembleAllWatchKeys(someAppId, someCluster, defaultNamespace,
someDataCenter))
.thenReturn(
watchKeys);
when(someReleaseMessage.getId()).thenReturn(notificationId);
when(someReleaseMessage.getMessage()).thenReturn(releaseMessage);
when(releaseMessageService.findLatestReleaseMessageForMessages(watchKeys))
.thenReturn(someReleaseMessage);
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter,
someNotificationId, someClientIp);
ResponseEntity<ApolloConfigNotification> result =
(ResponseEntity<ApolloConfigNotification>) deferredResult.getResult();
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals(defaultNamespace, result.getBody().getNamespaceName());
assertEquals(notificationId, result.getBody().getNotificationId());
}
@Test
public void testPollNotificationWithDefaultNamespaceAndHandleMessage() throws Exception {
String someWatchKey = "someKey";
String anotherWatchKey = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
.join(someAppId, someCluster, defaultNamespace);
Set<String> watchKeys = Sets.newHashSet(someWatchKey, anotherWatchKey);
when(watchKeysUtil
.assembleAllWatchKeys(someAppId, someCluster, defaultNamespace,
someDataCenter)).thenReturn(
watchKeys);
DeferredResult<ResponseEntity<ApolloConfigNotification>>
deferredResult = controller
.pollNotification(someAppId, someCluster, defaultNamespace, someDataCenter,
someNotificationId, someClientIp);
long someId = 1;
ReleaseMessage someReleaseMessage = new ReleaseMessage(anotherWatchKey);
someReleaseMessage.setId(someId);
controller.handleMessage(someReleaseMessage, Topics.APOLLO_RELEASE_TOPIC);
ResponseEntity<ApolloConfigNotification> response =
(ResponseEntity<ApolloConfigNotification>) deferredResult.getResult();
ApolloConfigNotification notification = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(defaultNamespace, notification.getNamespaceName());
assertEquals(someId, notification.getNotificationId());
}
}