diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/RestHelper.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/RestHelper.java new file mode 100644 index 000000000..fe762e2e8 --- /dev/null +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/RestHelper.java @@ -0,0 +1,83 @@ +package pro.taskana; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.hateoas.hal.Jackson2HalModule; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * Helps to simplify rest api testing. + */ +@Component +public class RestHelper { + + @Autowired + Environment environment; + + public static RestTemplate template = getRestTemplate(); + + public String toUrl(String relativeUrl, Object... uriVariables) { + return UriComponentsBuilder.fromPath(relativeUrl) + .scheme("http") + .host("127.0.0.1") + .port(environment.getProperty("local.server.port")) + .build(uriVariables) + .toString(); + } + + public HttpEntity defaultRequest() { + return new HttpEntity<>(getHeaders()); + } + + public HttpHeaders getHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); + headers.add("Content-Type", "application/hal+json"); + return headers; + } + + public HttpHeaders getHeadersAdmin() { + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin + headers.add("Content-Type", "application/hal+json"); + return headers; + } + + /** + * Return a REST template which is capable of dealing with responses in HAL format. + * + * @return RestTemplate + */ + public static RestTemplate getRestTemplate() { + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.registerModule(new Jackson2HalModule()); + + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); + converter.setObjectMapper(mapper); + + RestTemplate template = new RestTemplate(); + template.getMessageConverters().clear(); + //Parse Json Strings + template.getMessageConverters().add(new StringHttpMessageConverter()); + + //Parse Raw Files (Form upload) + template.getMessageConverters().add(new AllEncompassingFormHttpMessageConverter()); + template.getMessageConverters().add(converter); + return template; + } +} diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/jobs/AsyncUpdateJobIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/jobs/AsyncUpdateJobIntTest.java index 9579daded..cd4fd6218 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/jobs/AsyncUpdateJobIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/jobs/AsyncUpdateJobIntTest.java @@ -3,37 +3,29 @@ package pro.taskana.jobs; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import java.io.IOException; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.env.Environment; import org.springframework.hateoas.Link; -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.StringHttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import pro.taskana.Classification; +import pro.taskana.RestHelper; import pro.taskana.Task; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.rest.Mapping; import pro.taskana.rest.resource.ClassificationResource; import pro.taskana.rest.resource.ClassificationResourceAssembler; import pro.taskana.rest.resource.TaskResource; @@ -56,36 +48,29 @@ class AsyncUpdateJobIntTest { @Autowired JobScheduler jobScheduler; - @Autowired - Environment env; + @Autowired RestHelper restHelper; - @LocalServerPort - int port; + static RestTemplate template; - private String server; - - private RestTemplate template; - - @BeforeEach - void before() { - template = getRestTemplate(); - server = "http://127.0.0.1:" + port; + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); } @Test void testUpdateClassificationPrioServiceLevel() - throws IOException, InvalidArgumentException { + throws Exception { // 1st step: get old classification : Instant before = Instant.now(); ObjectMapper mapper = new ObjectMapper(); ResponseEntity response = template.exchange( - server + "/api/v1/classifications/{classificationId}", + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID), HttpMethod.GET, - new HttpEntity(getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class), - CLASSIFICATION_ID); + new HttpEntity(restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); assertNotNull(response.getBody()); ClassificationResource classification = response.getBody(); @@ -97,9 +82,9 @@ class AsyncUpdateJobIntTest { classification.setPriority(1000); template.put( - server + "/api/v1/classifications/{classificationId}", - new HttpEntity<>(mapper.writeValueAsString(classification), getHeaders()), - CLASSIFICATION_ID); + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID), + new HttpEntity<>(mapper.writeValueAsString(classification), restHelper.getHeaders()) + ); //trigger jobs twice to refresh all entries. first entry on the first call and follow up on the seconds call jobScheduler.triggerJobs(); @@ -107,11 +92,11 @@ class AsyncUpdateJobIntTest { // verify the classification modified timestamp is after 'before' ResponseEntity repeatedResponse = template.exchange( - server + "/api/v1/classifications/{classificationId}", + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID), HttpMethod.GET, - new HttpEntity(getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class), - CLASSIFICATION_ID); + new HttpEntity(restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); assertNotNull(repeatedResponse.getBody()); @@ -148,17 +133,13 @@ class AsyncUpdateJobIntTest { private void verifyTaskIsModifiedAfter(String taskId, Instant before) throws InvalidArgumentException { - RestTemplate admTemplate = getRestTemplate(); - HttpHeaders admHeaders = new HttpHeaders(); - admHeaders.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin - - HttpEntity admRequest = new HttpEntity<>(admHeaders); + RestTemplate admTemplate = RestHelper.getRestTemplate(); ResponseEntity taskResponse = admTemplate.exchange( - server + "/api/v1/tasks/{taskId}", + restHelper.toUrl(Mapping.URL_TASKS_ID,taskId), HttpMethod.GET, - admRequest, - ParameterizedTypeReference.forType(TaskResource.class), taskId); + new HttpEntity<>(restHelper.getHeadersAdmin()), + ParameterizedTypeReference.forType(TaskResource.class)); TaskResource taskResource = taskResponse.getBody(); Task task = taskResourceAssembler.toModel(taskResource); @@ -166,33 +147,4 @@ class AsyncUpdateJobIntTest { assertFalse("Task " + task.getId() + " has not been refreshed.", before.isAfter(task.getModified())); } - /** - * 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.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.registerModule(new Jackson2HalModule()); - - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); - converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); - converter.setObjectMapper(mapper); - - RestTemplate template = new RestTemplate(); - template.getMessageConverters().clear(); - template.getMessageConverters().add(new StringHttpMessageConverter()); - template.getMessageConverters().add(converter); - return template; - } - - private HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - headers.add("Content-Type", "application/hal+json"); - return headers; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/AccessIdValidationControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/AccessIdValidationControllerIntTest.java index e6410eb72..c777c51ca 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/AccessIdValidationControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/AccessIdValidationControllerIntTest.java @@ -6,27 +6,20 @@ import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; -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.HttpStatus; -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.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.ldap.LdapCacheTestImpl; import pro.taskana.rest.resource.AccessIdResource; @@ -37,18 +30,23 @@ import pro.taskana.rest.resource.AccessIdResource; @TaskanaSpringBootTest class AccessIdValidationControllerIntTest { - @LocalServerPort - int port; + @Autowired RestHelper restHelper; + + static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); + } @Test void testGetMatches() { AccessIdController.setLdapCache(new LdapCacheTestImpl()); - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); + HttpEntity request = new HttpEntity(restHelper.getHeaders()); ResponseEntity> response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/access-ids?search-for=ali", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=ali", + HttpMethod.GET, + request, new ParameterizedTypeReference>() { }); @@ -64,13 +62,12 @@ class AccessIdValidationControllerIntTest { @Test void testBadRequestWhenSearchForIsTooShort() { AccessIdController.setLdapCache(new LdapCacheTestImpl()); - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); + HttpEntity request = new HttpEntity(restHelper.getHeaders()); try { template.exchange( - "http://127.0.0.1:" + port + "/api/v1/access-ids?search-for=al", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=al", + HttpMethod.GET, + request, ParameterizedTypeReference.forType(List.class)); } catch (HttpClientErrorException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); @@ -79,22 +76,4 @@ class AccessIdValidationControllerIntTest { } - /** - * 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.>singletonList(converter)); - return template; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java index bc5ed7812..6224a5175 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java @@ -5,44 +5,27 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.OutputStreamWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.time.Instant; -import java.util.Collections; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.env.Environment; import org.springframework.hateoas.Link; -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.HttpStatus; -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.annotation.DirtiesContext; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -import pro.taskana.Task; +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; -import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.rest.resource.ClassificationResource; import pro.taskana.rest.resource.ClassificationSummaryListResource; import pro.taskana.rest.resource.ClassificationSummaryResource; -import pro.taskana.rest.resource.TaskResource; -import pro.taskana.rest.resource.TaskResourceAssembler; /** * Test ClassificationController. @@ -52,30 +35,19 @@ import pro.taskana.rest.resource.TaskResourceAssembler; @TaskanaSpringBootTest class ClassificationControllerIntTest { - @Autowired - private TaskResourceAssembler taskResourceAssembler; + @Autowired RestHelper restHelper; - @Autowired - Environment env; + static RestTemplate template; - String server = "http://127.0.0.1:"; - RestTemplate template; - HttpEntity request; - HttpHeaders headers = new HttpHeaders(); - @LocalServerPort - int port; - - @BeforeEach - void before() { - template = getRestTemplate(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - request = new HttpEntity(headers); + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); } @Test void testGetAllClassifications() { ResponseEntity response = template.exchange( - server + port + "/api/v1/classifications", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); } @@ -83,8 +55,8 @@ class ClassificationControllerIntTest { @Test void testGetAllClassificationsFilterByCustomAttribute() { ResponseEntity response = template.exchange( - server + port + "/api/v1/classifications?domain=DOMAIN_A&custom-1-like=RVNR", HttpMethod.GET, - request, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_A&custom-1-like=RVNR", HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertEquals(13, response.getBody().getContent().size()); @@ -93,8 +65,8 @@ class ClassificationControllerIntTest { @Test void testGetAllClassificationsKeepingFilters() { ResponseEntity response = template.exchange( - server + port + "/api/v1/classifications?domain=DOMAIN_A&sort-by=key&order=asc", HttpMethod.GET, - request, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_A&sort-by=key&order=asc", HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertTrue(response.getBody() @@ -108,9 +80,9 @@ class ClassificationControllerIntTest { @Test void testGetSecondPageSortedByKey() { ResponseEntity response = template.exchange( - server + port + "/api/v1/classifications?domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5", + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5", HttpMethod.GET, - request, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); assertEquals(5, response.getBody().getContent().size()); assertEquals("L1050", response.getBody().getContent().iterator().next().key); @@ -127,70 +99,61 @@ class ClassificationControllerIntTest { @Test @DirtiesContext - void testCreateClassification() throws IOException { + void testCreateClassification() { String newClassification = "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\",\"name\":\"new classification\",\"type\":\"TASK\"}"; - URL url = new URL(server + port + "/api/v1/classifications"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(201, con.getResponseCode()); - con.disconnect(); + + ResponseEntity responseEntity = template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); newClassification = "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS_2\",\"name\":\"new classification\",\"type\":\"TASK\"}"; - url = new URL(server + port + "/api/v1/classifications"); - con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(201, con.getResponseCode()); - con.disconnect(); + + responseEntity = template.exchange(restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); + + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); } @Test @DirtiesContext - void testCreateClassificationWithParentId() throws IOException { + void testCreateClassificationWithParentId() { String newClassification = "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\",\"key\":\"NEW_CLASS_P1\",\"name\":\"new classification\",\"type\":\"TASK\",\"parentId\":\"CLI:200000000000000000000000000000000015\"}"; - URL url = new URL(server + port + "/api/v1/classifications"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(201, con.getResponseCode()); - con.disconnect(); + + ResponseEntity responseEntity = template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + } @Test @DirtiesContext - void testCreateClassificationWithParentKey() throws IOException { + void testCreateClassificationWithParentKey() { String newClassification = "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\",\"key\":\"NEW_CLASS_P2\",\"name\":\"new classification\",\"type\":\"TASK\",\"parentKey\":\"T2100\"}"; - URL url = new URL(server + port + "/api/v1/classifications"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(201, con.getResponseCode()); - con.disconnect(); + + ResponseEntity responseEntity = template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); } @Test @@ -199,22 +162,19 @@ class ClassificationControllerIntTest { throws IOException { String newClassification = "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS_P2\",\"name\":\"new classification\",\"type\":\"TASK\",\"parentKey\":\"T2100\"}"; - URL url = new URL(server + port + "/api/v1/classifications"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(201, con.getResponseCode()); - con.disconnect(); + ResponseEntity responseEntity = template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + ); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); ResponseEntity response = template.exchange( - server + port + "/api/v1/classifications", HttpMethod.GET, - request, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); boolean foundClassificationCreated = false; @@ -232,112 +192,67 @@ class ClassificationControllerIntTest { @DirtiesContext void testReturn400IfCreateClassificationWithIncompatibleParentIdAndKey() throws IOException { String newClassification = "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\",\"key\":\"NEW_CLASS_P3\",\"name\":\"new classification\",\"type\":\"TASK\",\"parentId\":\"CLI:200000000000000000000000000000000015\",\"parentKey\":\"T2000\"}"; - URL url = new URL(server + port + "/api/v1/classifications"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(400, con.getResponseCode()); - con.disconnect(); + + HttpClientErrorException e = Assertions.assertThrows(HttpClientErrorException.class, () -> template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + )); + + assertNotNull(e); + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); } @Test @DirtiesContext void testCreateClassificationWithClassificationIdReturnsError400() throws IOException { String newClassification = "{\"classificationId\":\"someId\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\",\"name\":\"new classification\",\"type\":\"TASK\"}"; - URL url = new URL("http://127.0.0.1:" + port + "/api/v1/classifications"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setDoOutput(true); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(newClassification); - out.flush(); - out.close(); - assertEquals(400, con.getResponseCode()); - con.disconnect(); + + HttpClientErrorException e = Assertions.assertThrows(HttpClientErrorException.class, () -> template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class) + )); + + assertNotNull(e); + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); } @Test void testGetClassificationWithSpecialCharacter() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); + + HttpEntity request = new HttpEntity(restHelper.getHeadersAdmin()); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/classifications/CLI:100000000000000000000000000000000009", + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"), HttpMethod.GET, request, - ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); + ParameterizedTypeReference.forType(ClassificationSummaryResource.class) + ); assertEquals("Zustimmungserklärung", response.getBody().name); } @Test @DirtiesContext void testDeleteClassification() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); + HttpEntity request = new HttpEntity(restHelper.getHeaders()); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/classifications/CLI:200000000000000000000000000000000004", + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"), HttpMethod.DELETE, request, - ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); + ParameterizedTypeReference.forType(ClassificationSummaryResource.class) + ); assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); assertThrows(HttpClientErrorException.class, () -> { template.exchange( - "http://127.0.0.1:" + port + "/api/v1/classifications/CLI:200000000000000000000000000000000004", + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"), HttpMethod.GET, request, - ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); + ParameterizedTypeReference.forType(ClassificationSummaryResource.class) + ); }); } - - private void verifyTaskIsModifiedAfter(String taskId, Instant before) - throws InvalidArgumentException { - RestTemplate admTemplate = getRestTemplate(); - HttpHeaders admHeaders = new HttpHeaders(); - admHeaders.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin - - HttpEntity admRequest = new HttpEntity(admHeaders); - - ResponseEntity taskResponse = admTemplate.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks/" + taskId, - HttpMethod.GET, - admRequest, - ParameterizedTypeReference.forType(TaskResource.class)); - - TaskResource taskResource = taskResponse.getBody(); - Task task = taskResourceAssembler.toModel(taskResource); - - assertTrue(!before.isAfter(task.getModified())); - } - - /** - * 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.>singletonList(converter)); - return template; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationDefinitionControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationDefinitionControllerIntTest.java index b5f977be3..9e0b863ec 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationDefinitionControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/ClassificationDefinitionControllerIntTest.java @@ -14,35 +14,29 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.env.Environment; import org.springframework.core.io.FileSystemResource; -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.HttpStatus; 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.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.rest.resource.ClassificationResource; import pro.taskana.rest.resource.ClassificationSummaryListResource; @@ -57,35 +51,23 @@ class ClassificationDefinitionControllerIntTest { private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationController.class); - String server = "http://127.0.0.1:"; + private ObjectMapper objMapper = new ObjectMapper(); - RestTemplate template; + @Autowired RestHelper restHelper; - HttpEntity request; + private static RestTemplate template; - HttpHeaders headers = new HttpHeaders(); - - ObjectMapper objMapper = new ObjectMapper(); - - @LocalServerPort - int port; - - @Autowired - Environment env; - - @BeforeEach - void before() { - LOGGER.debug("before"); - template = getRestTemplate(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - request = new HttpEntity(headers); + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); } @Test void testExportClassifications() { ResponseEntity response = template.exchange( - server + port + "/api/v1/classification-definitions?domain=DOMAIN_B", - HttpMethod.GET, request, ParameterizedTypeReference.forType(ClassificationResource[].class)); + restHelper.toUrl(Mapping.URL_CLASSIFICATIONDEFINITION) + "?domain=DOMAIN_B", + HttpMethod.GET, restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationResource[].class)); assertEquals(HttpStatus.OK, response.getStatusCode()); assertTrue(response.getBody().length >= 5); assertTrue(response.getBody().length <= 7); @@ -95,8 +77,9 @@ class ClassificationDefinitionControllerIntTest { @Test void testExportClassificationsFromWrongDomain() { ResponseEntity response = template.exchange( - server + port + "/api/v1/classification-definitions?domain=ADdfe", - HttpMethod.GET, request, ParameterizedTypeReference.forType(ClassificationResource[].class)); + restHelper.toUrl(Mapping.URL_CLASSIFICATIONDEFINITION) + "?domain=ADdfe", + HttpMethod.GET, restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationResource[].class)); assertEquals(0, response.getBody().length); } @@ -403,12 +386,9 @@ class ClassificationDefinitionControllerIntTest { private ClassificationSummaryResource getClassificationWithKeyAndDomain(String key, String domain) { LOGGER.debug("Request classification with key={} in domain={}", key, domain); - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); + HttpEntity request = new HttpEntity(restHelper.getHeaders()); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/classifications?key=" + key + "&domain=" + domain, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?key=" + key + "&domain=" + domain, HttpMethod.GET, request, ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); @@ -423,31 +403,15 @@ class ClassificationDefinitionControllerIntTest { writer.close(); MultiValueMap body = new LinkedMultiValueMap<>(); + + HttpHeaders headers = restHelper.getHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); body.add("file", new FileSystemResource(tmpFile)); HttpEntity> requestEntity = new HttpEntity<>(body, headers); - String serverUrl = server + port + "/api/v1/classification-definitions"; - RestTemplate restTemplate = new RestTemplate(); + String serverUrl = restHelper.toUrl(Mapping.URL_CLASSIFICATIONDEFINITION); - return restTemplate.postForEntity(serverUrl, requestEntity, Void.class); + return template.postForEntity(serverUrl, requestEntity, Void.class); } - /** - * 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/haljson,*/*")); - converter.setObjectMapper(mapper); - - RestTemplate template = new RestTemplate(Collections.>singletonList(converter)); - return template; - } } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/GenenalExceptionHandlingTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/GenenalExceptionHandlingTest.java index f4b3910cf..bfd537774 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/GenenalExceptionHandlingTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/GenenalExceptionHandlingTest.java @@ -3,34 +3,26 @@ 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.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.slf4j.LoggerFactory; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; -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.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.LoggingEvent; import ch.qos.logback.core.Appender; +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.ldap.LdapCacheTestImpl; import pro.taskana.rest.resource.ClassificationSummaryListResource; @@ -42,23 +34,24 @@ import pro.taskana.rest.resource.ClassificationSummaryListResource; @TaskanaSpringBootTest class GenenalExceptionHandlingTest { - String server = "http://127.0.0.1:"; - RestTemplate template; - HttpEntity request; - HttpHeaders headers = new HttpHeaders(); - @LocalServerPort - int port; @Mock private Appender mockAppender; @Captor private ArgumentCaptor captorLoggingEvent; + @Autowired RestHelper restHelper; + + private static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); + } + @BeforeEach void before() { - template = getRestTemplate(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - request = new HttpEntity(headers); + final Logger logger = (Logger) LoggerFactory.getLogger(TaskanaRestExceptionHandler.class); logger.addAppender(mockAppender); } @@ -77,7 +70,7 @@ class GenenalExceptionHandlingTest { AccessIdController.setLdapCache(new LdapCacheTestImpl()); template.exchange( - server + port + "/api/v1/access-ids?search-for=al", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=al", HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(List.class)); } catch (Exception ex) { verify(mockAppender).doAppend(captorLoggingEvent.capture()); @@ -90,8 +83,10 @@ class GenenalExceptionHandlingTest { void testDeleteNonExisitingClassificationExceptionIsLogged() { try { template.exchange( - server + port + "/api/v1/classifications/non-existing-id", HttpMethod.DELETE, request, - ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, "non-existing-id"), HttpMethod.DELETE, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationSummaryListResource.class) + ); } catch (Exception ex) { verify(mockAppender).doAppend(captorLoggingEvent.capture()); assertTrue(captorLoggingEvent.getValue() @@ -100,22 +95,4 @@ class GenenalExceptionHandlingTest { } } - - /** - * 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.>singletonList(converter)); - return template; - } } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/MappingTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/MappingTest.java new file mode 100644 index 000000000..d2cf29139 --- /dev/null +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/MappingTest.java @@ -0,0 +1,35 @@ +package pro.taskana.rest; + +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; + +import pro.taskana.TaskanaSpringBootTest; + +/** + * Test Mapping and Linkbuilder. + */ +class MappingTest { + + @Test + void testMapping() throws Exception { + + String mapUrl = Mapping.URL_TASKS; + String buildUrl = linkTo(methodOn(TaskController.class).getTasks(new LinkedMultiValueMap<>())).toString(); + Assertions.assertEquals(mapUrl, buildUrl); + } + + @Test + void testMappingWithVariable() throws Exception { + + String id = "25"; + + String mapUrl = UriComponentsBuilder.fromPath(Mapping.URL_TASKS_ID).buildAndExpand(id).toUriString(); + String buildUrl = linkTo(methodOn(TaskController.class).getTask(id)).toString(); + Assertions.assertEquals(mapUrl, buildUrl); + } +} diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskControllerIntTest.java index 38b898168..3c44990d2 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskControllerIntTest.java @@ -15,25 +15,22 @@ import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.sql.SQLException; -import java.util.Collections; +import java.time.Instant; import javax.sql.DataSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; import org.springframework.hateoas.Link; -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.HttpStatus; -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.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; @@ -41,10 +38,14 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import pro.taskana.ObjectReference; +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.exceptions.SystemException; +import pro.taskana.rest.resource.ClassificationSummaryResource; import pro.taskana.rest.resource.TaskResource; import pro.taskana.rest.resource.TaskSummaryListResource; +import pro.taskana.rest.resource.WorkbasketSummaryResource; import pro.taskana.sampledata.SampleDataGenerator; /** @@ -57,8 +58,14 @@ class TaskControllerIntTest { @Value("${taskana.schemaName:TASKANA}") public String schemaName; - @LocalServerPort - int port; + @Autowired RestHelper restHelper; + + private static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); + } @Autowired private DataSource dataSource; @@ -75,12 +82,8 @@ class TaskControllerIntTest { @Test void testGetAllTasks() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_TASKS), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertEquals(25, response.getBody().getContent().size()); @@ -88,13 +91,9 @@ class TaskControllerIntTest { @Test void testGetAllTasksByWorkbasketId() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); // teamlead_1 - HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?workbasket-id=WBI:100000000000000000000000000000000001", - HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-id=WBI:100000000000000000000000000000000001", + HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertEquals(22, response.getBody().getContent().size()); @@ -102,12 +101,11 @@ class TaskControllerIntTest { @Test void testGetAllTasksByWorkbasketKeyAndDomain() { - RestTemplate template = getRestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI="); // user_1_2 HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?workbasket-key=USER_1_2&domain=DOMAIN_A", + restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2&domain=DOMAIN_A", HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); @@ -116,13 +114,13 @@ class TaskControllerIntTest { @Test void testExceptionIfKeyIsSetButDomainIsMissing() { - RestTemplate template = getRestTemplate(); + HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI="); // user_1_2 HttpEntity request = new HttpEntity(headers); try { ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?workbasket-key=USER_1_2", + restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2", HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskSummaryListResource.class)); fail(); @@ -133,12 +131,8 @@ class TaskControllerIntTest { @Test void testGetAllTasksWithAdminRole() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // Role Admin - HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_TASKS), HttpMethod.GET, new HttpEntity<>(restHelper.getHeadersAdmin()), ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertEquals(73, response.getBody().getContent().size()); @@ -146,13 +140,9 @@ class TaskControllerIntTest { @Test void testGetAllTasksKeepingFilters() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?por.type=VNR&por.value=22334455&sort-by=por.value&order=desc", - HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_TASKS) + "?por.type=VNR&por.value=22334455&sort-by=por.value&order=desc", + HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertTrue(response.getBody() @@ -163,14 +153,10 @@ class TaskControllerIntTest { @Test void testThrowsExceptionIfInvalidFilterIsUsed() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); try { template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?invalid=VNR", - HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_TASKS) + "?invalid=VNR", + HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(TaskSummaryListResource.class)); fail(); } catch (HttpClientErrorException e) { @@ -181,13 +167,11 @@ class TaskControllerIntTest { @Test void testGetLastPageSortedByPorValue() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // Role Admin - HttpEntity request = new HttpEntity(headers); + + HttpEntity request = new HttpEntity(restHelper.getHeadersAdmin()); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port - + "/api/v1/tasks?state=READY,CLAIMED&sort-by=por.value&order=desc&page=15&page-size=5", + restHelper.toUrl(Mapping.URL_TASKS) + + "?state=READY,CLAIMED&sort-by=por.value&order=desc&page=15&page-size=5", HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskSummaryListResource.class)); @@ -209,19 +193,19 @@ class TaskControllerIntTest { void testGetLastPageSortedByDueWithHiddenTasksRemovedFromResult() { resetDb(); // required because ClassificationControllerIntTest.testGetQueryByPorSecondPageSortedByType changes // tasks and this test depends on the tasks as they are in sampledata - RestTemplate template = getRestTemplate(); + HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?sort-by=due&order=desc", HttpMethod.GET, + restHelper.toUrl(Mapping.URL_TASKS) + "?sort-by=due&order=desc", HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertEquals(25, response.getBody().getContent().size()); response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/tasks?sort-by=due&order=desc&page=5&page-size=5", HttpMethod.GET, + restHelper.toUrl(Mapping.URL_TASKS) + "?sort-by=due&order=desc&page=5&page-size=5", HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskSummaryListResource.class)); assertEquals(5, response.getBody().getContent().size()); @@ -242,13 +226,13 @@ class TaskControllerIntTest { void testGetQueryByPorSecondPageSortedByType() { resetDb(); // required because ClassificationControllerIntTest.testGetQueryByPorSecondPageSortedByType changes // tasks and this test depends on the tasks as they are in sampledata - RestTemplate template = getRestTemplate(); + HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port - + "/api/v1/tasks?por.company=00&por.system=PASystem&por.instance=00&por.type=VNR&por.value=22334455&sort-by=por.type&order=asc&page=2&page-size=5", + restHelper.toUrl(Mapping.URL_TASKS) + + "?por.company=00&por.system=PASystem&por.instance=00&por.type=VNR&por.value=22334455&sort-by=por.type&order=asc&page=2&page-size=5", HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskSummaryListResource.class)); @@ -268,7 +252,7 @@ class TaskControllerIntTest { @Test void testGetTaskWithAttachments() throws IOException { - URL url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks/TKI:000000000000000000000000000000000002"); + URL url = new URL(restHelper.toUrl("/api/v1/tasks/TKI:000000000000000000000000000000000002")); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("Authorization", "Basic YWRtaW46YWRtaW4="); @@ -294,7 +278,7 @@ class TaskControllerIntTest { @Test void testGetAndUpdateTask() throws IOException { - URL url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks/TKI:100000000000000000000000000000000000"); + URL url = new URL(restHelper.toUrl("/api/v1/tasks/TKI:100000000000000000000000000000000000")); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); @@ -323,7 +307,7 @@ class TaskControllerIntTest { assertEquals(200, con.getResponseCode()); con.disconnect(); - url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks/TKI:100000000000000000000000000000000000"); + url = new URL(restHelper.toUrl("/api/v1/tasks/TKI:100000000000000000000000000000000000")); con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); @@ -350,47 +334,66 @@ class TaskControllerIntTest { } @Test - void testCreateAndDeleteTask() throws IOException { - String taskToCreateJson = "{\"classificationSummaryResource\":{\"key\":\"L11010\"}," - + "\"workbasketSummaryResource\":{\"workbasketId\":\"WBI:100000000000000000000000000000000004\"}," - + "\"primaryObjRef\":{\"company\":\"MyCompany1\",\"system\":\"MySystem1\",\"systemInstance\":\"MyInstance1\",\"type\":\"MyType1\",\"value\":\"00000001\"}}"; + void testCreateAndDeleteTask() { - URL url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setDoOutput(true); - con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - con.setRequestProperty("Content-Type", "application/json"); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); - out.write(taskToCreateJson); - out.flush(); - out.close(); - assertEquals(201, con.getResponseCode()); - // con.disconnect(); - - BufferedReader in = new BufferedReader( - new InputStreamReader(con.getInputStream())); - StringBuffer responsePayload = new StringBuffer(); - String inputLine; - while ((inputLine = in.readLine()) != null) { - responsePayload.append(inputLine); - } - in.close(); - con.disconnect(); - String createdTask = responsePayload.toString(); - String taskIdOfCreatedTask = createdTask.substring(createdTask.indexOf("TKI:"), - createdTask.indexOf("TKI:") + 40); + TaskResource taskResource = getTaskResourceSample(); + ResponseEntity responseCreate = template.exchange(restHelper.toUrl(Mapping.URL_TASKS), + HttpMethod.POST, + new HttpEntity<>(taskResource, restHelper.getHeaders()), + ParameterizedTypeReference.forType(TaskResource.class)); + assertEquals(responseCreate.getStatusCode(), HttpStatus.CREATED); + assertNotNull(responseCreate.getBody()); + String taskIdOfCreatedTask = responseCreate.getBody().getTaskId(); assertNotNull(taskIdOfCreatedTask); assertTrue(taskIdOfCreatedTask.startsWith("TKI:")); - // delete task again to clean test data - url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks/" + taskIdOfCreatedTask); - con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("DELETE"); - con.setRequestProperty("Authorization", "Basic YWRtaW46YWRtaW4="); // admin - assertEquals(204, con.getResponseCode()); - con.disconnect(); + ResponseEntity responseDeleted = template.exchange( + restHelper.toUrl(Mapping.URL_TASKS_ID, taskIdOfCreatedTask), + HttpMethod.DELETE, + new HttpEntity<>(restHelper.getHeadersAdmin()), + ParameterizedTypeReference.forType(Void.class) + ); + + assertEquals(HttpStatus.NO_CONTENT, responseDeleted.getStatusCode()); + } + + /** + * TSK-926: If Planned and Due Date is provided to create a task throw an exception + * One is calculated by other other date + service level. + */ + @Test + void testCreateWithPlannedAndDueDate() { + TaskResource taskResource = getTaskResourceSample(); + Instant now = Instant.now(); + taskResource.setPlanned(now.toString()); + taskResource.setDue(now.toString()); + + HttpClientErrorException ex = Assertions.assertThrows(HttpClientErrorException.class, + () -> template.exchange(restHelper.toUrl(Mapping.URL_TASKS), HttpMethod.POST, + new HttpEntity<>(taskResource, restHelper.getHeaders()), + ParameterizedTypeReference.forType(TaskResource.class))); + + } + + private TaskResource getTaskResourceSample() { + ClassificationSummaryResource classificationResource = new ClassificationSummaryResource(); + classificationResource.key = "L11010"; + WorkbasketSummaryResource workbasketSummaryResource = new WorkbasketSummaryResource(); + workbasketSummaryResource.setWorkbasketId("WBI:100000000000000000000000000000000004"); + + ObjectReference objectReference = new ObjectReference(); + objectReference.setCompany("MyCompany1"); + objectReference.setSystem("MySystem1"); + objectReference.setSystemInstance("MyInstance1"); + objectReference.setType("MyType1"); + objectReference.setValue("00000001"); + + TaskResource taskResource = new TaskResource(); + taskResource.setClassificationSummaryResource(classificationResource); + taskResource.setWorkbasketSummaryResource(workbasketSummaryResource); + taskResource.setPrimaryObjRef(objectReference); + return taskResource; } @Test @@ -399,7 +402,7 @@ class TaskControllerIntTest { + "\"workbasketSummaryResource\":{\"workbasketId\":\"WBI:100000000000000000000000000000000004\"}," + "\"primaryObjRef\":{\"company\":\"MyCompany1\",\"system\":\"MySystem1\",\"systemInstance\":\"MyInstance1\",\"type\":\"MyType1\",\"value\":\"00000001\"}}"; - URL url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks"); + URL url = new URL(restHelper.toUrl("/api/v1/tasks")); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setDoOutput(true); @@ -417,7 +420,7 @@ class TaskControllerIntTest { + "\"workbasketSummaryResource\":{\"workbasketId\":\"\"}," + "\"primaryObjRef\":{\"company\":\"MyCompany1\",\"system\":\"MySystem1\",\"systemInstance\":\"MyInstance1\",\"type\":\"MyType1\",\"value\":\"00000001\"}}"; - url = new URL("http://127.0.0.1:" + port + "/api/v1/tasks"); + url = new URL(restHelper.toUrl("/api/v1/tasks")); con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setDoOutput(true); @@ -432,23 +435,4 @@ class TaskControllerIntTest { } - /** - * 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.setSupportedMediaTypes(ImmutableList.of(MediaTypes.HAL_JSON)); - converter.setObjectMapper(mapper); - - RestTemplate template = new RestTemplate(Collections.>singletonList(converter)); - return template; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskanaEngineControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskanaEngineControllerIntTest.java index 7141f043b..ca8b34ffc 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskanaEngineControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TaskanaEngineControllerIntTest.java @@ -4,25 +4,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; -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.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - +import pro.taskana.RestHelper; import pro.taskana.TaskanaRole; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.rest.resource.TaskanaUserInfoResource; @@ -32,31 +26,29 @@ import pro.taskana.rest.resource.TaskanaUserInfoResource; */ @TaskanaSpringBootTest -public class TaskanaEngineControllerIntTest { +class TaskanaEngineControllerIntTest { - @LocalServerPort - int port; + @Autowired RestHelper restHelper; + + private static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); + } @Test void testDomains() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); ResponseEntity> response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/domains", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_DOMAIN), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(List.class)); assertTrue(response.getBody().contains("DOMAIN_A")); } @Test void testClassificationTypes() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); ResponseEntity> response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/classification-types", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONTYPES), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(List.class)); assertTrue(response.getBody().contains("TASK")); assertTrue(response.getBody().contains("DOCUMENT")); @@ -65,12 +57,11 @@ public class TaskanaEngineControllerIntTest { @Test void testClassificationCategories() { - RestTemplate template = getRestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); HttpEntity request = new HttpEntity(headers); ResponseEntity> response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/classification-categories/?type=TASK", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_CLASSIFICATIONCATEGORIES), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(List.class)); assertTrue(response.getBody().contains("MANUAL")); assertTrue(response.getBody().contains("EXTERNAL")); @@ -81,35 +72,12 @@ public class TaskanaEngineControllerIntTest { @Test void testGetCurrentUserInfo() { - RestTemplate template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - HttpEntity request = new HttpEntity(headers); ResponseEntity response = template.exchange( - "http://127.0.0.1:" + port + "/api/v1/current-user-info", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_CURRENTUSER), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(TaskanaUserInfoResource.class)); assertEquals("teamlead_1", response.getBody().getUserId()); assertTrue(response.getBody().getGroupIds().contains("businessadmin")); assertTrue(response.getBody().getRoles().contains(TaskanaRole.BUSINESS_ADMIN)); assertFalse(response.getBody().getRoles().contains(TaskanaRole.ADMIN)); } - - /** - * 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, application/json")); - converter.setObjectMapper(mapper); - - RestTemplate template = new RestTemplate(Collections.>singletonList(converter)); - return template; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TestSchemaNameCustomizable.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TestSchemaNameCustomizable.java index 047edc415..24da65f7c 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TestSchemaNameCustomizable.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/TestSchemaNameCustomizable.java @@ -3,21 +3,12 @@ package pro.taskana.rest; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.Collections; import javax.sql.DataSource; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.hateoas.hal.Jackson2HalModule; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.web.client.RestTemplate; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.configuration.SpringTaskanaEngineConfiguration; @@ -78,24 +69,4 @@ class TestSchemaNameCustomizable { e.printStackTrace(); } } - - /** - * 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.setSupportedMediaTypes(ImmutableList.of(MediaTypes.HAL_JSON)); - converter.setObjectMapper(mapper); - - RestTemplate template = new RestTemplate(Collections.>singletonList(converter)); - return template; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketAccessItemControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketAccessItemControllerIntTest.java index 2a0f4aae6..c69bf63e6 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketAccessItemControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketAccessItemControllerIntTest.java @@ -6,30 +6,20 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.Collections; - -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.hateoas.Link; -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.HttpStatus; -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.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.rest.resource.WorkbasketAccessItemListResource; import pro.taskana.rest.resource.WorkbasketAccessItemPaginatedListResource; @@ -41,33 +31,29 @@ import pro.taskana.rest.resource.WorkbasketAccessItemPaginatedListResource; @TaskanaSpringBootTest class WorkbasketAccessItemControllerIntTest { - String url = "http://127.0.0.1:"; - RestTemplate template; - HttpEntity request; - @LocalServerPort - int port; + @Autowired RestHelper restHelper; - @BeforeEach - void before() { - template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - request = new HttpEntity(headers); + private static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); } @Test void testGetAllWorkbasketAccessItems() { ResponseEntity response = template.exchange( - url + port + "/api/v1/workbasket-access-items", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKETACCESSITEMS), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketAccessItemListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); } @Test void testGetWorkbasketAccessItemsKeepingFilters() { - String parameters = "/api/v1/workbasket-access-items?sort-by=workbasket-key&order=asc&page=1&page-size=9&access-ids=user_1_1"; + String parameters = "?sort-by=workbasket-key&order=asc&page=1&page-size=9&access-ids=user_1_1"; ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKETACCESSITEMS) + parameters, HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketAccessItemListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertTrue(response.getBody() @@ -80,9 +66,9 @@ class WorkbasketAccessItemControllerIntTest { void testThrowsExceptionIfInvalidFilterIsUsed() { try { template.exchange( - url + port - + "/api/v1/workbasket-access-items/?sort-by=workbasket-key&order=asc&page=1&page-size=9&invalid=user_1_1", - HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKETACCESSITEMS) + + "?sort-by=workbasket-key&order=asc&page=1&page-size=9&invalid=user_1_1", HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketAccessItemListResource.class)); fail(); } catch (HttpClientErrorException e) { @@ -93,9 +79,10 @@ class WorkbasketAccessItemControllerIntTest { @Test void testGetSecondPageSortedByWorkbasketKey() { - String parameters = "/api/v1/workbasket-access-items?sort-by=workbasket-key&order=asc&page=2&page-size=9&access-ids=user_1_1"; + String parameters = "?sort-by=workbasket-key&order=asc&page=2&page-size=9&access-ids=user_1_1"; ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKETACCESSITEMS) + parameters, HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketAccessItemPaginatedListResource.class)); assertEquals(1, response.getBody().getContent().size()); assertEquals("user_1_1", response.getBody().getContent().iterator().next().accessId); @@ -115,9 +102,10 @@ class WorkbasketAccessItemControllerIntTest { @Test void testRemoveWorkbasketAccessItemsOfUser() { - String parameters = "/api/v1/workbasket-access-items/?access-id=user_1_1"; + String parameters = "?access-id=user_1_1"; ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.DELETE, request, + restHelper.toUrl(Mapping.URL_WORKBASKETACCESSITEMS) + parameters, HttpMethod.DELETE, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(Void.class)); assertNull(response.getBody()); assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); @@ -125,31 +113,14 @@ class WorkbasketAccessItemControllerIntTest { @Test void testGetBadRequestIfTryingToDeleteAccessItemsForGroup() { - String parameters = "/api/v1/workbasket-access-items?access-id=cn=DevelopersGroup,ou=groups,o=TaskanaTest"; + String parameters = "?access-id=cn=DevelopersGroup,ou=groups,o=TaskanaTest"; try { ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.DELETE, request, + restHelper.toUrl(Mapping.URL_WORKBASKETACCESSITEMS) + parameters, HttpMethod.DELETE, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(Void.class)); } catch (HttpClientErrorException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); } } - - /** - * 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.>singletonList(converter)); - return template; - } } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketControllerIntTest.java index fe7dc98bd..bddf988fd 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketControllerIntTest.java @@ -6,29 +6,20 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.Collections; import java.util.Iterator; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.hateoas.Link; -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.HttpStatus; -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.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.rest.resource.DistributionTargetListResource; import pro.taskana.rest.resource.DistributionTargetResource; @@ -41,24 +32,19 @@ import pro.taskana.rest.resource.WorkbasketSummaryListResource; @TaskanaSpringBootTest class WorkbasketControllerIntTest { - String url = "http://127.0.0.1:"; - RestTemplate template; - HttpEntity request; - @LocalServerPort - int port; + @Autowired RestHelper restHelper; - @BeforeEach - void before() { - template = getRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - request = new HttpEntity(headers); + private static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); } @Test void testGetAllWorkbaskets() { ResponseEntity response = template.exchange( - url + port + "/api/v1/workbaskets", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKET), HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); } @@ -66,7 +52,8 @@ class WorkbasketControllerIntTest { @Test void testGetAllWorkbasketsBusinessAdminHasOpenPermission() { ResponseEntity response = template.exchange( - url + port + "/api/v1/workbaskets?required-permission=OPEN", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKET) + "?required-permission=OPEN", HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertEquals(3, response.getBody().getContent().size()); @@ -74,9 +61,9 @@ class WorkbasketControllerIntTest { @Test void testGetAllWorkbasketsKeepingFilters() { - String parameters = "/api/v1/workbaskets?type=PERSONAL&sort-by=key&order=desc"; + String parameters = "?type=PERSONAL&sort-by=key&order=desc"; ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKET) + parameters, HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketSummaryListResource.class)); assertNotNull(response.getBody().getLink(Link.REL_SELF)); assertTrue(response.getBody() @@ -89,7 +76,8 @@ class WorkbasketControllerIntTest { void testThrowsExceptionIfInvalidFilterIsUsed() { try { template.exchange( - url + port + "/api/v1/workbaskets?invalid=PERSONAL", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKET) + "?invalid=PERSONAL", HttpMethod.GET, + restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketSummaryListResource.class)); fail(); } catch (HttpClientErrorException e) { @@ -101,9 +89,9 @@ class WorkbasketControllerIntTest { @Test void testGetSecondPageSortedByKey() { - String parameters = "/api/v1/workbaskets?sort-by=key&order=desc&page=2&page-size=5"; + String parameters = "?sort-by=key&order=desc&page=2&page-size=5"; ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKET) + parameters, HttpMethod.GET, restHelper.defaultRequest(), ParameterizedTypeReference.forType(WorkbasketSummaryListResource.class)); assertEquals(5, response.getBody().getContent().size()); assertEquals("USER_1_1", response.getBody().getContent().iterator().next().getKey()); @@ -120,39 +108,22 @@ class WorkbasketControllerIntTest { @Test void testRemoveWorkbasketAsDistributionTarget() { - String parameters = "/api/v1/workbaskets/distribution-targets/WBI:100000000000000000000000000000000007"; ResponseEntity response = template.exchange( - url + port + parameters, HttpMethod.DELETE, request, - Void.class); + restHelper.toUrl(Mapping.URL_WORKBASKET_DISTRIBUTION_ID, "WBI:100000000000000000000000000000000007"), + HttpMethod.DELETE, restHelper.defaultRequest(), + Void.class + ); assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); ResponseEntity response2 = template.exchange( - url + port + "/api/v1/workbaskets/WBI:100000000000000000000000000000000002/distribution-targets", - HttpMethod.GET, request, - ParameterizedTypeReference.forType(DistributionTargetListResource.class)); + restHelper.toUrl(Mapping.URL_WORKBASKET_ID_DISTRIBUTION, "WBI:100000000000000000000000000000000002"), + HttpMethod.GET, restHelper.defaultRequest(), + ParameterizedTypeReference.forType(DistributionTargetListResource.class) + ); assertEquals(HttpStatus.OK, response2.getStatusCode()); Iterator iterator = response2.getBody().getContent().iterator(); while (iterator.hasNext()) { assertNotEquals("WBI:100000000000000000000000000000000007", iterator.next().getWorkbasketId()); } } - - /** - * 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.>singletonList(converter)); - return template; - } - } diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java index 148e7a157..971403a27 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java @@ -11,33 +11,30 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.FileSystemResource; -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.HttpStatus; 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.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; import pro.taskana.rest.resource.WorkbasketDefinitionResource; @@ -49,26 +46,27 @@ import pro.taskana.rest.resource.WorkbasketDefinitionResource; class WorkbasketDefinitionControllerIntTest { private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationController.class); - private String server = "http://127.0.0.1:"; - private RestTemplate template; - private HttpEntity request; - private HttpHeaders headers = new HttpHeaders(); private ObjectMapper objMapper = new ObjectMapper(); - @LocalServerPort - private int port; + + @Autowired RestHelper restHelper; + + private static RestTemplate template; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); + } @BeforeEach void before() { LOGGER.debug("before"); - template = getRestTemplate(); - headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"); - request = new HttpEntity(headers); } @Test void testExportWorkbasketFromDomain() { ResponseEntity> response = template.exchange( - server + port + "/api/v1/workbasket-definitions?domain=DOMAIN_A", HttpMethod.GET, request, + restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=DOMAIN_A", HttpMethod.GET, + restHelper.defaultRequest(), new ParameterizedTypeReference>() { }); @@ -95,16 +93,19 @@ class WorkbasketDefinitionControllerIntTest { @Test void testExportWorkbasketsFromWrongDomain() { ResponseEntity> response = template.exchange( - server + port + "/api/v1/workbasket-definitions?domain=wrongDomain", - HttpMethod.GET, request, ParameterizedTypeReference.forType(List.class)); + restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=wrongDomain", HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(List.class)); assertEquals(0, response.getBody().size()); } @Test void testImportWorkbasket() throws IOException { ResponseEntity> response = template.exchange( - server + port + "/api/v1/workbasket-definitions?domain=DOMAIN_A", - HttpMethod.GET, request, ParameterizedTypeReference.forType(List.class)); + + restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=DOMAIN_A", HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(List.class)); List list = new ArrayList<>(); list.add(objMapper.writeValueAsString(response.getBody().get(0))); @@ -115,8 +116,9 @@ class WorkbasketDefinitionControllerIntTest { @Test void testFailOnImportDuplicates() throws IOException { ResponseEntity> response = template.exchange( - server + port + "/api/v1/workbasket-definitions?domain=DOMAIN_A", - HttpMethod.GET, request, new ParameterizedTypeReference>() { + restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=DOMAIN_A", HttpMethod.GET, + restHelper.defaultRequest(), + new ParameterizedTypeReference>() { }); @@ -135,8 +137,10 @@ class WorkbasketDefinitionControllerIntTest { void testNoErrorWhenImportWithSameIdButDifferentKeyAndDomain() throws IOException { ResponseEntity> response = template.exchange( - server + port + "/api/v1/workbasket-definitions?domain=DOMAIN_A", - HttpMethod.GET, request, new ParameterizedTypeReference>() { + + restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=DOMAIN_A", HttpMethod.GET, + restHelper.defaultRequest(), + new ParameterizedTypeReference>() { }); @@ -156,30 +160,13 @@ class WorkbasketDefinitionControllerIntTest { writer.close(); MultiValueMap body = new LinkedMultiValueMap<>(); + HttpHeaders headers = restHelper.getHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); body.add("file", new FileSystemResource(tmpFile)); HttpEntity> requestEntity = new HttpEntity<>(body, headers); - String serverUrl = server + port + "/api/v1/workbasket-definitions"; - RestTemplate restTemplate = new RestTemplate(); + String serverUrl = restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS); - return restTemplate.postForEntity(serverUrl, requestEntity, Void.class); - } - - /** - * 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/haljson,*/*")); - converter.setObjectMapper(mapper); - - return new RestTemplate(Collections.>singletonList(converter)); + return template.postForEntity(serverUrl, requestEntity, Void.class); } } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AccessIdController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AccessIdController.java index ef2e91aa7..23bf747f3 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AccessIdController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AccessIdController.java @@ -9,7 +9,6 @@ import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -25,7 +24,6 @@ import pro.taskana.rest.resource.AccessIdResource; */ @RestController @EnableHypermediaSupport(type = HypermediaType.HAL) -@RequestMapping(path = "/api/v1/access-ids", produces = "application/hal+json") public class AccessIdController { private static final Logger LOGGER = LoggerFactory.getLogger(AccessIdController.class); @@ -35,7 +33,7 @@ public class AccessIdController { private static LdapCache ldapCache; - @GetMapping + @GetMapping(path = Mapping.URL_ACCESSID) public ResponseEntity> validateAccessIds( @RequestParam("search-for") String searchFor) throws InvalidArgumentException { LOGGER.debug("Entry to validateAccessIds(search-for= {})", searchFor); @@ -68,7 +66,7 @@ public class AccessIdController { } } - @GetMapping(path = "/groups") + @GetMapping(path = Mapping.URL_ACCESSID_GROUPS) public ResponseEntity> getGroupsByAccessId( @RequestParam("access-id") String accessId) throws InvalidArgumentException { LOGGER.debug("Entry to getGroupsByAccessId(access-id= {})", accessId); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationController.java index b7dacc8eb..1202fc3f5 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationController.java @@ -16,7 +16,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -43,7 +42,6 @@ import pro.taskana.rest.resource.PagedResources.PageMetadata; */ @RestController @EnableHypermediaSupport(type = HypermediaType.HAL) -@RequestMapping(path = "/api/v1/classifications", produces = "application/hal+json") public class ClassificationController extends AbstractPagingController { private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationController.class); @@ -97,7 +95,7 @@ public class ClassificationController extends AbstractPagingController { this.classificationSummaryResourceAssembler = classificationSummaryResourceAssembler; } - @GetMapping + @GetMapping(path = Mapping.URL_CLASSIFICATIONS) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getClassifications( @RequestParam MultiValueMap params) throws InvalidArgumentException { @@ -123,7 +121,7 @@ public class ClassificationController extends AbstractPagingController { return response; } - @GetMapping(path = "/{classificationId}") + @GetMapping(path = Mapping.URL_CLASSIFICATIONS_ID) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getClassification(@PathVariable String classificationId) throws ClassificationNotFoundException { @@ -141,7 +139,7 @@ public class ClassificationController extends AbstractPagingController { return response; } - @PostMapping + @PostMapping(path = Mapping.URL_CLASSIFICATIONS) @Transactional(rollbackFor = Exception.class) public ResponseEntity createClassification( @RequestBody ClassificationResource resource) @@ -162,7 +160,7 @@ public class ClassificationController extends AbstractPagingController { return response; } - @PutMapping(path = "/{classificationId}") + @PutMapping(path = Mapping.URL_CLASSIFICATIONS_ID) @Transactional(rollbackFor = Exception.class) public ResponseEntity updateClassification( @PathVariable(value = "classificationId") String classificationId, @RequestBody ClassificationResource resource) @@ -191,7 +189,7 @@ public class ClassificationController extends AbstractPagingController { return result; } - @DeleteMapping(path = "/{classificationId}") + @DeleteMapping(path = Mapping.URL_CLASSIFICATIONS_ID) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity deleteClassification(@PathVariable String classificationId) throws ClassificationNotFoundException, ClassificationInUseException, NotAuthorizedException { diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationDefinitionController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationDefinitionController.java index 4df4f5197..97fb8036c 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationDefinitionController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/ClassificationDefinitionController.java @@ -12,12 +12,11 @@ import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; -import org.springframework.http.MediaType; +import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -44,7 +43,7 @@ import pro.taskana.rest.resource.ClassificationResourceAssembler; * Controller for Importing / Exporting classifications. */ @RestController -@RequestMapping(path = "/api/v1/classification-definitions", produces = {MediaType.APPLICATION_JSON_VALUE}) +@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) public class ClassificationDefinitionController { private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationDefinitionController.class); @@ -60,7 +59,7 @@ public class ClassificationDefinitionController { this.classificationResourceAssembler = classificationResourceAssembler; } - @GetMapping + @GetMapping(path = Mapping.URL_CLASSIFICATIONDEFINITION) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity> exportClassifications( @RequestParam(required = false) String domain) @@ -86,7 +85,7 @@ public class ClassificationDefinitionController { return response; } - @PostMapping + @PostMapping(path = Mapping.URL_CLASSIFICATIONDEFINITION) @Transactional(rollbackFor = Exception.class) public ResponseEntity importClassifications( @RequestParam("file") MultipartFile file) diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/Mapping.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/Mapping.java new file mode 100644 index 000000000..05dbfb207 --- /dev/null +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/Mapping.java @@ -0,0 +1,53 @@ +package pro.taskana.rest; + +/** + * Collection of Url to Controller mappings. + */ +public final class Mapping { + + private static final String PRE = "/api/v1/"; + + public static final String URL_ACCESSID = PRE + "access-ids"; + public static final String URL_ACCESSID_GROUPS = URL_ACCESSID + "/groups"; + + public static final String URL_CLASSIFICATIONS = PRE + "classifications"; + public static final String URL_CLASSIFICATIONS_ID = URL_CLASSIFICATIONS + "/{classificationId}"; + + public static final String URL_CLASSIFICATIONDEFINITION = PRE + "classification-definitions"; + + public static final String URL_MONITOR = PRE + "monitor"; + public static final String URL_MONITOR_TASKSSTATUS = URL_MONITOR + "/tasks-status-report"; + public static final String URL_MONITOR_TASKSWORKBASKET = URL_MONITOR + "/tasks-workbasket-report"; + public static final String URL_MONITOR_TASKSWORKBASKETPLANNED = + URL_MONITOR + "/tasks-workbasket-planned-date-report"; + public static final String URL_MONITOR_TASKSCLASSIFICATION = URL_MONITOR + "/tasks-classification-report"; + public static final String URL_MONITOR_TIMESTAMP = URL_MONITOR + "/timestamp-report"; + + public static final String URL_DOMAIN = PRE + "domains"; + public static final String URL_CLASSIFICATIONCATEGORIES = PRE + "classification-categories"; + public static final String URL_CLASSIFICATIONTYPES = PRE + "classification-types"; + public static final String URL_CURRENTUSER = PRE + "current-user-info"; + public static final String URL_HISTORYENABLED = PRE + "history-provider-enabled"; + public static final String URL_VERSION = PRE + "version"; + + public static final String URL_TASKS = PRE + "tasks"; + public static final String URL_TASKS_ID = URL_TASKS + "/{taskId}"; + public static final String URL_TASKS_ID_CLAIM = URL_TASKS_ID + "/claim"; + public static final String URL_TASKS_ID_COMPLETE = URL_TASKS_ID + "/complete"; + public static final String URL_TASKS_ID_TRANSFER_WORKBASKETID = URL_TASKS_ID + "/transfer/{workbasketId}"; + + public static final String URL_WORKBASKETACCESSITEMS = PRE + "workbasket-access-items"; + + public static final String URL_WORKBASKET = PRE + "workbaskets"; + public static final String URL_WORKBASKET_ID = URL_WORKBASKET + "/{workbasketId}"; + public static final String URL_WORKBASKET_ID_ACCESSITEMS = URL_WORKBASKET_ID + "/workbasketAccessItems"; + public static final String URL_WORKBASKET_ID_DISTRIBUTION = URL_WORKBASKET_ID + "/distribution-targets"; + //TODO @Deprecated + public static final String URL_WORKBASKET_DISTRIBUTION_ID = URL_WORKBASKET + "/distribution-targets/{workbasketId}"; + + public static final String URL_WORKBASKETDEFIITIONS = PRE + "workbasket-definitions"; + + private Mapping() { + } + +} diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/MonitorController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/MonitorController.java index d90ca3c0a..6cc6d2e77 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/MonitorController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/MonitorController.java @@ -8,11 +8,11 @@ import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -28,7 +28,7 @@ import pro.taskana.rest.resource.ReportResourceAssembler; * Controller for all monitoring endpoints. */ @RestController -@RequestMapping(path = "/api/v1/monitor", produces = "application/hal+json") +@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) public class MonitorController { private static final Logger LOGGER = LoggerFactory.getLogger(MonitorController.class); @@ -42,7 +42,7 @@ public class MonitorController { this.reportResourceAssembler = reportResourceAssembler; } - @GetMapping(path = "/tasks-status-report") + @GetMapping(path = Mapping.URL_MONITOR_TASKSSTATUS) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getTasksStatusReport(@RequestParam(required = false) List domains, @RequestParam(required = false) List states) throws NotAuthorizedException, @@ -58,7 +58,7 @@ public class MonitorController { return response; } - @GetMapping(path = "/tasks-workbasket-report") + @GetMapping(path = Mapping.URL_MONITOR_TASKSWORKBASKET) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getTasksWorkbasketReport( @RequestParam(value = "states") List states) @@ -80,7 +80,7 @@ public class MonitorController { } - @GetMapping(path = "/tasks-workbasket-planned-date-report") + @GetMapping(path = Mapping.URL_MONITOR_TASKSWORKBASKETPLANNED) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getTasksWorkbasketPlannedDateReport( @RequestParam(value = "daysInPast") int daysInPast, @@ -103,7 +103,7 @@ public class MonitorController { } - @GetMapping(path = "/tasks-classification-report") + @GetMapping(path = Mapping.URL_MONITOR_TASKSCLASSIFICATION) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getTasksClassificationReport() throws NotAuthorizedException, InvalidArgumentException { @@ -122,7 +122,7 @@ public class MonitorController { .body(report); } - @GetMapping(path = "/timestamp-report") + @GetMapping(path = Mapping.URL_MONITOR_TIMESTAMP) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getDailyEntryExitReport() throws NotAuthorizedException, InvalidArgumentException { diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskController.java index 32512b108..5d24a9d83 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskController.java @@ -11,13 +11,13 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; 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; @@ -49,7 +49,6 @@ import pro.taskana.rest.resource.TaskSummaryResourceAssembler; */ @RestController @EnableHypermediaSupport(type = HypermediaType.HAL) -@RequestMapping(path = "/api/v1/tasks", produces = "application/hal+json") public class TaskController extends AbstractPagingController { private static final Logger LOGGER = LoggerFactory.getLogger(TaskController.class); @@ -94,7 +93,7 @@ public class TaskController extends AbstractPagingController { this.taskSummaryResourceAssembler = taskSummaryResourceAssembler; } - @GetMapping + @GetMapping(path = Mapping.URL_TASKS) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getTasks( @RequestParam MultiValueMap params) throws InvalidArgumentException { @@ -119,7 +118,7 @@ public class TaskController extends AbstractPagingController { return response; } - @GetMapping(path = "/{taskId}") + @GetMapping(path = Mapping.URL_TASKS_ID) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getTask(@PathVariable String taskId) throws TaskNotFoundException, NotAuthorizedException { @@ -133,7 +132,7 @@ public class TaskController extends AbstractPagingController { return result; } - @PostMapping(path = "/{taskId}/claim") + @PostMapping(path = Mapping.URL_TASKS_ID_CLAIM) @Transactional(rollbackFor = Exception.class) public ResponseEntity claimTask(@PathVariable String taskId, @RequestBody String userName) throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { @@ -149,7 +148,7 @@ public class TaskController extends AbstractPagingController { return result; } - @RequestMapping(method = RequestMethod.POST, value = "/{taskId}/complete") + @PostMapping(path = Mapping.URL_TASKS_ID_COMPLETE) @Transactional(rollbackFor = Exception.class) public ResponseEntity completeTask(@PathVariable String taskId) throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { @@ -164,7 +163,7 @@ public class TaskController extends AbstractPagingController { return result; } - @RequestMapping(method = RequestMethod.DELETE, value = "/{taskId}") + @DeleteMapping(path = Mapping.URL_TASKS_ID) @Transactional(rollbackFor = Exception.class) public ResponseEntity deleteTask(@PathVariable String taskId) throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { @@ -175,7 +174,7 @@ public class TaskController extends AbstractPagingController { return result; } - @RequestMapping(method = RequestMethod.POST) + @PostMapping(path = Mapping.URL_TASKS) @Transactional(rollbackFor = Exception.class) public ResponseEntity createTask(@RequestBody TaskResource taskResource) throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, @@ -194,7 +193,7 @@ public class TaskController extends AbstractPagingController { return result; } - @RequestMapping(path = "/{taskId}/transfer/{workbasketId}") + @RequestMapping(path = Mapping.URL_TASKS_ID_TRANSFER_WORKBASKETID) @Transactional(rollbackFor = Exception.class) public ResponseEntity transferTask(@PathVariable String taskId, @PathVariable String workbasketId) throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidStateException { @@ -208,7 +207,7 @@ public class TaskController extends AbstractPagingController { return result; } - @PutMapping(path = "/{taskId}") + @PutMapping(path = Mapping.URL_TASKS_ID) @Transactional(rollbackFor = Exception.class) public ResponseEntity updateTask( @PathVariable(value = "taskId") String taskId, diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaEngineController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaEngineController.java index 80be7876a..e5ffee294 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaEngineController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaEngineController.java @@ -5,10 +5,9 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.MediaType; +import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import pro.taskana.TaskanaEngine; @@ -22,7 +21,7 @@ import pro.taskana.security.CurrentUserContext; * Controller for TaskanaEngine related tasks. */ @RestController -@RequestMapping(path = "/api/v1", produces = MediaType.APPLICATION_JSON_VALUE) +@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) public class TaskanaEngineController { private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineController.class); @@ -38,7 +37,7 @@ public class TaskanaEngineController { this.taskanaEngine = taskanaEngine; } - @GetMapping(path = "/domains") + @GetMapping(path = Mapping.URL_DOMAIN) public ResponseEntity> getDomains() { ResponseEntity> response = ResponseEntity.ok(taskanaEngineConfiguration.getDomains()); if (LOGGER.isDebugEnabled()) { @@ -47,7 +46,7 @@ public class TaskanaEngineController { return response; } - @GetMapping(path = "/classification-categories") + @GetMapping(path = Mapping.URL_CLASSIFICATIONCATEGORIES) public ResponseEntity> getClassificationCategories(String type) { LOGGER.debug("Entry to getClassificationCategories(type = {})", type); ResponseEntity> response; @@ -65,7 +64,7 @@ public class TaskanaEngineController { return response; } - @GetMapping(path = "/classification-types") + @GetMapping(path = Mapping.URL_CLASSIFICATIONTYPES) public ResponseEntity> getClassificationTypes() { ResponseEntity> response = ResponseEntity.ok( taskanaEngineConfiguration.getClassificationTypes()); @@ -75,7 +74,7 @@ public class TaskanaEngineController { return response; } - @GetMapping(path = "/current-user-info") + @GetMapping(path = Mapping.URL_CURRENTUSER) public ResponseEntity getCurrentUserInfo() { LOGGER.debug("Entry to getCurrentUserInfo()"); TaskanaUserInfoResource resource = new TaskanaUserInfoResource(); @@ -94,7 +93,7 @@ public class TaskanaEngineController { return response; } - @GetMapping(path = "/history-provider-enabled") + @GetMapping(path = Mapping.URL_HISTORYENABLED) public ResponseEntity getIsHistoryProviderEnabled() { ResponseEntity response = ResponseEntity.ok(taskanaEngine.isHistoryEnabled()); LOGGER.debug("Exit from getIsHistoryProviderEnabled(), returning {}", response); @@ -106,7 +105,7 @@ public class TaskanaEngineController { * * @return The current version. */ - @GetMapping(path = "/version") + @GetMapping(path = Mapping.URL_VERSION) public ResponseEntity currentVersion() { LOGGER.debug("Entry to currentVersion()"); VersionResource resource = new VersionResource(); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaRestExceptionHandler.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaRestExceptionHandler.java index d3038ffad..eabff2a80 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaRestExceptionHandler.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskanaRestExceptionHandler.java @@ -124,7 +124,8 @@ public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler } @ExceptionHandler(MaxUploadSizeExceededException.class) - protected ResponseEntity handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, WebRequest req) { + protected ResponseEntity handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, + WebRequest req) { return buildResponse(ex, req, HttpStatus.PAYLOAD_TOO_LARGE); } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketAccessItemController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketAccessItemController.java index 935e6e0a3..b1047420c 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketAccessItemController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketAccessItemController.java @@ -12,7 +12,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -32,7 +31,6 @@ import pro.taskana.rest.resource.WorkbasketAccessItemResourceAssembler; */ @RestController @EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) -@RequestMapping(path = "/api/v1/workbasket-access-items", produces = "application/hal+json") public class WorkbasketAccessItemController extends AbstractPagingController { private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketAccessItemController.class); @@ -67,7 +65,7 @@ public class WorkbasketAccessItemController extends AbstractPagingController { * @throws InvalidArgumentException * if some argument is invalid. */ - @GetMapping + @GetMapping(path = Mapping.URL_WORKBASKETACCESSITEMS) public ResponseEntity getWorkbasketAccessItems( @RequestParam MultiValueMap params) throws NotAuthorizedException, InvalidArgumentException { @@ -106,7 +104,7 @@ public class WorkbasketAccessItemController extends AbstractPagingController { * @throws InvalidArgumentException * if some argument is invalid. */ - @DeleteMapping + @DeleteMapping(path = Mapping.URL_WORKBASKETACCESSITEMS) public ResponseEntity removeWorkbasketAccessItems( @RequestParam("access-id") String accessId) throws NotAuthorizedException, InvalidArgumentException { diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java index abbcee7b3..2f4621e1d 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java @@ -19,7 +19,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -54,9 +53,9 @@ import pro.taskana.rest.resource.WorkbasketSummaryResourceAssembler; /** * Controller for all {@link Workbasket} related endpoints. */ + @RestController @EnableHypermediaSupport(type = HypermediaType.HAL) -@RequestMapping(path = "/api/v1/workbaskets", produces = "application/hal+json") public class WorkbasketController extends AbstractPagingController { private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketController.class); @@ -99,7 +98,7 @@ public class WorkbasketController extends AbstractPagingController { this.workbasketAccessItemResourceAssembler = workbasketAccessItemResourceAssembler; } - @GetMapping + @GetMapping(path = Mapping.URL_WORKBASKET) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getWorkbaskets( @RequestParam MultiValueMap params) throws InvalidArgumentException { @@ -125,7 +124,7 @@ public class WorkbasketController extends AbstractPagingController { return response; } - @GetMapping(path = "/{workbasketId}") + @GetMapping(path = Mapping.URL_WORKBASKET_ID) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getWorkbasket(@PathVariable(value = "workbasketId") String workbasketId) throws WorkbasketNotFoundException, NotAuthorizedException { @@ -140,7 +139,7 @@ public class WorkbasketController extends AbstractPagingController { return result; } - @DeleteMapping(path = "/{workbasketId}") + @DeleteMapping(path = Mapping.URL_WORKBASKET_ID) @Transactional(rollbackFor = Exception.class, noRollbackFor = WorkbasketNotFoundException.class) public ResponseEntity markWorkbasketForDeletion(@PathVariable(value = "workbasketId") String workbasketId) throws NotAuthorizedException, InvalidArgumentException, @@ -152,7 +151,7 @@ public class WorkbasketController extends AbstractPagingController { return response; } - @PostMapping + @PostMapping(path = Mapping.URL_WORKBASKET) @Transactional(rollbackFor = Exception.class) public ResponseEntity createWorkbasket(@RequestBody WorkbasketResource workbasketResource) throws InvalidWorkbasketException, NotAuthorizedException, WorkbasketAlreadyExistException, @@ -172,7 +171,7 @@ public class WorkbasketController extends AbstractPagingController { return response; } - @PutMapping(path = "/{workbasketId}") + @PutMapping(path = Mapping.URL_WORKBASKET_ID) @Transactional(rollbackFor = Exception.class) public ResponseEntity updateWorkbasket( @PathVariable(value = "workbasketId") String workbasketId, @@ -198,7 +197,7 @@ public class WorkbasketController extends AbstractPagingController { return result; } - @GetMapping(path = "/{workbasketId}/workbasketAccessItems") + @GetMapping(path = Mapping.URL_WORKBASKET_ID_ACCESSITEMS) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getWorkbasketAccessItems( @PathVariable(value = "workbasketId") String workbasketId) @@ -215,7 +214,7 @@ public class WorkbasketController extends AbstractPagingController { return result; } - @PutMapping(value = "/{workbasketId}/workbasketAccessItems") + @PutMapping(path = Mapping.URL_WORKBASKET_ID_ACCESSITEMS) @Transactional(rollbackFor = Exception.class) public ResponseEntity setWorkbasketAccessItems( @PathVariable(value = "workbasketId") String workbasketId, @@ -241,7 +240,7 @@ public class WorkbasketController extends AbstractPagingController { return response; } - @GetMapping(path = "/{workbasketId}/distribution-targets") + @GetMapping(path = Mapping.URL_WORKBASKET_ID_DISTRIBUTION) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity getDistributionTargets( @PathVariable(value = "workbasketId") String workbasketId) @@ -259,7 +258,7 @@ public class WorkbasketController extends AbstractPagingController { return result; } - @PutMapping(path = "/{workbasketId}/distribution-targets") + @PutMapping(path = Mapping.URL_WORKBASKET_ID_DISTRIBUTION) @Transactional(rollbackFor = Exception.class) public ResponseEntity setDistributionTargetsForWorkbasketId( @PathVariable(value = "workbasketId") String sourceWorkbasketId, @@ -282,7 +281,8 @@ public class WorkbasketController extends AbstractPagingController { return response; } - @DeleteMapping(path = "/distribution-targets/{workbasketId}") + // TODO - schema inconsistent with PUT and GET + @DeleteMapping(path = Mapping.URL_WORKBASKET_DISTRIBUTION_ID) @Transactional(rollbackFor = Exception.class) public ResponseEntity> removeDistributionTargetForWorkbasketId( @PathVariable(value = "workbasketId") String targetWorkbasketId) diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java index e98e5885f..c5aa10433 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java @@ -12,12 +12,11 @@ import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; -import org.springframework.http.MediaType; +import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -45,8 +44,9 @@ import pro.taskana.rest.resource.WorkbasketResource; /** * Controller for all {@link WorkbasketDefinitionResource} related endpoints. */ + @RestController -@RequestMapping(path = "/api/v1/workbasket-definitions", produces = {MediaType.APPLICATION_JSON_VALUE}) +@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) public class WorkbasketDefinitionController { private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketDefinitionController.class); @@ -62,7 +62,7 @@ public class WorkbasketDefinitionController { this.workbasketDefinitionAssembler = workbasketDefinitionAssembler; } - @GetMapping + @GetMapping(path = Mapping.URL_WORKBASKETDEFIITIONS) @Transactional(readOnly = true, rollbackFor = Exception.class) public ResponseEntity> exportWorkbaskets( @RequestParam(required = false) String domain) @@ -110,7 +110,7 @@ public class WorkbasketDefinitionController { * @throws InvalidArgumentException * if authorization information in workbaskets definitions is incorrect. */ - @PostMapping + @PostMapping(path = Mapping.URL_WORKBASKETDEFIITIONS) @Transactional(rollbackFor = Exception.class) public ResponseEntity importWorkbaskets(@RequestParam("file") MultipartFile file) throws IOException, NotAuthorizedException, DomainNotFoundException, InvalidWorkbasketException, diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/ClassificationSummaryResourceAssembler.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/ClassificationSummaryResourceAssembler.java index 9a73776ce..fa101aaa6 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/ClassificationSummaryResourceAssembler.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/ClassificationSummaryResourceAssembler.java @@ -11,6 +11,7 @@ import pro.taskana.ClassificationService; import pro.taskana.ClassificationSummary; import pro.taskana.impl.ClassificationImpl; import pro.taskana.rest.ClassificationController; +import pro.taskana.rest.Mapping; import pro.taskana.rest.resource.PagedResources.PageMetadata; import pro.taskana.rest.resource.links.PageLinks; @@ -43,7 +44,7 @@ public class ClassificationSummaryResourceAssembler return classification.asSummary(); } - @PageLinks(ClassificationController.class) + @PageLinks(Mapping.URL_CLASSIFICATIONS) public ClassificationSummaryListResource toResources(Collection entities, PageMetadata pageMetadata) { return new ClassificationSummaryListResource(toResources(entities), pageMetadata); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/TaskSummaryResourceAssembler.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/TaskSummaryResourceAssembler.java index 6705c3702..ab87c6177 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/TaskSummaryResourceAssembler.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/TaskSummaryResourceAssembler.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; import pro.taskana.TaskSummary; import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.SystemException; +import pro.taskana.rest.Mapping; import pro.taskana.rest.TaskController; import pro.taskana.rest.resource.PagedResources.PageMetadata; import pro.taskana.rest.resource.links.PageLinks; @@ -34,7 +35,7 @@ public class TaskSummaryResourceAssembler } } - @PageLinks(TaskController.class) + @PageLinks(Mapping.URL_TASKS) public TaskSummaryListResource toResources(List taskSummaries, PageMetadata pageMetadata) { return new TaskSummaryListResource(toResources(taskSummaries), pageMetadata); } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketAccessItemResourceAssembler.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketAccessItemResourceAssembler.java index e015ef75a..0d61794eb 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketAccessItemResourceAssembler.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketAccessItemResourceAssembler.java @@ -15,7 +15,7 @@ import pro.taskana.WorkbasketService; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.WorkbasketAccessItemImpl; -import pro.taskana.rest.WorkbasketAccessItemController; +import pro.taskana.rest.Mapping; import pro.taskana.rest.WorkbasketController; import pro.taskana.rest.resource.PagedResources.PageMetadata; import pro.taskana.rest.resource.links.PageLinks; @@ -48,7 +48,7 @@ public class WorkbasketAccessItemResourceAssembler extends return wbAccItemModel; } - @PageLinks(WorkbasketAccessItemController.class) + @PageLinks(Mapping.URL_WORKBASKETACCESSITEMS) public WorkbasketAccessItemPaginatedListResource toResources( List entities, PageMetadata pageMetadata) { return new WorkbasketAccessItemPaginatedListResource(toResources(entities), pageMetadata); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketSummaryResourceAssembler.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketSummaryResourceAssembler.java index b33d4d9ec..00b316953 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketSummaryResourceAssembler.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketSummaryResourceAssembler.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component; import pro.taskana.WorkbasketService; import pro.taskana.WorkbasketSummary; import pro.taskana.impl.WorkbasketImpl; +import pro.taskana.rest.Mapping; import pro.taskana.rest.WorkbasketController; import pro.taskana.rest.resource.PagedResources.PageMetadata; import pro.taskana.rest.resource.links.PageLinks; @@ -33,7 +34,7 @@ public class WorkbasketSummaryResourceAssembler return new WorkbasketSummaryResource(workbasketSummary); } - @PageLinks(WorkbasketController.class) + @PageLinks(Mapping.URL_WORKBASKET) public WorkbasketSummaryListResource toResources(List entities, PageMetadata pageMetadata) { return new WorkbasketSummaryListResource(toResources(entities), pageMetadata); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinks.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinks.java index 6bfdb5e3d..b662692b7 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinks.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinks.java @@ -11,5 +11,6 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PageLinks { - Class value(); + + String value(); } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinksAspect.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinksAspect.java index c719817ba..424287c57 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinksAspect.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/links/PageLinksAspect.java @@ -19,6 +19,7 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.util.UriComponentsBuilder; +import pro.taskana.rest.WorkbasketController; import pro.taskana.rest.resource.PagedResources.PageMetadata; /** @@ -35,8 +36,8 @@ public class PageLinksAspect { .getRequest(); Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); PageLinks pageLinks = method.getAnnotation(PageLinks.class); - Class controller = pageLinks.value(); - UriComponentsBuilder original = originalUri(controller, request); + String relativeUrl = pageLinks.value(); + UriComponentsBuilder original = originalUri(relativeUrl, request); ResourceSupport resourceSupport = (ResourceSupport) joinPoint.proceed(); resourceSupport.add(new Link(original.toUriString()).withSelfRel()); if (page != null) { @@ -57,8 +58,10 @@ public class PageLinksAspect { return resourceSupport; } - private UriComponentsBuilder originalUri(Class controller, HttpServletRequest request) { - UriComponentsBuilder baseUri = linkTo(controller).toUriComponentsBuilder(); + private UriComponentsBuilder originalUri(String relativeUrl, HttpServletRequest request) { + //any controller with a "root" mapping will do + UriComponentsBuilder baseUri = linkTo(WorkbasketController.class).toUriComponentsBuilder(); + baseUri.path(relativeUrl); for (Map.Entry entry : request.getParameterMap().entrySet()) { for (String value : entry.getValue()) { baseUri.queryParam(entry.getKey(), value);