Commit 6141e812 by Jason Song

Merge pull request #130 from yiming187/exception_update

Update exception
parents cde0de19 166f154a
......@@ -10,8 +10,10 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.service.ConfigService;
import com.ctrip.apollo.biz.service.NamespaceService;
import com.ctrip.apollo.biz.service.ReleaseService;
import com.ctrip.apollo.biz.service.ViewService;
import com.ctrip.apollo.common.auth.ActiveUser;
......@@ -31,6 +33,9 @@ public class ReleaseController {
@Autowired
private ConfigService configService;
@Autowired
private NamespaceService namespaceService;
@RequestMapping("/release/{releaseId}")
public ReleaseDTO get(@PathVariable("releaseId") long releaseId) {
Release release = releaseService.findOne(releaseId);
......@@ -66,8 +71,12 @@ public class ReleaseController {
@PathVariable("namespaceName") String namespaceName, @RequestParam("name") String name,
@RequestParam(name = "comment", required = false) String comment,
@ActiveUser UserDetails user) {
Release release = releaseService.buildRelease(name, comment, appId, clusterName, namespaceName,
user.getUsername());
Namespace namespace = namespaceService.findOne(appId, clusterName, namespaceName);
if (namespace == null) {
throw new NotFoundException(String.format("Could not find namespace for %s %s %s", appId,
clusterName, namespaceName));
}
Release release = releaseService.buildRelease(name, comment, namespace, user.getUsername());
return BeanUtils.transfrom(ReleaseDTO.class, release);
}
}
......@@ -11,21 +11,24 @@ INSERT INTO Cluster (AppId, Name) VALUES ('100003173', 'default');
INSERT INTO Cluster (AppId, Name) VALUES ('100003173', 'cluster3');
INSERT INTO Cluster (AppId, Name) VALUES ('fxhermesproducer', 'default');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003171', 'application');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003172', 'application');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003173', 'application');
INSERT INTO AppNamespace (AppID, Name) VALUES ('fxhermesproducer', 'application');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003171', '100003171');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003171', 'fx.apollo.config');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003172', '100003172');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003172', 'fx.apollo.admin');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003173', '100003173');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003173', 'fx.apollo.portal');
INSERT INTO AppNamespace (AppID, Name) VALUES ('fxhermesproducer', 'fx.hermes.producer');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (1, '100003171', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (2, 'fxhermesproducer', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (3, '100003172', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (4, '100003173', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (5, '100003171', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (1, '100003171', 'default', '100003171');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (2, 'fxhermesproducer', 'default', 'fx.hermes.producer');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (3, '100003172', 'default', '100003172');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (4, '100003173', 'default', '100003173');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (5, '100003171', 'default', '100003171');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (1, 'k1', 'v1', 'comment1');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (1, 'k2', 'v2', 'comment2');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (2, 'k3', 'v3', 'comment3');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (5, 'k3', 'v4', 'comment4');
INSERT INTO RELEASE (Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('REV1','First Release','100003171', 'default', 'application', '{"k1":"v1"}');
INSERT INTO RELEASE (Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('REV1','First Release','100003171', 'default', '100003171', '{"k1":"v1"}');
package com.ctrip.apollo.biz.service;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
......@@ -27,32 +26,28 @@ public class ConfigService {
private Gson gson = new Gson();
private Type configurationTypeReference = new TypeToken<Map<String, String>>(){}.getType();
private Type configurationTypeReference = new TypeToken<Map<String, String>>() {}.getType();
public Release findRelease(String appId, String clusterName, String namespaceName) {
Release release = releaseRepository.findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(appId, clusterName, namespaceName);
Release release = releaseRepository.findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(
appId, clusterName, namespaceName);
return release;
}
/**
* Load configuration from database
*/
public ApolloConfig loadConfig(Release release, String namespaceName) {
public ApolloConfig loadConfig(Release release) {
if (release == null) {
return null;
}
ApolloConfig config = new ApolloConfig(release.getAppId(), release.getClusterName(),
namespaceName, String.valueOf(release.getId()));
release.getNamespaceName(), String.valueOf(release.getId()));
config.setConfigurations(transformConfigurationToMap(release.getConfigurations()));
return config;
}
Map<String, String> transformConfigurationToMap(String configurations) {
try {
return gson.fromJson(configurations, configurationTypeReference);
} catch (Throwable e) {
e.printStackTrace();
return Maps.newHashMap();
}
return gson.fromJson(configurations, configurationTypeReference);
}
}
......@@ -11,8 +11,6 @@ import com.ctrip.apollo.common.utils.BeanUtils;
import com.ctrip.apollo.core.dto.ItemChangeSets;
import com.ctrip.apollo.core.dto.ItemDTO;
import java.util.Date;
@Service
public class ItemSetService {
......
......@@ -14,9 +14,7 @@ import com.ctrip.apollo.biz.entity.Item;
import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.repository.ItemRepository;
import com.ctrip.apollo.biz.repository.NamespaceRepository;
import com.ctrip.apollo.biz.repository.ReleaseRepository;
import com.ctrip.apollo.core.exception.NotFoundException;
import com.ctrip.apollo.core.utils.StringUtils;
import com.google.gson.Gson;
......@@ -30,9 +28,6 @@ public class ReleaseService {
private ReleaseRepository releaseRepository;
@Autowired
private NamespaceRepository namespaceRepository;
@Autowired
private ItemRepository itemRepository;
@Autowired
......@@ -46,14 +41,7 @@ public class ReleaseService {
}
@Transactional
public Release buildRelease(String name, String comment, String appId, String clusterName,
String namespaceName, String owner) {
Namespace namespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(appId,
clusterName, namespaceName);
if (namespace == null) {
throw new NotFoundException(String.format("Could not find namespace for %s %s %s", appId,
clusterName, namespaceName));
}
public Release buildRelease(String name, String comment, Namespace namespace, String owner) {
List<Item> items = itemRepository.findByNamespaceIdOrderByLineNumAsc(namespace.getId());
Map<String, String> configurations = new HashMap<String, String>();
for (Item item : items) {
......@@ -68,9 +56,9 @@ public class ReleaseService {
release.setDataChangeCreatedBy(owner);
release.setName(name);
release.setComment(comment);
release.setAppId(appId);
release.setClusterName(clusterName);
release.setNamespaceName(namespaceName);
release.setAppId(namespace.getAppId());
release.setClusterName(namespace.getClusterName());
release.setNamespaceName(namespace.getNamespaceName());
release.setConfigurations(gson.toJson(configurations));
release = releaseRepository.save(release);
......
package com.ctrip.apollo.biz.service;
import com.google.common.collect.Maps;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.repository.ReleaseRepository;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
......@@ -12,10 +16,11 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.ctrip.apollo.biz.entity.Release;
import com.ctrip.apollo.biz.repository.ReleaseRepository;
import com.ctrip.apollo.core.dto.ApolloConfig;
import com.google.common.collect.Maps;
import com.google.gson.JsonSyntaxException;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -24,91 +29,58 @@ import static org.junit.Assert.assertTrue;
public class ConfigServiceTest {
@Mock
private ReleaseRepository releaseRepository;
private ConfigService configService;
@Before
public void setUp() throws Exception {
configService = new ConfigService();
ReflectionTestUtils
.setField(configService, "releaseRepository", releaseRepository);
ReflectionTestUtils.setField(configService, "releaseRepository", releaseRepository);
}
// @Test
// public void testLoadConfig() throws Exception {
// String someAppId = "1";
// String someClusterName = "someClusterName";
// String someGroupName = "someGroupName";
// String someVersionName = "someVersionName";
// long someReleaseId = 1;
// String someValidConfiguration = "{\"apollo.bar\": \"foo\"}";
//
// Version someVersion = assembleVersion(someAppId, someVersionName, someReleaseId);
// Release
// someRelease =
// assembleRelease(someReleaseId, someClusterName, someGroupName, someValidConfiguration);
// Map<String, Object> someMap = Maps.newHashMap();
//
// when(versionRepository.findByAppIdAndName(someAppId, someVersionName)).thenReturn(someVersion);
// when(releaseRepository.findByReleaseIdAndClusterName(someReleaseId, someClusterName))
// .thenReturn(someReleaseSnapShot);
// when(objectMapper.readValue(eq(someValidConfiguration), (TypeReference) anyObject()))
// .thenReturn(someMap);
//
// ApolloConfig result = configService.loadConfig(someAppId, someClusterName, someVersionName);
//
// assertEquals(someAppId, result.getAppId());
// assertEquals(someClusterName, result.getCluster());
// assertEquals(someVersionName, result.getVersion());
// assertEquals(someReleaseId, result.getReleaseId());
// assertEquals(someMap, result.getConfigurations());
// }
//
// @Test
// public void testLoadConfigWithVersionNotFound() throws Exception {
// String someAppId = "1";
// String someClusterName = "someClusterName";
// String someVersionName = "someVersionName";
//
// when(versionRepository.findByAppIdAndName(someAppId, someVersionName)).thenReturn(null);
//
// ApolloConfig result = configService.loadConfig(someAppId, someClusterName, someVersionName);
//
// assertNull(result);
// verify(versionRepository, times(1)).findByAppIdAndName(someAppId, someVersionName);
// }
//
// @Test
// public void testLoadConfigWithConfigNotFound() throws Exception {
// String someAppId = "1";
// String someClusterName = "someClusterName";
// String someVersionName = "someVersionName";
// long someReleaseId = 1;
// Version someVersion = assembleVersion(someAppId, someVersionName, someReleaseId);
//
// when(versionRepository.findByAppIdAndName(someAppId, someVersionName)).thenReturn(someVersion);
// when(releaseRepository.findByReleaseIdAndClusterName(someReleaseId, someClusterName))
// .thenReturn(null);
//
// ApolloConfig result = configService.loadConfig(someAppId, someClusterName, someVersionName);
//
// assertNull(result);
// verify(versionRepository, times(1)).findByAppIdAndName(someAppId, someVersionName);
// verify(releaseRepository, times(1))
// .findByReleaseIdAndClusterName(someReleaseId, someClusterName);
// }
//
// private Version assembleVersion(String appId, String versionName, long releaseId) {
// Version version = new Version();
// version.setAppId(appId);
// version.setName(versionName);
// version.setReleaseId(releaseId);
// return version;
// }
private Release assembleRelease(long releaseId, String clusterName, String groupName,
String configurations) {
@Test
public void testLoadConfig() throws Exception {
String someAppId = "1";
String someClusterName = "someClusterName";
String someGroupName = "someGroupName";
String someReleaseId = "1";
String someValidConfiguration = "{\"apollo.bar\": \"foo\"}";
Release someRelease = assembleRelease(someReleaseId, someAppId, someClusterName, someGroupName,
someValidConfiguration);
when(releaseRepository.findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(someAppId,
someClusterName, someGroupName)).thenReturn(someRelease);
ApolloConfig result = configService.loadConfig(someRelease);
assertEquals(someAppId, result.getAppId());
assertEquals(someClusterName, result.getCluster());
assertEquals(someReleaseId, result.getReleaseId());
assertEquals("foo", result.getConfigurations().get("apollo.bar"));
}
@Test
public void testLoadConfigWithConfigNotFound() throws Exception {
String someAppId = "1";
String someClusterName = "someClusterName";
String someNamespaceName = "someNamespaceName";
when(releaseRepository.findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(someAppId,
someClusterName, someNamespaceName)).thenReturn(null);
Release someRelease = configService.findRelease(someAppId, someClusterName, someNamespaceName);
ApolloConfig result = configService.loadConfig(someRelease);
assertNull(result);
verify(releaseRepository, times(1)).findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(
someAppId, someClusterName, someNamespaceName);
}
private Release assembleRelease(String releaseId, String appId, String clusterName,
String groupName, String configurations) {
Release release = new Release();
release.setId(releaseId);
release.setId(Long.valueOf(releaseId));
release.setAppId(appId);
release.setClusterName(clusterName);
release.setNamespaceName(groupName);
release.setConfigurations(configurations);
......@@ -127,12 +99,11 @@ public class ConfigServiceTest {
assertEquals(someMap, result);
}
@Test
@Test(expected = JsonSyntaxException.class)
public void testTransformConfigurationToMapFailed() throws Exception {
String someInvalidConfiguration = "xxx";
Map<String, String>
result =
Map<String, String> result =
configService.transformConfigurationToMap(someInvalidConfiguration);
assertTrue(result.isEmpty());
......
......@@ -13,7 +13,9 @@ import com.ctrip.apollo.core.exception.AbstractBaseException;
import com.ctrip.apollo.core.exception.BadRequestException;
import com.ctrip.apollo.core.exception.NotFoundException;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
......@@ -32,6 +34,8 @@ public class GlobalDefaultExceptionHandler {
private Gson gson = new Gson();
private static Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
@ExceptionHandler(Exception.class)
public ResponseEntity<Map<String, Object>> exception(HttpServletRequest request, Exception ex) {
return handleError(request, INTERNAL_SERVER_ERROR, ex);
......@@ -85,8 +89,7 @@ public class GlobalDefaultExceptionHandler {
@ExceptionHandler(HttpStatusCodeException.class)
public ResponseEntity<Map<String, Object>> restTemplateException(HttpServletRequest request,
HttpStatusCodeException ex) {
@SuppressWarnings("unchecked")
Map<String, Object> errorAttributes = gson.fromJson(ex.getResponseBodyAsString(), Map.class);
Map<String, Object> errorAttributes = gson.fromJson(ex.getResponseBodyAsString(), mapType);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_JSON);
return new ResponseEntity<>(errorAttributes, headers, ex.getStatusCode());
......
package com.ctrip.apollo.common.utils;
import java.lang.reflect.Type;
import java.util.Map;
import org.springframework.web.client.HttpStatusCodeException;
import com.google.common.base.MoreObjects;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public final class ExceptionUtils {
private static Gson gson = new Gson();
private static Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
public static String toString(HttpStatusCodeException e) {
@SuppressWarnings("unchecked")
Map<String, Object> errorAttributes = gson.fromJson(e.getResponseBodyAsString(), Map.class);
Map<String, Object> errorAttributes = gson.fromJson(e.getResponseBodyAsString(), mapType);
if (errorAttributes != null) {
return MoreObjects.toStringHelper(HttpStatusCodeException.class)
return MoreObjects.toStringHelper(HttpStatusCodeException.class).omitNullValues()
.add("status", errorAttributes.get("status"))
.add("message", errorAttributes.get("message"))
.add("timestamp", errorAttributes.get("timestamp"))
......
......@@ -55,7 +55,7 @@ public class ConfigController {
return null;
}
ApolloConfig apolloConfig = configService.loadConfig(release, namespace);
ApolloConfig apolloConfig = configService.loadConfig(release);
if (apolloConfig == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
......
......@@ -54,14 +54,14 @@ public class ConfigControllerTest {
when(configService.findRelease(someAppId, someClusterName, someNamespaceName))
.thenReturn(someRelease);
when(someRelease.getId()).thenReturn(someServerSideNewReleaseId);
when(configService.loadConfig(someRelease, someNamespaceName)).thenReturn(someApolloConfig);
when(configService.loadConfig(someRelease)).thenReturn(someApolloConfig);
ApolloConfig result = configController.queryConfig(someAppId, someClusterName,
someNamespaceName, String.valueOf(someClientSideReleaseId), someResponse);
assertEquals(someApolloConfig, result);
verify(configService, times(1)).findRelease(someAppId, someClusterName, someNamespaceName);
verify(configService, times(1)).loadConfig(someRelease, someNamespaceName);
verify(configService, times(1)).loadConfig(someRelease);
}
......@@ -95,7 +95,7 @@ public class ConfigControllerTest {
when(configService.findRelease(someAppId, someClusterName, someNamespaceName))
.thenReturn(someRelease);
when(someRelease.getId()).thenReturn(someServerSideNewReleaseId);
when(configService.loadConfig(someRelease, someNamespaceName)).thenReturn(null);
when(configService.loadConfig(someRelease)).thenReturn(null);
ApolloConfig result = configController.queryConfig(someAppId, someClusterName,
someNamespaceName, String.valueOf(someClientSideReleaseId), someResponse);
......@@ -123,6 +123,6 @@ public class ConfigControllerTest {
assertNull(result);
verify(someResponse, times(1)).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
verify(configService, never()).loadConfig(any(Release.class), anyString());
verify(configService, never()).loadConfig(any(Release.class));
}
}
......@@ -11,21 +11,24 @@ INSERT INTO Cluster (AppId, Name) VALUES ('100003173', 'default');
INSERT INTO Cluster (AppId, Name) VALUES ('100003173', 'cluster3');
INSERT INTO Cluster (AppId, Name) VALUES ('fxhermesproducer', 'default');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003171', 'application');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003172', 'application');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003173', 'application');
INSERT INTO AppNamespace (AppID, Name) VALUES ('fxhermesproducer', 'application');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003171', '100003171');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003171', 'fx.apollo.config');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003172', '100003172');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003172', 'fx.apollo.admin');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003173', '100003173');
INSERT INTO AppNamespace (AppId, Name) VALUES ('100003173', 'fx.apollo.portal');
INSERT INTO AppNamespace (AppID, Name) VALUES ('fxhermesproducer', 'fx.hermes.producer');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (1, '100003171', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (2, 'fxhermesproducer', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (3, '100003172', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (4, '100003173', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (5, '100003171', 'default', 'application');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (1, '100003171', 'default', '100003171');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (2, 'fxhermesproducer', 'default', 'fx.hermes.producer');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (3, '100003172', 'default', '100003172');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (4, '100003173', 'default', '100003173');
INSERT INTO Namespace (Id, AppId, ClusterName, NamespaceName) VALUES (5, '100003171', 'default', '100003171');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (1, 'k1', 'v1', 'comment1');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (1, 'k2', 'v2', 'comment2');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (2, 'k3', 'v3', 'comment3');
INSERT INTO Item (NamespaceId, `Key`, Value, Comment) VALUES (5, 'k3', 'v4', 'comment4');
INSERT INTO RELEASE (Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('REV1','First Release','100003171', 'default', 'application', '{"k1":"v1"}');
INSERT INTO RELEASE (Name, Comment, AppId, ClusterName, NamespaceName, Configurations) VALUES ('REV1','First Release','100003171', 'default', '100003171', '{"k1":"v1"}');
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