TSK-226: Enable HATEOAS on REST at least for Workbasket

This commit is contained in:
Marcel Lengl 2018-02-27 11:27:25 +01:00 committed by Holger Hagen
parent 0bdbf4700b
commit 42d8739a67
13 changed files with 186 additions and 78 deletions

View File

@ -22,6 +22,11 @@ import org.springframework.web.bind.annotation.RestController;
import pro.taskana.Classification; import pro.taskana.Classification;
import pro.taskana.ClassificationService; import pro.taskana.ClassificationService;
import pro.taskana.ClassificationSummary; import pro.taskana.ClassificationSummary;
import pro.taskana.exceptions.ClassificationAlreadyExistException;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.mapper.ClassificationMapper;
@RestController @RestController
@RequestMapping(path = "/v1/classifications", produces = {MediaType.APPLICATION_JSON_VALUE}) @RequestMapping(path = "/v1/classifications", produces = {MediaType.APPLICATION_JSON_VALUE})
@ -30,6 +35,9 @@ public class ClassificationController {
@Autowired @Autowired
private ClassificationService classificationService; private ClassificationService classificationService;
@Autowired
private ClassificationMapper classificationMapper;
@GetMapping @GetMapping
@Transactional(readOnly = true, rollbackFor = Exception.class) @Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<List<ClassificationSummary>> getClassifications() { public ResponseEntity<List<ClassificationSummary>> getClassifications() {
@ -42,52 +50,61 @@ public class ClassificationController {
} }
} }
@GetMapping(path = "/{classificationKey}") @GetMapping(path = "/{classificationId}")
@Transactional(readOnly = true, rollbackFor = Exception.class) @Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<Classification> getClassification(@PathVariable String classificationKey) { public ResponseEntity<ClassificationResource> getClassification(@PathVariable String classificationId) {
try { try {
Classification classification = classificationService.getClassification(classificationKey, ""); Classification classification = classificationService.getClassification(classificationId);
return ResponseEntity.status(HttpStatus.OK).body(classification); return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
} catch (Exception e) { } catch (ClassificationNotFoundException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} }
} }
@GetMapping(path = "/{classificationKey}/{domain}") @GetMapping(path = "/{classificationKey}/{domain}")
@Transactional(readOnly = true, rollbackFor = Exception.class) @Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<Classification> getClassification(@PathVariable String classificationKey, public ResponseEntity<ClassificationResource> getClassification(@PathVariable String classificationKey,
@PathVariable String domain) { @PathVariable String domain) {
try { try {
Classification classification = classificationService.getClassification(classificationKey, domain); Classification classification = classificationService.getClassification(classificationKey, domain);
return ResponseEntity.status(HttpStatus.OK).body(classification); return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
} catch (Exception e) { } catch (ClassificationNotFoundException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} }
} }
@PostMapping @PostMapping
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseEntity<Classification> createClassification(@RequestBody Classification classification) { public ResponseEntity<ClassificationResource> createClassification(
@RequestBody ClassificationResource resource) {
try { try {
classificationService.createClassification(classification); Classification classification = classificationMapper.toModel(resource);
return ResponseEntity.status(HttpStatus.CREATED).body(classification); classification = classificationService.createClassification(classification);
} catch (Exception e) { return ResponseEntity.status(HttpStatus.CREATED).body(classificationMapper.toResource(classification));
} catch (ClassificationAlreadyExistException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.CONFLICT).build();
} catch (NotAuthorizedException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
} }
} }
@PutMapping @PutMapping
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseEntity<Classification> updateClassification(@RequestBody Classification classification) { public ResponseEntity<ClassificationResource> updateClassification(@RequestBody ClassificationResource resource) {
try { try {
classificationService.updateClassification(classification); Classification classification = classificationMapper.toModel(resource);
return ResponseEntity.status(HttpStatus.CREATED).body(classification); classification = classificationService.updateClassification(classification);
} catch (Exception e) { return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
} catch (ClassificationNotFoundException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (NotAuthorizedException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
} }
} }
} }

View File

@ -35,7 +35,7 @@ import pro.taskana.sampledata.SampleDataGenerator;
@EnableTransactionManagement @EnableTransactionManagement
public class RestConfiguration { public class RestConfiguration {
private static final Logger logger = LoggerFactory.getLogger(RestApplication.class); private static final Logger LOGGER = LoggerFactory.getLogger(RestApplication.class);
@Bean @Bean
@Primary @Primary
@ -80,8 +80,8 @@ public class RestConfiguration {
@Bean @Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource) throws SQLException { public TaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource) throws SQLException {
TaskanaEngineConfiguration taskanaEngineConfiguration = TaskanaEngineConfiguration taskanaEngineConfiguration = new SpringTaskanaEngineConfiguration(dataSource, true,
new SpringTaskanaEngineConfiguration(dataSource, true, true); true);
new SampleDataGenerator(dataSource).generateSampleData(); new SampleDataGenerator(dataSource).generateSampleData();

View File

@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; 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.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -182,9 +181,16 @@ public class WorkbasketController {
public ResponseEntity<List<WorkbasketAccessItemResource>> getWorkbasketAuthorizations( public ResponseEntity<List<WorkbasketAccessItemResource>> getWorkbasketAuthorizations(
@PathVariable(value = "workbasketId") String workbasketId) { @PathVariable(value = "workbasketId") String workbasketId) {
List<WorkbasketAccessItem> wbAuthorizations = workbasketService.getWorkbasketAuthorizations(workbasketId); List<WorkbasketAccessItem> wbAuthorizations = workbasketService.getWorkbasketAuthorizations(workbasketId);
return new ResponseEntity<>(wbAuthorizations.stream() List<WorkbasketAccessItemResource> result = new ArrayList<>();
.map(accItem -> workbasketAccessItemMapper.toResource(accItem)) wbAuthorizations.stream()
.collect(Collectors.toList()), HttpStatus.OK); .forEach(accItem -> {
try {
result.add(workbasketAccessItemMapper.toResource(accItem));
} catch (NotAuthorizedException e) {
e.printStackTrace();
}
});
return new ResponseEntity<>(result, HttpStatus.OK);
} }
@PostMapping(path = "/authorizations") @PostMapping(path = "/authorizations")
@ -216,7 +222,7 @@ public class WorkbasketController {
} }
} }
@RequestMapping(value = "/{workbasketId}/authorizations/", method = RequestMethod.PUT) @PutMapping(value = "/{workbasketId}/authorizations/")
public ResponseEntity<?> setWorkbasketAuthorizations(@PathVariable(value = "workbasketId") String workbasketId, public ResponseEntity<?> setWorkbasketAuthorizations(@PathVariable(value = "workbasketId") String workbasketId,
@RequestBody List<WorkbasketAccessItemResource> workbasketAccessResourceItems) { @RequestBody List<WorkbasketAccessItemResource> workbasketAccessResourceItems) {
try { try {
@ -263,7 +269,7 @@ public class WorkbasketController {
@PutMapping(path = "/{workbasketId}/distributiontargets") @PutMapping(path = "/{workbasketId}/distributiontargets")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseEntity<?> setDistributionTargets( public ResponseEntity<?> setDistributionTargetsForWorkbasketId(
@PathVariable(value = "workbasketId") String sourceWorkbasketId, @PathVariable(value = "workbasketId") String sourceWorkbasketId,
@RequestBody List<String> targetWorkbasketIds) { @RequestBody List<String> targetWorkbasketIds) {
ResponseEntity<?> result; ResponseEntity<?> result;

View File

@ -87,8 +87,7 @@ public class WorkbasketDefinitionController {
*/ */
@PostMapping(path = "/import") @PostMapping(path = "/import")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseEntity<String> importWorkbaskets(@RequestBody List<WorkbasketDefinition> definitions) public ResponseEntity<String> importWorkbaskets(@RequestBody List<WorkbasketDefinition> definitions) {
throws InvalidArgumentException {
try { try {
// key: logical ID // key: logical ID
// value: system ID (in database) // value: system ID (in database)
@ -141,9 +140,7 @@ public class WorkbasketDefinitionController {
// no verification necessary since the workbasket was already imported in step 1. // no verification necessary since the workbasket was already imported in step 1.
idConversion.get(definition.workbasketResource.workbasketId), distributionTargets); idConversion.get(definition.workbasketResource.workbasketId), distributionTargets);
} }
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} catch (WorkbasketNotFoundException e) { } catch (WorkbasketNotFoundException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return new ResponseEntity<>(HttpStatus.NOT_FOUND); return new ResponseEntity<>(HttpStatus.NOT_FOUND);
@ -153,6 +150,9 @@ public class WorkbasketDefinitionController {
} catch (NotAuthorizedException e) { } catch (NotAuthorizedException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
} catch (InvalidArgumentException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
} }
} }

View File

@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import pro.taskana.ClassificationService;
import pro.taskana.TaskQuery; import pro.taskana.TaskQuery;
import pro.taskana.TaskService; import pro.taskana.TaskService;
import pro.taskana.TaskSummary; import pro.taskana.TaskSummary;
@ -49,9 +48,6 @@ public class TaskFilter {
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
@Autowired
private ClassificationService classificationService;
public List<TaskSummary> getAll() throws NotAuthorizedException { public List<TaskSummary> getAll() throws NotAuthorizedException {
return taskService.createTaskQuery().list(); return taskService.createTaskQuery().list();
} }

View File

@ -26,5 +26,4 @@ public class WorkbasketDefinition extends ResourceSupport {
this.distributionTargets = distributionTargets; this.distributionTargets = distributionTargets;
this.authorizations = authorizations; this.authorizations = authorizations;
} }
} }

View File

@ -1,5 +1,8 @@
package pro.taskana.rest.resource.mapper; package pro.taskana.rest.resource.mapper;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.time.Instant; import java.time.Instant;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -8,8 +11,9 @@ import org.springframework.stereotype.Component;
import pro.taskana.Classification; import pro.taskana.Classification;
import pro.taskana.ClassificationService; import pro.taskana.ClassificationService;
import pro.taskana.impl.ClassificationImpl;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.ClassificationImpl;
import pro.taskana.rest.ClassificationController;
import pro.taskana.rest.resource.ClassificationResource; import pro.taskana.rest.resource.ClassificationResource;
@Component @Component
@ -21,10 +25,10 @@ public class ClassificationMapper {
public ClassificationResource toResource(Classification classification) { public ClassificationResource toResource(Classification classification) {
ClassificationResource resource = new ClassificationResource(); ClassificationResource resource = new ClassificationResource();
BeanUtils.copyProperties(classification, resource); BeanUtils.copyProperties(classification, resource);
//need to be set by hand, because they are named different, or have different types // need to be set by hand, because they are named different, or have different types
resource.setClassificationId(classification.getId()); resource.setClassificationId(classification.getId());
resource.setCreated(classification.getCreated().toString()); resource.setCreated(classification.getCreated().toString());
return resource; return addLinks(resource, classification);
} }
public Classification toModel(ClassificationResource classificationResource) throws NotAuthorizedException { public Classification toModel(ClassificationResource classificationResource) throws NotAuthorizedException {
@ -36,4 +40,23 @@ public class ClassificationMapper {
classification.setCreated(Instant.parse(classificationResource.getCreated())); classification.setCreated(Instant.parse(classificationResource.getCreated()));
return classification; return classification;
} }
private ClassificationResource addLinks(ClassificationResource resource, Classification classification) {
resource.add(
linkTo(methodOn(ClassificationController.class).getClassification(classification.getId()))
.withSelfRel());
resource.add(
linkTo(methodOn(ClassificationController.class).getClassification(classification.getKey(),
classification.getDomain()))
.withRel("getClassificationByKeyAndDomain"));
resource.add(
linkTo(methodOn(ClassificationController.class).getClassifications()).withRel("getAllClassifications"));
resource.add(
linkTo(methodOn(ClassificationController.class).createClassification(resource))
.withRel("createClassification"));
resource.add(
linkTo(methodOn(ClassificationController.class).updateClassification(resource))
.withRel("updateClassification"));
return resource;
}
} }

View File

@ -3,12 +3,15 @@ package pro.taskana.rest.resource.mapper;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.Arrays;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import pro.taskana.WorkbasketAccessItem; import pro.taskana.WorkbasketAccessItem;
import pro.taskana.WorkbasketService; import pro.taskana.WorkbasketService;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.WorkbasketAccessItemImpl; import pro.taskana.impl.WorkbasketAccessItemImpl;
import pro.taskana.rest.WorkbasketController; import pro.taskana.rest.WorkbasketController;
import pro.taskana.rest.resource.WorkbasketAccessItemResource; import pro.taskana.rest.resource.WorkbasketAccessItemResource;
@ -19,17 +22,13 @@ public class WorkbasketAccessItemMapper {
@Autowired @Autowired
private WorkbasketService workbasketService; private WorkbasketService workbasketService;
public WorkbasketAccessItemResource toResource(WorkbasketAccessItem wbAccItem) { public WorkbasketAccessItemResource toResource(WorkbasketAccessItem wbAccItem) throws NotAuthorizedException {
WorkbasketAccessItemResource resource = new WorkbasketAccessItemResource(); WorkbasketAccessItemResource resource = new WorkbasketAccessItemResource();
BeanUtils.copyProperties(wbAccItem, resource); BeanUtils.copyProperties(wbAccItem, resource);
//property is named different, so it needs to be set by hand // property is named different, so it needs to be set by hand
resource.setAccessItemId(wbAccItem.getId()); resource.setAccessItemId(wbAccItem.getId());
// Add self-decription link to hateoas return addLinks(resource, wbAccItem);
resource.add(
linkTo(methodOn(WorkbasketController.class).getWorkbasketAuthorizations(wbAccItem.getWorkbasketId()))
.withSelfRel());
return resource;
} }
public WorkbasketAccessItem toModel(WorkbasketAccessItemResource wbAccItemRecource) { public WorkbasketAccessItem toModel(WorkbasketAccessItemResource wbAccItemRecource) {
@ -41,4 +40,24 @@ public class WorkbasketAccessItemMapper {
return wbAccItemModel; return wbAccItemModel;
} }
WorkbasketAccessItemResource addLinks(WorkbasketAccessItemResource resource, WorkbasketAccessItem wbAccItem)
throws NotAuthorizedException {
resource.add(
linkTo(methodOn(WorkbasketController.class).getWorkbasketAuthorizations(wbAccItem.getWorkbasketId()))
.withRel("getWorkbasketAuthorizations"));
resource.add(
linkTo(methodOn(WorkbasketController.class).createWorkbasketAuthorization(resource))
.withRel("createWorkbasketAuthorization"));
resource.add(
linkTo(methodOn(WorkbasketController.class).updateWorkbasketAuthorization(wbAccItem.getId(), resource))
.withRel("updateWorkbasketAuthorization"));
resource.add(
linkTo(methodOn(WorkbasketController.class).setWorkbasketAuthorizations(wbAccItem.getWorkbasketId(),
Arrays.asList(resource)))
.withRel("setWorkbasketAuthorizations"));
resource.add(
linkTo(methodOn(WorkbasketController.class).deleteWorkbasketAuthorization(wbAccItem.getId()))
.withRel("deleteWorkbasketAuthorization"));
return resource;
}
} }

View File

@ -1,5 +1,10 @@
package pro.taskana.rest.resource.mapper; package pro.taskana.rest.resource.mapper;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -12,6 +17,7 @@ import pro.taskana.WorkbasketService;
import pro.taskana.WorkbasketSummary; import pro.taskana.WorkbasketSummary;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.rest.WorkbasketDefinitionController;
import pro.taskana.rest.resource.WorkbasketAccessItemResource; import pro.taskana.rest.resource.WorkbasketAccessItemResource;
import pro.taskana.rest.resource.WorkbasketDefinition; import pro.taskana.rest.resource.WorkbasketDefinition;
@ -29,21 +35,45 @@ public class WorkbasketDefinitionMapper {
/** /**
* maps the distro targets to their id to remove overhead. * maps the distro targets to their id to remove overhead.
* @param basket {@link Workbasket} which will be converted *
* @return a {@link WorkbasketDefinition}, containing the {@code basket}, * @param basket
* its ditribution targets and its authorizations * {@link Workbasket} which will be converted
* @throws NotAuthorizedException if the user is not authorized * @return a {@link WorkbasketDefinition}, containing the {@code basket}, its ditribution targets and its
* @throws WorkbasketNotFoundException if {@code basket} is an unknown workbasket * authorizations
* @throws NotAuthorizedException
* if the user is not authorized
* @throws WorkbasketNotFoundException
* if {@code basket} is an unknown workbasket
*/ */
public WorkbasketDefinition toResource(Workbasket basket) public WorkbasketDefinition toResource(Workbasket basket)
throws NotAuthorizedException, WorkbasketNotFoundException { throws NotAuthorizedException, WorkbasketNotFoundException {
List<WorkbasketAccessItemResource> authorizations = workbasketService.getWorkbasketAuthorizations( List<WorkbasketAccessItemResource> authorizations = new ArrayList<>();
basket.getKey()).stream() workbasketService.getWorkbasketAuthorizations(
.map(workbasketAccessItemMapper::toResource) basket.getKey())
.collect(Collectors.toList()); .stream()
Set<String> distroTargets = workbasketService.getDistributionTargets(basket.getId()).stream() .forEach(t -> {
try {
authorizations.add(workbasketAccessItemMapper.toResource(t));
} catch (NotAuthorizedException e) {
e.printStackTrace();
}
});
Set<String> distroTargets = workbasketService.getDistributionTargets(basket.getId())
.stream()
.map(WorkbasketSummary::getId) .map(WorkbasketSummary::getId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return new WorkbasketDefinition(workbasketMapper.toResource(basket), distroTargets, authorizations); WorkbasketDefinition resource = new WorkbasketDefinition(workbasketMapper.toResource(basket), distroTargets,
authorizations);
return addLinks(resource, basket);
}
private WorkbasketDefinition addLinks(WorkbasketDefinition resource, Workbasket workbasket) {
resource.add(
linkTo(methodOn(WorkbasketDefinitionController.class).exportWorkbaskets(workbasket.getDomain()))
.withRel("exportWorkbaskets"));
resource.add(
linkTo(methodOn(WorkbasketDefinitionController.class).importWorkbaskets(Arrays.asList(resource)))
.withRel("importWorkbaskets"));
return resource;
} }
} }

View File

@ -22,17 +22,15 @@ public class WorkbasketMapper {
@Autowired @Autowired
private WorkbasketService workbasketService; private WorkbasketService workbasketService;
public WorkbasketResource toResource(Workbasket wb) { public WorkbasketResource toResource(Workbasket wb) throws NotAuthorizedException {
WorkbasketResource resource = new WorkbasketResource(); WorkbasketResource resource = new WorkbasketResource();
BeanUtils.copyProperties(wb, resource); BeanUtils.copyProperties(wb, resource);
//need to be set by hand, since name or type is different // need to be set by hand, since name or type is different
resource.setWorkbasketId(wb.getId()); resource.setWorkbasketId(wb.getId());
resource.setModified(wb.getModified().toString()); resource.setModified(wb.getModified().toString());
resource.setCreated(wb.getCreated().toString()); resource.setCreated(wb.getCreated().toString());
// Add self-decription link to hateoas return addLinks(resource, wb);
resource.add(linkTo(methodOn(WorkbasketController.class).getWorkbasket(wb.getId())).withSelfRel());
return resource;
} }
public Workbasket toModel(WorkbasketResource wbResource) throws NotAuthorizedException { public Workbasket toModel(WorkbasketResource wbResource) throws NotAuthorizedException {
@ -44,4 +42,17 @@ public class WorkbasketMapper {
workbasket.setCreated(Instant.parse(wbResource.created)); workbasket.setCreated(Instant.parse(wbResource.created));
return workbasket; return workbasket;
} }
private WorkbasketResource addLinks(WorkbasketResource resource, Workbasket wb) throws NotAuthorizedException {
resource.add(linkTo(methodOn(WorkbasketController.class).getWorkbasket(wb.getId())).withSelfRel());
resource
.add(linkTo(methodOn(WorkbasketController.class).createWorkbasket(resource)).withRel("createWorkbasket"));
resource
.add(linkTo(methodOn(WorkbasketController.class).updateWorkbasket(wb.getId(), resource))
.withRel("updateWorkbasket"));
resource
.add(linkTo(methodOn(WorkbasketController.class).deleteWorkbasket(wb.getId()))
.withRel("deleteWorkbasket"));
return resource;
}
} }

View File

@ -16,12 +16,16 @@ public class WorkbasketSummaryMapper {
public WorkbasketSummaryResource toResource(WorkbasketSummary summary) { public WorkbasketSummaryResource toResource(WorkbasketSummary summary) {
WorkbasketSummaryResource resource = new WorkbasketSummaryResource(); WorkbasketSummaryResource resource = new WorkbasketSummaryResource();
BeanUtils.copyProperties(summary, resource); BeanUtils.copyProperties(summary, resource);
//named different so needs to be set by hand // named different so needs to be set by hand
resource.setWorkbasketId(summary.getId()); resource.setWorkbasketId(summary.getId());
// Add self reference return addLinks(resource, summary);
resource.add(linkTo(methodOn(WorkbasketController.class).getWorkbasket(summary.getId())).withSelfRel());
return resource;
} }
private WorkbasketSummaryResource addLinks(WorkbasketSummaryResource resource, WorkbasketSummary summary) {
resource.add(linkTo(WorkbasketController.class).slash(summary.getId()).withSelfRel());
resource.add(linkTo(methodOn(WorkbasketController.class).getDistributionTargetsForWorkbasketId(summary.getId()))
.withRel("getDistributionTargetsForWorkbasketId"));
return resource;
}
} }

View File

@ -10,6 +10,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
import pro.taskana.WorkbasketAccessItem; import pro.taskana.WorkbasketAccessItem;
import pro.taskana.WorkbasketService; import pro.taskana.WorkbasketService;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.RestApplication; import pro.taskana.rest.RestApplication;
import pro.taskana.rest.resource.WorkbasketAccessItemResource; import pro.taskana.rest.resource.WorkbasketAccessItemResource;
@ -18,12 +19,14 @@ import pro.taskana.rest.resource.WorkbasketAccessItemResource;
@WebAppConfiguration @WebAppConfiguration
public class WorkbasketAccessItemMapperTest { public class WorkbasketAccessItemMapperTest {
@Autowired WorkbasketAccessItemMapper workbasketAccessItemMapper; @Autowired
@Autowired WorkbasketService workbasketService; WorkbasketAccessItemMapper workbasketAccessItemMapper;
@Autowired
WorkbasketService workbasketService;
@Test @Test
public void workBasketAccessItemToResourcePropertiesEqual() { public void workBasketAccessItemToResourcePropertiesEqual() throws NotAuthorizedException {
//given // given
WorkbasketAccessItem accessItem = workbasketService.newWorkbasketAccessItem("1", "2"); WorkbasketAccessItem accessItem = workbasketService.newWorkbasketAccessItem("1", "2");
accessItem.setPermDistribute(false); accessItem.setPermDistribute(false);
accessItem.setPermOpen(true); accessItem.setPermOpen(true);
@ -42,16 +45,16 @@ public class WorkbasketAccessItemMapperTest {
accessItem.setPermCustom10(true); accessItem.setPermCustom10(true);
accessItem.setPermCustom11(true); accessItem.setPermCustom11(true);
accessItem.setPermCustom12(true); accessItem.setPermCustom12(true);
//when // when
WorkbasketAccessItemResource resource = workbasketAccessItemMapper.toResource( WorkbasketAccessItemResource resource = workbasketAccessItemMapper.toResource(
accessItem); accessItem);
//then // then
testEquality(accessItem, resource); testEquality(accessItem, resource);
} }
@Test @Test
public void workBasketAccessItemToModelPropertiesEqual() { public void workBasketAccessItemToModelPropertiesEqual() {
//given // given
WorkbasketAccessItemResource resource = new WorkbasketAccessItemResource(); WorkbasketAccessItemResource resource = new WorkbasketAccessItemResource();
resource.setAccessId("10"); resource.setAccessId("10");
resource.setAccessItemId("120"); resource.setAccessItemId("120");
@ -73,9 +76,9 @@ public class WorkbasketAccessItemMapperTest {
resource.setPermCustom10(false); resource.setPermCustom10(false);
resource.setPermCustom11(true); resource.setPermCustom11(true);
resource.setPermCustom12(false); resource.setPermCustom12(false);
//when // when
WorkbasketAccessItem accessItem = workbasketAccessItemMapper.toModel(resource); WorkbasketAccessItem accessItem = workbasketAccessItemMapper.toModel(resource);
//then // then
testEquality(accessItem, resource); testEquality(accessItem, resource);
} }

View File

@ -29,7 +29,7 @@ public class WorkbasketMapperTest {
WorkbasketMapper workbasketMapper; WorkbasketMapper workbasketMapper;
@Test @Test
public void workbasketToResource() { public void workbasketToResource() throws NotAuthorizedException {
// given // given
Workbasket workbasket = workbasketService.newWorkbasket("1", "DOMAIN_A"); Workbasket workbasket = workbasketService.newWorkbasket("1", "DOMAIN_A");
((WorkbasketImpl) workbasket).setId("ID"); ((WorkbasketImpl) workbasket).setId("ID");