TSK-1085: Hateoas self-links which contain variables are not working for Paged representationmodels

Bug Fix
* update Aspect
* update unit-test and test "href-self" part of json
* fix checkstyl-finding
This commit is contained in:
Nikita Kolytschew 2020-07-22 00:16:45 +02:00 committed by Nik
parent d6c1040bb0
commit 5030415f17
3 changed files with 25 additions and 15 deletions

View File

@ -1,15 +1,11 @@
package pro.taskana.resource.rest;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link;
@ -17,6 +13,7 @@ import org.springframework.hateoas.PagedModel.PageMetadata;
import org.springframework.hateoas.RepresentationModel;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;
/**
@ -31,12 +28,7 @@ public class PageLinksAspect {
public <T extends RepresentationModel<? extends T> & ProceedingJoinPoint>
RepresentationModel<T> addLinksToPageResource(
ProceedingJoinPoint joinPoint, List<?> data, PageMetadata page) throws Throwable {
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
PageLinks pageLinks = method.getAnnotation(PageLinks.class);
String relativeUrl = pageLinks.value();
UriComponentsBuilder original = originalUri(relativeUrl, request);
final UriComponentsBuilder original = originalUri();
RepresentationModel<T> resourceSupport = (RepresentationModel<T>) joinPoint.proceed();
resourceSupport.add(Link.of(original.toUriString()).withSelfRel());
if (page != null) {
@ -60,10 +52,11 @@ public class PageLinksAspect {
return resourceSupport;
}
private UriComponentsBuilder originalUri(String relativeUrl, HttpServletRequest request) {
// argument to linkTo does not matter as we just want to have the default baseUrl
UriComponentsBuilder baseUri = linkTo(PageLinksAspect.class).toUriComponentsBuilder();
baseUri.path(relativeUrl);
private UriComponentsBuilder originalUri() {
final HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
final UriComponentsBuilder baseUri =
ServletUriComponentsBuilder.fromServletMapping(request).path(request.getRequestURI());
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
for (String value : entry.getValue()) {
baseUri.queryParam(entry.getKey(), value);

View File

@ -1,6 +1,7 @@
package pro.taskana.doc.api;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
@ -351,6 +352,8 @@ class WorkbasketControllerRestDocumentation extends BaseRestDocumentation {
.accept("application/hal+json")
.header("Authorization", TEAMLEAD_1_CREDENTIALS))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("_links.self.href",
is("http://localhost:8080/api/v1/workbaskets/WBI:100000000000000000000000000000000001")))
.andDo(
MockMvcRestDocumentation.document(
"GetSpecificWorkbasketDocTest", responseFields(workbasketFieldDescriptors)));
@ -383,6 +386,8 @@ class WorkbasketControllerRestDocumentation extends BaseRestDocumentation {
.accept("application/hal+json")
.header("Authorization", TEAMLEAD_1_CREDENTIALS))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("_links.self.href",
is("http://localhost:8080/api/v1/workbaskets/WBI:100000000000000000000000000000000001")))
.andDo(
MockMvcRestDocumentation.document(
"WorkbasketSubset", responseFields(workbasketSubsetFieldDescriptors)));
@ -411,6 +416,8 @@ class WorkbasketControllerRestDocumentation extends BaseRestDocumentation {
"WBI:100000000000000000000000000000000002"))
.header("Authorization", TEAMLEAD_1_CREDENTIALS))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("_links.self.href",
is("http://localhost:8080/api/v1/workbaskets/WBI:100000000000000000000000000000000002/distribution-targets")))
.andDo(
MockMvcRestDocumentation.document(
"GetAllWorkbasketDistributionTargets",
@ -470,6 +477,8 @@ class WorkbasketControllerRestDocumentation extends BaseRestDocumentation {
.contentType("application/json")
.content(modifiedWorkbasket))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("_links.self.href",
is("http://localhost:8080/api/v1/workbaskets/WBI:100000000000000000000000000000000002")))
.andDo(
MockMvcRestDocumentation.document(
"UpdateWorkbasketDocTest",
@ -500,6 +509,8 @@ class WorkbasketControllerRestDocumentation extends BaseRestDocumentation {
.accept("application/hal+json")
.header("Authorization", TEAMLEAD_1_CREDENTIALS))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("_links.self.href",
is("http://localhost:8080/api/v1/workbaskets/WBI:100000000000000000000000000000000001/workbasketAccessItems")))
.andDo(
MockMvcRestDocumentation.document(
"AccessItemsDocTest", responseFields(accessItemFieldDescriptors)));

View File

@ -5,11 +5,13 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static pro.taskana.common.rest.RestHelper.TEMPLATE;
import java.time.Instant;
import java.util.Optional;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
@ -49,14 +51,18 @@ class WorkbasketControllerIntTest {
@Test
void testGetWorkbasket() {
final String url = restHelper.toUrl(Mapping.URL_WORKBASKET_ID,
"WBI:100000000000000000000000000000000006");
ResponseEntity<WorkbasketRepresentationModel> response =
TEMPLATE.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, "WBI:100000000000000000000000000000000006"),
url,
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(WorkbasketRepresentationModel.class));
assertThat(response.getBody()).isNotNull();
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
assertThat(response.getBody().getLink(IanaLinkRelations.SELF))
.isEqualTo(Optional.of(Link.of(url)));
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaTypes.HAL_JSON);
}