From bcf031c22d690acbdf887e29cc3c8af3b382de3b Mon Sep 17 00:00:00 2001 From: Jose Ignacio Recuerda Cambil Date: Wed, 20 Feb 2019 17:59:17 +0100 Subject: [PATCH] TSK-789: Workbasket export does not contain authorizations --- ...WorkbasketDefinitionControllerIntTest.java | 90 +++++++++++++++---- .../rest/WorkbasketDefinitionController.java | 32 +++---- .../rest/resource/WorkbasketDefinition.java | 39 -------- .../WorkbasketDefinitionResource.java | 62 +++++++++++++ ...orkbasketDefinitionResourceAssembler.java} | 19 ++-- .../WorkbasketResourceWithoutLinks.java | 11 +++ 6 files changed, 170 insertions(+), 83 deletions(-) delete mode 100644 rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinition.java create mode 100644 rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResource.java rename rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/{WorkbasketDefinitionAssembler.java => WorkbasketDefinitionResourceAssembler.java} (77%) create mode 100644 rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketResourceWithoutLinks.java diff --git a/rest/taskana-rest-spring-example/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java b/rest/taskana-rest-spring-example/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java index 9007d3d3e..1a587da84 100644 --- a/rest/taskana-rest-spring-example/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java +++ b/rest/taskana-rest-spring-example/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java @@ -2,8 +2,14 @@ package pro.taskana.rest; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -13,8 +19,10 @@ import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.web.server.LocalServerPort; 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; @@ -25,28 +33,27 @@ import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import pro.taskana.rest.resource.WorkbasketDefinition; +import pro.taskana.rest.resource.WorkbasketDefinitionResource; -/** - * Test workbasket definitions. - */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = RestConfiguration.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = RestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class WorkbasketDefinitionControllerIntTest { private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationController.class); private String server = "http://127.0.0.1:"; - RestTemplate template; + private RestTemplate template; private HttpEntity request; private HttpHeaders headers = new HttpHeaders(); - + private ObjectMapper objMapper = new ObjectMapper(); @LocalServerPort - int port; + private int port; @Before public void before() { @@ -57,27 +64,73 @@ public class WorkbasketDefinitionControllerIntTest { } @Test - public void exportWorkbasketFromDomain() { - ResponseEntity> response = template.exchange( - this.server + this.port + "/v1/workbasket-definitions?domain=DOMAIN_A", - HttpMethod.GET, request, new ParameterizedTypeReference>() { + public void testExportWorkbasketFromDomain() { + ResponseEntity> response = template.exchange( + server + port + "/v1/workbasket-definitions?domain=DOMAIN_A", HttpMethod.GET, request, + new ParameterizedTypeReference>() { }); + assertNotNull(response.getBody()); assertEquals(HttpStatus.OK, response.getStatusCode()); - assertThat(response.getBody().get(0), instanceOf(WorkbasketDefinition.class)); - assertEquals(11, response.getBody().size()); + assertThat(response.getBody().get(0), instanceOf(WorkbasketDefinitionResource.class)); + + boolean allAuthorizationsAreEmpty = true, allDistributionTargetsAreEmpty = true; + for (WorkbasketDefinitionResource workbasketDefinition : response.getBody()) { + if (allAuthorizationsAreEmpty && !workbasketDefinition.getAuthorizations().isEmpty()) { + allAuthorizationsAreEmpty = false; + } + if (allDistributionTargetsAreEmpty && !workbasketDefinition.getDistributionTargets().isEmpty()) { + allDistributionTargetsAreEmpty = false; + } + if (!allAuthorizationsAreEmpty && !allDistributionTargetsAreEmpty) { + break; + } + } + assertFalse(allDistributionTargetsAreEmpty); + assertFalse(allAuthorizationsAreEmpty); } @Test - public void exportWorkbasketFromWrongDomain() { - ResponseEntity> response = template.exchange( - this.server + this.port + "/v1/workbasket-definitions?domain=wrongDomain", - HttpMethod.GET, request, new ParameterizedTypeReference>() { + public void testExportWorkbasketsFromWrongDomain() { + ResponseEntity> response = template.exchange( + server + port + "/v1/workbasket-definitions?domain=wrongDomain", + HttpMethod.GET, request, new ParameterizedTypeReference>() { }); assertEquals(0, response.getBody().size()); } + @Test + public void testImportWorkbasket() throws IOException { + ResponseEntity> response = template.exchange( + server + port + "/v1/workbasket-definitions?domain=DOMAIN_A", + HttpMethod.GET, request, new ParameterizedTypeReference>() { + + }); + + List list = new ArrayList<>(); + list.add(objMapper.writeValueAsString(response.getBody().get(0))); + ResponseEntity responseImport = importRequest(list); + assertEquals(HttpStatus.OK, responseImport.getStatusCode()); + } + + private ResponseEntity importRequest(List clList) throws IOException { + File tmpFile = File.createTempFile("test", ".tmp"); + FileWriter writer = new FileWriter(tmpFile); + writer.write(clList.toString()); + writer.close(); + + MultiValueMap body = new LinkedMultiValueMap<>(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + body.add("file", new FileSystemResource(tmpFile)); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String serverUrl = server + port + "/v1/workbasket-definitions"; + RestTemplate restTemplate = new RestTemplate(); + + return restTemplate.postForEntity(serverUrl, requestEntity, String.class); + } + /** * Return a REST template which is capable of dealing with responses in HAL format. * @@ -94,5 +147,4 @@ public class WorkbasketDefinitionControllerIntTest { return new RestTemplate(Collections.>singletonList(converter)); } - } 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 660f11845..3e338f784 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 @@ -37,11 +37,11 @@ import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; -import pro.taskana.rest.resource.WorkbasketDefinition; -import pro.taskana.rest.resource.WorkbasketDefinitionAssembler; +import pro.taskana.rest.resource.WorkbasketDefinitionResource; +import pro.taskana.rest.resource.WorkbasketDefinitionResourceAssembler; /** - * Controller for all {@link WorkbasketDefinition} related endpoints. + * Controller for all {@link WorkbasketDefinitionResource} related endpoints. */ @RestController @RequestMapping(path = "/v1/workbasket-definitions", produces = {MediaType.APPLICATION_JSON_VALUE}) @@ -53,21 +53,21 @@ public class WorkbasketDefinitionController { private WorkbasketService workbasketService; @Autowired - private WorkbasketDefinitionAssembler workbasketDefinitionAssembler; + private WorkbasketDefinitionResourceAssembler workbasketDefinitionAssembler; @GetMapping @Transactional(readOnly = true, rollbackFor = Exception.class) - public ResponseEntity> exportWorkbaskets(@RequestParam(required = false) String domain) + public ResponseEntity> exportWorkbaskets(@RequestParam(required = false) String domain) throws NotAuthorizedException, WorkbasketNotFoundException { LOGGER.debug("Entry to exportWorkbaskets(domain= {})", domain); WorkbasketQuery workbasketQuery = workbasketService.createWorkbasketQuery(); List workbasketSummaryList = domain != null ? workbasketQuery.domainIn(domain).list() : workbasketQuery.list(); - List basketExports = new ArrayList<>(); + List basketExports = new ArrayList<>(); for (WorkbasketSummary summary : workbasketSummaryList) { Workbasket workbasket = workbasketService.getWorkbasket(summary.getId()); - basketExports.add(workbasketDefinitionAssembler.toDefinition(workbasket)); + basketExports.add(workbasketDefinitionAssembler.toResource(workbasket)); } if (LOGGER.isDebugEnabled()) { @@ -79,7 +79,7 @@ public class WorkbasketDefinitionController { } /** - * This method imports a list of {@link WorkbasketDefinition}. This does not exactly match the REST norm, but + * This method imports a list of {@link WorkbasketDefinitionResource}. This does not exactly match the REST norm, but * we want to have an option to import all settings at once. When a logical equal (key and domain are equal) * workbasket already exists an update will be executed. Otherwise a new workbasket will be created. * @@ -96,8 +96,8 @@ public class WorkbasketDefinitionController { ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - List definitions = mapper.readValue(file.getInputStream(), - new TypeReference>() { + List definitions = mapper.readValue(file.getInputStream(), + new TypeReference>() { }); @@ -113,8 +113,8 @@ public class WorkbasketDefinitionController { Map idConversion = new HashMap<>(); // STEP 1: update or create workbaskets from the import - for (WorkbasketDefinition definition : definitions) { - Workbasket importedWb = workbasketDefinitionAssembler.toModel(definition.workbasket); + for (WorkbasketDefinitionResource definition : definitions) { + Workbasket importedWb = workbasketDefinitionAssembler.toModel(definition.getWorkbasket()); Workbasket workbasket; if (systemIds.containsKey(logicalId(importedWb))) { workbasket = workbasketService.updateWorkbasket(importedWb); @@ -127,7 +127,7 @@ public class WorkbasketDefinitionController { for (WorkbasketAccessItem accessItem : workbasketService.getWorkbasketAccessItems(workbasket.getId())) { workbasketService.deleteWorkbasketAccessItem(accessItem.getId()); } - for (WorkbasketAccessItem authorization : definition.authorizations) { + for (WorkbasketAccessItem authorization : definition.getAuthorizations()) { workbasketService.createWorkbasketAccessItem(authorization); } idConversion.put(importedWb.getId(), workbasket.getId()); @@ -135,9 +135,9 @@ public class WorkbasketDefinitionController { // STEP 2: update distribution targets // This can not be done in step 1 because the system IDs are only known after step 1 - for (WorkbasketDefinition definition : definitions) { + for (WorkbasketDefinitionResource definition : definitions) { List distributionTargets = new ArrayList<>(); - for (String oldId : definition.distributionTargets) { + for (String oldId : definition.getDistributionTargets()) { if (idConversion.containsKey(oldId)) { distributionTargets.add(idConversion.get(oldId)); } else { @@ -150,7 +150,7 @@ public class WorkbasketDefinitionController { workbasketService.setDistributionTargets( // no verification necessary since the workbasket was already imported in step 1. - idConversion.get(definition.workbasket.getWorkbasketId()), distributionTargets); + idConversion.get(definition.getWorkbasket().getWorkbasketId()), distributionTargets); } LOGGER.debug("Exit from importWorkbaskets(), returning {}", new ResponseEntity<>(HttpStatus.OK)); return new ResponseEntity<>(HttpStatus.OK); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinition.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinition.java deleted file mode 100644 index 4048e2c53..000000000 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinition.java +++ /dev/null @@ -1,39 +0,0 @@ -package pro.taskana.rest.resource; - -import java.util.List; -import java.util.Set; - -import pro.taskana.WorkbasketAccessItem; -import pro.taskana.impl.util.LoggerUtils; - -/** - * this class represents a workbasket including its distro targets and authorisations. - */ -public class WorkbasketDefinition { - - public Set distributionTargets; - public List authorizations; - public WorkbasketResource workbasket; - - public WorkbasketDefinition() { - // necessary for de-serializing - } - - public WorkbasketDefinition(WorkbasketResource workbasket, - Set distributionTargets, - List authorizations) { - super(); - this.workbasket = workbasket; - this.distributionTargets = distributionTargets; - this.authorizations = authorizations; - } - - @Override - public String toString() { - return "WorkbasketDefinition [" - + "distributionTargets= " + LoggerUtils.setToString(this.distributionTargets) - + "authorizations= " + LoggerUtils.listToString(this.authorizations) - + "workbasket= " + this.workbasket - + "]"; - } -} diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResource.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResource.java new file mode 100644 index 000000000..dfaf1b463 --- /dev/null +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResource.java @@ -0,0 +1,62 @@ +package pro.taskana.rest.resource; + +import java.util.List; +import java.util.Set; + +import pro.taskana.impl.WorkbasketAccessItemImpl; +import pro.taskana.impl.util.LoggerUtils; + +/** + * this class represents a workbasket including its distro targets and authorisations. + */ +public class WorkbasketDefinitionResource { + + private Set distributionTargets; + private List authorizations; + private WorkbasketResourceWithoutLinks workbasket; + + public WorkbasketDefinitionResource() { + // necessary for de-serializing + } + + public WorkbasketDefinitionResource(WorkbasketResourceWithoutLinks workbasket, + Set distributionTargets, List authorizations) { + super(); + this.workbasket = workbasket; + this.distributionTargets = distributionTargets; + this.authorizations = authorizations; + } + + public Set getDistributionTargets() { + return distributionTargets; + } + + public void setDistributionTargets(Set distributionTargets) { + this.distributionTargets = distributionTargets; + } + + public List getAuthorizations() { + return authorizations; + } + + public void setAuthorizations(List authorizations) { + this.authorizations = authorizations; + } + + public WorkbasketResourceWithoutLinks getWorkbasket() { + return workbasket; + } + + public void setWorkbasket(WorkbasketResourceWithoutLinks workbasket) { + this.workbasket = workbasket; + } + + @Override + public String toString() { + return "WorkbasketDefinitionResource [" + + "distributionTargets= " + LoggerUtils.setToString(this.distributionTargets) + + "authorizations= " + LoggerUtils.listToString(this.authorizations) + + "workbasket= " + this.workbasket + + "]"; + } +} diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionAssembler.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResourceAssembler.java similarity index 77% rename from rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionAssembler.java rename to rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResourceAssembler.java index d63584e09..cdc24775e 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionAssembler.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketDefinitionResourceAssembler.java @@ -16,14 +16,15 @@ import pro.taskana.WorkbasketService; import pro.taskana.WorkbasketSummary; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.WorkbasketNotFoundException; +import pro.taskana.impl.WorkbasketAccessItemImpl; import pro.taskana.impl.WorkbasketImpl; /** - * Transforms {@link Workbasket} into a {@link WorkbasketDefinition} + * Transforms {@link Workbasket} into a {@link WorkbasketDefinitionResource} * containing all additional information about that workbasket. */ @Component -public class WorkbasketDefinitionAssembler { +public class WorkbasketDefinitionResourceAssembler { @Autowired private WorkbasketService workbasketService; @@ -33,31 +34,31 @@ public class WorkbasketDefinitionAssembler { * * @param workbasket * {@link Workbasket} which will be converted - * @return a {@link WorkbasketDefinition}, containing the {@code basket}, its distribution targets and its + * @return a {@link WorkbasketDefinitionResource}, containing the {@code basket}, its distribution targets and its * authorizations * @throws NotAuthorizedException * if the user is not authorized * @throws WorkbasketNotFoundException * if {@code basket} is an unknown workbasket */ - public WorkbasketDefinition toDefinition(Workbasket workbasket) + public WorkbasketDefinitionResource toResource(Workbasket workbasket) throws NotAuthorizedException, WorkbasketNotFoundException { - WorkbasketResource basket = new WorkbasketResource(); + WorkbasketResourceWithoutLinks basket = new WorkbasketResourceWithoutLinks(); BeanUtils.copyProperties(workbasket, basket); basket.setWorkbasketId(workbasket.getId()); basket.setModified(workbasket.getModified().toString()); basket.setCreated(workbasket.getCreated().toString()); - List authorizations = new ArrayList<>(); - for (WorkbasketAccessItem accessItem : workbasketService.getWorkbasketAccessItems(basket.getKey())) { - authorizations.add(accessItem); + List authorizations = new ArrayList<>(); + for (WorkbasketAccessItem accessItem : workbasketService.getWorkbasketAccessItems(basket.getWorkbasketId())) { + authorizations.add((WorkbasketAccessItemImpl) accessItem); } Set distroTargets = workbasketService.getDistributionTargets(workbasket.getId()) .stream() .map(WorkbasketSummary::getId) .collect(Collectors.toSet()); - return new WorkbasketDefinition(basket, distroTargets, authorizations); + return new WorkbasketDefinitionResource(basket, distroTargets, authorizations); } public Workbasket toModel(WorkbasketResource wbResource) { diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketResourceWithoutLinks.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketResourceWithoutLinks.java new file mode 100644 index 000000000..2cd2335b5 --- /dev/null +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/resource/WorkbasketResourceWithoutLinks.java @@ -0,0 +1,11 @@ +package pro.taskana.rest.resource; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * Resource class for {@link pro.taskana.Workbasket} but without links property. + */ +@JsonIgnoreProperties(value = { "links" }) +public class WorkbasketResourceWithoutLinks extends WorkbasketResource { + +}