diff --git a/.travis.yml b/.travis.yml index 79a441b..4a1a394 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,6 @@ addons: env: matrix: - PROFILE=non-existant - - PROFILE=spring5 - PROFILE=spring5-next cache: diff --git a/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/Employee.java b/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/Employee.java index ad39b9a..8dca6cf 100644 --- a/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/Employee.java +++ b/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/Employee.java @@ -15,15 +15,16 @@ */ package org.springframework.hateoas.examples; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.util.Arrays; +import java.util.Optional; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; -import lombok.Data; -import lombok.NoArgsConstructor; - import org.springframework.hateoas.Identifiable; import org.springframework.util.StringUtils; @@ -51,6 +52,10 @@ class Employee implements Identifiable { this.role = role; } + public Optional getId() { + return Optional.ofNullable(this.id); + } + /** * Just merge {@literal firstName} and {@literal lastName} together. * diff --git a/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index 1d62c90..974e3f5 100644 --- a/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/api-evolution/new-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -65,14 +65,20 @@ class EmployeeController { Employee savedEmployee = repository.save(employee); - return ResponseEntity - .created(linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).toUri()) - .body(assembler.toResource(savedEmployee)); + return savedEmployee.getId() + .map(id -> ResponseEntity + .created(linkTo(methodOn(EmployeeController.class).findOne(id)).toUri()) + .body(assembler.toResource(savedEmployee))) + .orElse(ResponseEntity.notFound().build()); } @GetMapping(value = "/employees/{id}", produces = MediaTypes.HAL_JSON_VALUE) - public Resource findOne(@PathVariable Long id) { - return assembler.toResource(repository.findOne(id)); + public ResponseEntity> findOne(@PathVariable Long id) { + + return repository.findById(id) + .map(assembler::toResource) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); } } diff --git a/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/Employee.java b/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/Employee.java index 9c12476..afff895 100644 --- a/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/Employee.java +++ b/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/Employee.java @@ -15,20 +15,23 @@ */ package org.springframework.hateoas.examples; +import lombok.AccessLevel; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Optional; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; -import lombok.Data; -import lombok.NoArgsConstructor; - import org.springframework.hateoas.Identifiable; /** * @author Greg Turnquist */ @Data -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) @Entity class Employee implements Identifiable { @@ -42,4 +45,8 @@ class Employee implements Identifiable { this.name = name; this.role = role; } + + public Optional getId() { + return Optional.ofNullable(this.id); + } } diff --git a/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index 5cd2e78..8ed6b85 100644 --- a/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/api-evolution/original-server/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -66,13 +66,17 @@ class EmployeeController { Employee savedEmployee = repository.save(employee); return ResponseEntity - .created(linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).toUri()) + .created(savedEmployee.getId() + .map(id -> linkTo(methodOn(EmployeeController.class).findOne(id)).toUri()) + .orElseThrow(() -> new RuntimeException("Failed to create for some reason"))) .body(assembler.toResource(savedEmployee)); } @GetMapping(value = "/employees/{id}", produces = MediaTypes.HAL_JSON_VALUE) public Resource findOne(@PathVariable Long id) { - return assembler.toResource(repository.findOne(id)); + return repository.findById(id) + .map(assembler::toResource) + .orElseThrow(() -> new RuntimeException("No employee '" + id + "' found")); } } diff --git a/basics/src/main/java/org/springframework/hateoas/examples/Employee.java b/basics/src/main/java/org/springframework/hateoas/examples/Employee.java index 82d5bfd..cd809a6 100644 --- a/basics/src/main/java/org/springframework/hateoas/examples/Employee.java +++ b/basics/src/main/java/org/springframework/hateoas/examples/Employee.java @@ -20,6 +20,8 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Optional; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @@ -74,6 +76,10 @@ class Employee implements Identifiable { this.role = role; } + public Optional getId() { + return Optional.ofNullable(this.id); + } + /** * This method will create another piece of data in the REST resource representation. These types * of methods are key in supporting backward compatibility. diff --git a/basics/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/basics/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index 54f7699..a9738b7 100644 --- a/basics/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/basics/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -70,8 +70,11 @@ class EmployeeController { */ @GetMapping(value = "/employees/{id}", produces = MediaTypes.HAL_JSON_VALUE) public ResponseEntity> findOne(@PathVariable long id) { - return ResponseEntity.ok( - assembler.toResource(repository.findOne(id))); + + return repository.findById(id) + .map(assembler::toResource) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); } } diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/Employee.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/Employee.java index 1d04e89..cbf7eca 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/Employee.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/Employee.java @@ -15,14 +15,16 @@ */ package org.springframework.hateoas.examples; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Optional; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; -import lombok.Data; -import lombok.NoArgsConstructor; - import org.springframework.hateoas.Identifiable; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -53,4 +55,8 @@ class Employee implements Identifiable { this.role = role; this.manager = manager; } + + public Optional getId() { + return Optional.ofNullable(this.id); + } } diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index bd65c0c..6f9764f 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -71,8 +71,11 @@ class EmployeeController { */ @GetMapping(value = "/employees/{id}", produces = MediaTypes.HAL_JSON_VALUE) public ResponseEntity> findOne(@PathVariable long id) { - return ResponseEntity.ok( - assembler.toResource(repository.findOne(id))); + + return repository.findById(id) + .map(assembler::toResource) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); } /** @@ -100,10 +103,10 @@ class EmployeeController { @GetMapping(value = "/employees/{id}/detailed", produces = MediaTypes.HAL_JSON_VALUE) public ResponseEntity> findDetailedEmployee(@PathVariable Long id) { - Employee employee = repository.findOne(id); - - return ResponseEntity.ok( - employeeWithManagerResourceAssembler.toResource( - new EmployeeWithManager(employee))); + return repository.findById(id) + .map(EmployeeWithManager::new) + .map(employeeWithManagerResourceAssembler::toResource) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); } } diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeResourceAssembler.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeResourceAssembler.java index 29ef64e..4ae6832 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeResourceAssembler.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeResourceAssembler.java @@ -47,12 +47,15 @@ class EmployeeResourceAssembler extends SimpleIdentifiableResourceAssembler { + // Add additional links + resource.add(linkTo(methodOn(ManagerController.class).findManager(id)).withRel("manager")); + resource.add(linkTo(methodOn(EmployeeController.class).findDetailedEmployee(id)).withRel("detailed")); - // Maintain a legacy link to support older clients not yet adjusted to the switch from "supervisor" to "manager". - resource.add(linkTo(methodOn(SupervisorController.class).findOne(resource.getContent().getId())).withRel("supervisor")); + // Maintain a legacy link to support older clients not yet adjusted to the switch from "supervisor" to "manager". + resource.add(linkTo(methodOn(SupervisorController.class).findOne(id)).withRel("supervisor")); + }); } /** diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeWithManager.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeWithManager.java index 119a25e..386e6e5 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeWithManager.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeWithManager.java @@ -33,7 +33,9 @@ public class EmployeeWithManager { private final Employee employee; public Long getId() { - return this.employee.getId(); + + return this.employee.getId() + .orElseThrow(() -> new RuntimeException("Couldn't find anything.")); } public String getName() { diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/Manager.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/Manager.java index fb34f98..5a3a4c5 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/Manager.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/Manager.java @@ -15,17 +15,18 @@ */ package org.springframework.hateoas.examples; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.util.ArrayList; import java.util.List; +import java.util.Optional; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; -import lombok.Data; -import lombok.NoArgsConstructor; - import org.springframework.hateoas.Identifiable; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -52,4 +53,8 @@ class Manager implements Identifiable { Manager(String name) { this.name = name; } + + public Optional getId() { + return Optional.ofNullable(this.id); + } } diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerController.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerController.java index 019a303..a2c18e1 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerController.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerController.java @@ -65,8 +65,11 @@ class ManagerController { */ @GetMapping(value = "/managers/{id}", produces = MediaTypes.HAL_JSON_VALUE) ResponseEntity> findOne(@PathVariable long id) { - return ResponseEntity.ok( - assembler.toResource(repository.findOne(id))); + + return repository.findById(id) + .map(assembler::toResource) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); } /** diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerResourceAssembler.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerResourceAssembler.java index 9a79ef5..ba7786f 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerResourceAssembler.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/ManagerResourceAssembler.java @@ -44,8 +44,11 @@ class ManagerResourceAssembler extends SimpleIdentifiableResourceAssembler { + // Add custom link to find all managed employees + resource.add(linkTo(methodOn(EmployeeController.class).findEmployees(id)).withRel("employees")); + }); } /** diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/Supervisor.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/Supervisor.java index 2c4b294..099e4bb 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/Supervisor.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/Supervisor.java @@ -15,11 +15,11 @@ */ package org.springframework.hateoas.examples; +import lombok.Value; + import java.util.List; import java.util.stream.Collectors; -import lombok.Value; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -37,7 +37,9 @@ class Supervisor { private final Manager manager; public Long getId() { - return this.manager.getId(); + + return this.manager.getId() + .orElseThrow(() -> new RuntimeException("Couldn't find anything")); } public String getName() { diff --git a/pom.xml b/pom.xml index d4b65cd..9603040 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.8.RELEASE + 2.0.0.M6 @@ -54,24 +54,13 @@ UTF-8 UTF-8 1.8 + + 1.0.0.BUILD-SNAPSHOT + 2.0.0.BUILD-SNAPSHOT - - spring5 - - 5.0.1.RELEASE - 2.9.2 - - - - spring-libs-milestone - http://repo.spring.io/libs-milestone - - - - spring5-next diff --git a/security/pom.xml b/security/pom.xml new file mode 100644 index 0000000..32fc0e9 --- /dev/null +++ b/security/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + spring-hateoas-examples-security + Spring HATEOAS - Examples - Security + jar + + + org.springframework.hateoas.examples + spring-hateoas-examples + 1.0.0.BUILD-SNAPSHOT + + + + + org.springframework.hateoas.examples + commons + 1.0.0.BUILD-SNAPSHOT + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file