TSK-575 Created General handling error log system for REST API

This commit is contained in:
Martin Rojas Miguel Angel 2018-06-20 15:24:47 +02:00 committed by Holger Hagen
parent 766cb64621
commit 8425ec32b4
3 changed files with 153 additions and 2 deletions

View File

@ -364,7 +364,7 @@ public class ClassificationServiceImpl implements ClassificationService {
Classification classification = this.classificationMapper.findByKeyAndDomain(classificationKey, domain); Classification classification = this.classificationMapper.findByKeyAndDomain(classificationKey, domain);
if (classification == null) { if (classification == null) {
throw new ClassificationNotFoundException(classificationKey, domain, throw new ClassificationNotFoundException(classificationKey, domain,
"The classification " + classificationKey + "wasn't found in the domain " + domain); "The classification \"" + classificationKey + "\" wasn't found in the domain " + domain);
} }
deleteClassification(classification.getId()); deleteClassification(classification.getId());
} finally { } finally {
@ -383,7 +383,7 @@ public class ClassificationServiceImpl implements ClassificationService {
Classification classification = this.classificationMapper.findById(classificationId); Classification classification = this.classificationMapper.findById(classificationId);
if (classification == null) { if (classification == null) {
throw new ClassificationNotFoundException(classificationId, throw new ClassificationNotFoundException(classificationId,
"The classification " + classificationId + "wasn't found"); "The classification \"" + classificationId + "\" wasn't found");
} }
if (classification.getDomain().equals("")) { if (classification.getDomain().equals("")) {

View File

@ -0,0 +1,135 @@
package pro.taskana.rest;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
import pro.taskana.ldap.LdapCacheTestImpl;
import pro.taskana.rest.resource.AccessIdResource;
import pro.taskana.rest.resource.ClassificationSummaryResource;
import pro.taskana.rest.resource.assembler.ClassificationResourceAssembler;
import pro.taskana.rest.resource.assembler.TaskResourceAssembler;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RestConfiguration.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
"devMode=true"})
public class GenenalExceptionHandlingTest {
@Autowired
private ClassificationResourceAssembler classificationResourceAssembler;
@Autowired
private TaskResourceAssembler taskResourceAssembler;
String server = "http://127.0.0.1:";
RestTemplate template;
HttpEntity<String> request;
HttpHeaders headers = new HttpHeaders();
@LocalServerPort
int port;
@Mock
private Appender mockAppender;
@Captor
private ArgumentCaptor<LoggingEvent> captorLoggingEvent;
@Before
public void before() {
template = getRestTemplate();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
request = new HttpEntity<String>(headers);
final Logger logger = (Logger) LoggerFactory.getLogger(TaskanaRestExceptionHandler.class);
logger.addAppender(mockAppender);
}
//Always have this teardown otherwise we can stuff up our expectations. Besides, it's
//good coding practise
@After
public void teardown() {
final Logger logger = (Logger) LoggerFactory.getLogger(TaskanaRestExceptionHandler.class);
logger.detachAppender(mockAppender);
}
@Test
public void testAccessIdValidationMinimunValueExceptionIsLogged() {
try {
AccessIdController.setLdapCache(new LdapCacheTestImpl());
ResponseEntity<List<AccessIdResource>> response = template.exchange(
server + port + "/v1/access-ids?searchFor=al", HttpMethod.GET, request,
new ParameterizedTypeReference<List<AccessIdResource>>() {
});
} catch (Exception ex) {
verify(mockAppender).doAppend(captorLoggingEvent.capture());
assertTrue(captorLoggingEvent.getValue().getMessage().contains("is too short. Minimum Length ="));
}
}
@Test
public void testDeleteNonExisitingClassificationExceptionIsLogged() {
try {
ResponseEntity<PagedResources<ClassificationSummaryResource>> response = template.exchange(
server + port + "/v1/classifications/non-existing-id", HttpMethod.DELETE, request,
new ParameterizedTypeReference<PagedResources<ClassificationSummaryResource>>() {
});
} catch (Exception ex){
verify(mockAppender).doAppend(captorLoggingEvent.capture());
assertTrue(captorLoggingEvent.getValue().getMessage().contains("The classification \"non-existing-id\" wasn't found"));
}
}
/**
* Return a REST template which is capable of dealing with responses in HAL format
*
* @return RestTemplate
*/
private RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate(Collections.<HttpMessageConverter<?>>singletonList(converter));
return template;
}
}

View File

@ -1,5 +1,7 @@
package pro.taskana.rest; package pro.taskana.rest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -34,6 +36,8 @@ import pro.taskana.exceptions.WorkbasketNotFoundException;
@ControllerAdvice @ControllerAdvice
public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler { public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaRestExceptionHandler.class);
@ExceptionHandler(InvalidArgumentException.class) @ExceptionHandler(InvalidArgumentException.class)
protected ResponseEntity<Object> handleInvalidArgument(InvalidArgumentException ex, WebRequest req) { protected ResponseEntity<Object> handleInvalidArgument(InvalidArgumentException ex, WebRequest req) {
return buildResponse(ex, req, HttpStatus.BAD_REQUEST); return buildResponse(ex, req, HttpStatus.BAD_REQUEST);
@ -112,9 +116,21 @@ public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler
return buildResponse(ex, req, HttpStatus.BAD_REQUEST); return buildResponse(ex, req, HttpStatus.BAD_REQUEST);
} }
@ExceptionHandler(Exception.class)
protected ResponseEntity<Object> handleGeneralException(Exception ex, WebRequest req) {
return buildResponse(ex, req, HttpStatus.BAD_REQUEST);
}
private ResponseEntity<Object> buildResponse(Exception ex, WebRequest req, HttpStatus status) { private ResponseEntity<Object> buildResponse(Exception ex, WebRequest req, HttpStatus status) {
TaskanaErrorData errorData = new TaskanaErrorData(status, ex, req); TaskanaErrorData errorData = new TaskanaErrorData(status, ex, req);
logError(ex, errorData);
return new ResponseEntity<>(errorData, status); return new ResponseEntity<>(errorData, status);
} }
private void logError(Exception ex, TaskanaErrorData errorData) {
LOGGER.error(
"Error occured during processing of rest request:\n" + errorData.toString(),
ex);
}
} }