Commit ea2770fa by Jason Song

Add instance related controller to admin service

parent e1589efa
package com.ctrip.framework.apollo.adminservice.controller;
import com.ctrip.framework.apollo.biz.entity.Instance;
import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
import com.ctrip.framework.apollo.biz.entity.Release;
import com.ctrip.framework.apollo.biz.service.InstanceService;
import com.ctrip.framework.apollo.biz.service.ReleaseService;
import com.ctrip.framework.apollo.common.dto.InstanceConfigDTO;
import com.ctrip.framework.apollo.common.dto.InstanceDTO;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.common.exception.NotFoundException;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RestController
@RequestMapping(path = "/instances")
public class InstanceConfigController {
@Autowired
private ReleaseService releaseService;
@Autowired
private InstanceService instanceService;
@RequestMapping(value = "/by-release", method = RequestMethod.GET)
public List<InstanceDTO> getByRelease(@RequestParam("releaseId") long releaseId,
@RequestParam(value = "withReleaseDetail", defaultValue =
"false") boolean withReleaseDetail,
Pageable pageable) {
Release release = releaseService.findOne(releaseId);
if (release == null) {
throw new NotFoundException(String.format("release not found for %s", releaseId));
}
List<InstanceConfig> instanceConfigs = instanceService.findActiveInstanceConfigsByReleaseKey
(release.getReleaseKey(), pageable);
if (instanceConfigs.isEmpty()) {
return Collections.emptyList();
}
Map<Long, List<InstanceConfig>> instanceConfigMap = instanceConfigs.stream().collect(Collectors
.groupingBy(InstanceConfig::getInstanceId));
List<Instance> instances = instanceService.findInstancesByIds(instanceConfigMap.keySet());
if (instances.isEmpty()) {
return Collections.emptyList();
}
return instances.stream().map(transformToInstanceConfigDto).peek(instanceDTO -> {
List<InstanceConfig> instanceConfigList = instanceConfigMap.get(instanceDTO.getId());
ReleaseDTO releaseDTO = withReleaseDetail ? BeanUtils.transfrom(ReleaseDTO.class, release)
: null;
instanceDTO.setConfigs(instanceConfigList.stream()
.map(instanceConfig -> transformToInstanceConfigDto(instanceConfig, releaseDTO))
.collect(Collectors.toList()));
}).collect(Collectors.toList());
}
private InstanceConfigDTO transformToInstanceConfigDto(InstanceConfig instanceConfig,
ReleaseDTO releaseDTO) {
InstanceConfigDTO instanceConfigDTO = new InstanceConfigDTO();
instanceConfigDTO.setDataChangeLastModifiedTime(instanceConfig
.getDataChangeLastModifiedTime());
instanceConfigDTO.setRelease(releaseDTO);
return instanceConfigDTO;
}
private static Function<Instance, InstanceDTO> transformToInstanceConfigDto = instance -> {
InstanceDTO instanceDTO = new InstanceDTO();
instanceDTO.setId(instance.getId());
instanceDTO.setAppId(instance.getAppId());
instanceDTO.setClusterName(instance.getClusterName());
instanceDTO.setDataCenter(instance.getDataCenter());
instanceDTO.setIp(instance.getIp());
instanceDTO.setDataChangeCreatedTime(instance.getDataChangeCreatedTime());
return instanceDTO;
};
}
package com.ctrip.framework.apollo.adminservice;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import com.ctrip.framework.apollo.adminservice.aop.NamespaceLockTest;
import com.ctrip.framework.apollo.adminservice.controller.AppControllerTest;
import com.ctrip.framework.apollo.adminservice.controller.ControllerExceptionTest;
import com.ctrip.framework.apollo.adminservice.controller.ControllerIntegrationExceptionTest;
import com.ctrip.framework.apollo.adminservice.controller.InstanceConfigControllerTest;
import com.ctrip.framework.apollo.adminservice.controller.ItemSetControllerTest;
import com.ctrip.framework.apollo.adminservice.controller.ReleaseControllerTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({AppControllerTest.class, ReleaseControllerTest.class, ItemSetControllerTest.class,
ControllerExceptionTest.class, ControllerIntegrationExceptionTest.class, NamespaceLockTest.class})
@SuiteClasses({
AppControllerTest.class, ReleaseControllerTest.class, ItemSetControllerTest.class,
ControllerExceptionTest.class, ControllerIntegrationExceptionTest.class,
NamespaceLockTest.class, InstanceConfigControllerTest.class
})
public class AllTests {
}
package com.ctrip.framework.apollo.adminservice.controller;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.biz.entity.Instance;
import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
import com.ctrip.framework.apollo.biz.entity.Release;
import com.ctrip.framework.apollo.biz.service.InstanceService;
import com.ctrip.framework.apollo.biz.service.ReleaseService;
import com.ctrip.framework.apollo.common.dto.InstanceDTO;
import com.ctrip.framework.apollo.common.exception.NotFoundException;
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.data.domain.Pageable;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class InstanceConfigControllerTest {
private InstanceConfigController instanceConfigController;
@Mock
private ReleaseService releaseService;
@Mock
private InstanceService instanceService;
@Mock
private Pageable pageable;
@Before
public void setUp() throws Exception {
instanceConfigController = new InstanceConfigController();
ReflectionTestUtils.setField(instanceConfigController, "releaseService", releaseService);
ReflectionTestUtils.setField(instanceConfigController, "instanceService", instanceService);
}
@Test
public void getByRelease() throws Exception {
long someReleaseId = 1;
long someInstanceId = 1;
long anotherInstanceId = 2;
String someReleaseKey = "someKey";
Release someRelease = new Release();
someRelease.setReleaseKey(someReleaseKey);
String someAppId = "someAppId";
String anotherAppId = "anotherAppId";
String someCluster = "someCluster";
String someDataCenter = "someDC";
String someConfigAppId = "someConfigAppId";
String someConfigNamespace = "someNamespace";
String someIp = "someIp";
boolean withReleaseDetail = true;
when(releaseService.findOne(someReleaseId)).thenReturn(someRelease);
InstanceConfig someInstanceConfig = assembleInstanceConfig(someInstanceId, someConfigAppId,
someConfigNamespace, someReleaseKey);
InstanceConfig anotherInstanceConfig = assembleInstanceConfig(anotherInstanceId,
someConfigAppId, someConfigNamespace, someReleaseKey);
List<InstanceConfig> instanceConfigs = Lists.newArrayList(someInstanceConfig,
anotherInstanceConfig);
when(instanceService.findActiveInstanceConfigsByReleaseKey(someReleaseKey, pageable))
.thenReturn(instanceConfigs);
Instance someInstance = assembleInstance(someInstanceId, someAppId,
someCluster, someDataCenter, someIp);
Instance anotherInstance = assembleInstance(anotherInstanceId, anotherAppId,
someCluster, someDataCenter, someIp);
List<Instance> instances = Lists.newArrayList(someInstance, anotherInstance);
Set<Long> instanceIds = Sets.newHashSet(someInstanceId, anotherInstanceId);
when(instanceService.findInstancesByIds(instanceIds))
.thenReturn(instances);
List<InstanceDTO> result = instanceConfigController.getByRelease(someReleaseId,
withReleaseDetail, pageable);
assertEquals(2, result.size());
InstanceDTO someInstanceDto = null;
InstanceDTO anotherInstanceDto = null;
for (InstanceDTO instanceDTO : result) {
if (instanceDTO.getId() == someInstanceId) {
someInstanceDto = instanceDTO;
} else if (instanceDTO.getId() == anotherInstanceId) {
anotherInstanceDto = instanceDTO;
}
}
verifyInstance(someInstance, someInstanceDto);
verifyInstance(anotherInstance, anotherInstanceDto);
assertEquals(1, someInstanceDto.getConfigs().size());
assertEquals(someReleaseKey, someInstanceDto.getConfigs().get(0).getRelease().getReleaseKey());
assertEquals(someInstanceConfig.getDataChangeLastModifiedTime(), someInstanceDto.getConfigs()
.get(0).getDataChangeLastModifiedTime());
assertEquals(1, anotherInstanceDto.getConfigs().size());
assertEquals(someReleaseKey, anotherInstanceDto.getConfigs().get(0).getRelease().getReleaseKey());
assertEquals(anotherInstanceConfig.getDataChangeLastModifiedTime(), anotherInstanceDto.getConfigs()
.get(0).getDataChangeLastModifiedTime());
}
@Test(expected = NotFoundException.class)
public void testGetByReleaseWhenReleaseIsNotFound() throws Exception {
long someReleaseIdNotExists = 1;
boolean withReleaseDetail = false;
when(releaseService.findOne(someReleaseIdNotExists)).thenReturn(null);
instanceConfigController.getByRelease(someReleaseIdNotExists, withReleaseDetail, pageable);
}
private void verifyInstance(Instance instance, InstanceDTO instanceDTO) {
assertEquals(instance.getId(), instanceDTO.getId());
assertEquals(instance.getAppId(), instanceDTO.getAppId());
assertEquals(instance.getClusterName(), instanceDTO.getClusterName());
assertEquals(instance.getDataCenter(), instanceDTO.getDataCenter());
assertEquals(instance.getIp(), instanceDTO.getIp());
assertEquals(instance.getDataChangeCreatedTime(), instanceDTO.getDataChangeCreatedTime());
}
private Instance assembleInstance(long instanceId, String appId, String clusterName, String
dataCenter, String
ip) {
Instance instance = new Instance();
instance.setId(instanceId);
instance.setAppId(appId);
instance.setIp(ip);
instance.setClusterName(clusterName);
instance.setDataCenter(dataCenter);
instance.setDataChangeCreatedTime(new Date());
return instance;
}
private InstanceConfig assembleInstanceConfig(long instanceId, String configAppId, String
configNamespaceName, String releaseKey) {
InstanceConfig instanceConfig = new InstanceConfig();
instanceConfig.setInstanceId(instanceId);
instanceConfig.setConfigAppId(configAppId);
instanceConfig.setConfigNamespaceName(configNamespaceName);
instanceConfig.setReleaseKey(releaseKey);
instanceConfig.setDataChangeLastModifiedTime(new Date());
return instanceConfig;
}
}
\ No newline at end of file
......@@ -2,8 +2,16 @@ package com.ctrip.framework.apollo.biz.repository;
import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.Date;
import java.util.List;
public interface InstanceConfigRepository extends PagingAndSortingRepository<InstanceConfig, Long> {
InstanceConfig findByInstanceIdAndConfigAppIdAndConfigNamespaceName(long instanceId, String configAppId, String configNamespaceName);
InstanceConfig findByInstanceIdAndConfigAppIdAndConfigNamespaceName(long instanceId, String
configAppId, String configNamespaceName);
List<InstanceConfig> findByReleaseKeyAndDataChangeLastModifiedTimeAfter(String releaseKey, Date
validDate, Pageable pageable);
}
package com.ctrip.framework.apollo.biz.service;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.ctrip.framework.apollo.biz.entity.Instance;
import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
......@@ -8,9 +9,16 @@ import com.ctrip.framework.apollo.biz.repository.InstanceConfigRepository;
import com.ctrip.framework.apollo.biz.repository.InstanceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author Jason Song(song_s@ctrip.com)
*/
......@@ -27,6 +35,14 @@ public class InstanceService {
dataCenter, ip);
}
public List<Instance> findInstancesByIds(Set<Long> instanceIds) {
Iterable<Instance> instances = instanceRepository.findAll(instanceIds);
if (instances == null) {
return Collections.emptyList();
}
return Lists.newArrayList(instances);
}
@Transactional
public Instance createInstance(Instance instance) {
instance.setId(0); //protection
......@@ -40,6 +56,28 @@ public class InstanceService {
instanceId, configAppId, configNamespaceName);
}
public List<InstanceConfig> findActiveInstanceConfigsByReleaseKey(String releaseKey, Pageable
pageable) {
List<InstanceConfig> instanceConfigs = instanceConfigRepository
.findByReleaseKeyAndDataChangeLastModifiedTimeAfter(releaseKey,
getValidInstanceConfigDate(), pageable);
if (instanceConfigs == null) {
return Collections.emptyList();
}
return instanceConfigs;
}
/**
* Currently the instance config is expired by 1 day, add one more hour to avoid possible time
* difference
*/
private Date getValidInstanceConfigDate() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
cal.add(Calendar.HOUR, -1);
return cal.getTime();
}
@Transactional
public InstanceConfig createInstanceConfig(InstanceConfig instanceConfig) {
instanceConfig.setId(0); //protection
......
package com.ctrip.framework.apollo.biz.service;
import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.biz.AbstractIntegrationTest;
import com.ctrip.framework.apollo.biz.entity.Instance;
import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.annotation.Rollback;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -19,7 +32,7 @@ public class InstanceServiceTest extends AbstractIntegrationTest {
@Test
@Rollback
public void testInstance() throws Exception {
public void testCreateAndFindInstance() throws Exception {
String someAppId = "someAppId";
String someClusterName = "someClusterName";
String someDataCenter = "someDataCenter";
......@@ -41,7 +54,29 @@ public class InstanceServiceTest extends AbstractIntegrationTest {
@Test
@Rollback
public void testInstanceConfig() throws Exception {
public void testFindInstancesByIds() throws Exception {
String someAppId = "someAppId";
String someClusterName = "someClusterName";
String someDataCenter = "someDataCenter";
String someIp = "someIp";
String anotherIp = "anotherIp";
Instance someInstance = instanceService.createInstance(assembleInstance(someAppId,
someClusterName, someDataCenter, someIp));
Instance anotherInstance = instanceService.createInstance(assembleInstance(someAppId,
someClusterName, someDataCenter, anotherIp));
List<Instance> instances = instanceService.findInstancesByIds(Sets.newHashSet(someInstance
.getId(), anotherInstance.getId()));
Set<String> ips = instances.stream().map(Instance::getIp).collect(Collectors.toSet());
assertEquals(2, instances.size());
assertEquals(Sets.newHashSet(someIp, anotherIp), ips);
}
@Test
@Rollback
public void testCreateAndFindInstanceConfig() throws Exception {
long someInstanceId = 1;
String someConfigAppId = "someConfigAppId";
String someConfigNamespaceName = "someConfigNamespaceName";
......@@ -73,7 +108,40 @@ public class InstanceServiceTest extends AbstractIntegrationTest {
assertEquals(anotherReleaseKey, updated.getReleaseKey());
}
private Instance assembleInstance(String appId, String clusterName, String dataCenter, String ip) {
@Test
@Rollback
public void testFindActiveInstanceConfigs() throws Exception {
long someInstanceId = 1;
long anotherInstanceId = 2;
String someConfigAppId = "someConfigAppId";
String someConfigNamespaceName = "someConfigNamespaceName";
String someReleaseKey = "someReleaseKey";
Date someValidDate = new Date();
Pageable pageable = new PageRequest(0, 10);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -2);
Date someInvalidDate = calendar.getTime();
InstanceConfig someValidConfig = assembleInstanceConfig(someInstanceId, someConfigAppId,
someConfigNamespaceName, someReleaseKey);
someValidConfig.setDataChangeCreatedTime(someValidDate);
InstanceConfig someInvalidConfig = assembleInstanceConfig(anotherInstanceId, someConfigAppId,
someConfigNamespaceName, someReleaseKey);
someInvalidConfig.setDataChangeCreatedTime(someInvalidDate);
instanceService.createInstanceConfig(someValidConfig);
instanceService.createInstanceConfig(someInvalidConfig);
List<InstanceConfig> validInstanceConfigs = instanceService
.findActiveInstanceConfigsByReleaseKey(someReleaseKey, pageable);
assertEquals(1, validInstanceConfigs.size());
assertEquals(someInstanceId, validInstanceConfigs.get(0).getInstanceId());
}
private Instance assembleInstance(String appId, String clusterName, String dataCenter, String
ip) {
Instance instance = new Instance();
instance.setAppId(appId);
instance.setIp(ip);
......
package com.ctrip.framework.apollo.common.dto;
import java.util.Date;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class InstanceConfigDTO {
private ReleaseDTO release;
private Date dataChangeLastModifiedTime;
public ReleaseDTO getRelease() {
return release;
}
public void setRelease(ReleaseDTO release) {
this.release = release;
}
public Date getDataChangeLastModifiedTime() {
return dataChangeLastModifiedTime;
}
public void setDataChangeLastModifiedTime(Date dataChangeLastModifiedTime) {
this.dataChangeLastModifiedTime = dataChangeLastModifiedTime;
}
}
package com.ctrip.framework.apollo.common.dto;
import java.util.Date;
import java.util.List;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class InstanceDTO {
private long id;
private String appId;
private String clusterName;
private String dataCenter;
private String ip;
private List<InstanceConfigDTO> configs;
private Date dataChangeCreatedTime;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getClusterName() {
return clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public String getDataCenter() {
return dataCenter;
}
public void setDataCenter(String dataCenter) {
this.dataCenter = dataCenter;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public List<InstanceConfigDTO> getConfigs() {
return configs;
}
public void setConfigs(List<InstanceConfigDTO> configs) {
this.configs = configs;
}
public Date getDataChangeCreatedTime() {
return dataChangeCreatedTime;
}
public void setDataChangeCreatedTime(Date dataChangeCreatedTime) {
this.dataChangeCreatedTime = dataChangeCreatedTime;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment