diff --git a/2022-02/spring-33/manual-hateoas/pom.xml b/2022-02/spring-33/manual-hateoas/pom.xml new file mode 100644 index 00000000..5b24b7df --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + ru.otus + manual-hateoas + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + + + 11 + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-hateoas + + + + + diff --git a/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/App.java b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/App.java new file mode 100644 index 00000000..045da3f5 --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/App.java @@ -0,0 +1,27 @@ +package ru.otus.spring.microservice; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.microservice.domain.Person; +import ru.otus.spring.microservice.repostory.PersonRepository; + +import javax.annotation.PostConstruct; + +@SpringBootApplication +public class App { + + @Autowired + private PersonRepository repository; + + public static void main(String[] args) { + SpringApplication.run(App.class); + } + + @PostConstruct + public void init() { + for(int i = 0 ; i < 18; ++i) { + repository.save(new Person("Пёрсона №" + i)); + } + } +} diff --git a/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/domain/Person.java b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/domain/Person.java new file mode 100644 index 00000000..e3d66986 --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/domain/Person.java @@ -0,0 +1,37 @@ +package ru.otus.spring.microservice.domain; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Person { + + @Id + @GeneratedValue + private int id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java new file mode 100644 index 00000000..5dc34cd8 --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java @@ -0,0 +1,7 @@ +package ru.otus.spring.microservice.repostory; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.otus.spring.microservice.domain.Person; + +public interface PersonRepository extends JpaRepository { +} diff --git a/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/rest/EntrypointRestController.java b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/rest/EntrypointRestController.java new file mode 100644 index 00000000..c66a9ed2 --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/rest/EntrypointRestController.java @@ -0,0 +1,19 @@ +package ru.otus.spring.microservice.rest; + + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +@RestController +public class EntrypointRestController { + @GetMapping("api/entrypoint") + public ResponseEntity getApiEntrypoint() { + var link = linkTo(methodOn(PersonsRestController.class).findAllPersons()).withRel("all"); + return new ResponseEntity<>(link, HttpStatus.OK); + } +} diff --git a/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/rest/PersonsRestController.java b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/rest/PersonsRestController.java new file mode 100644 index 00000000..64c16b8a --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/src/main/java/ru/otus/spring/microservice/rest/PersonsRestController.java @@ -0,0 +1,67 @@ +package ru.otus.spring.microservice.rest; + + +import org.springframework.hateoas.RepresentationModel; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import ru.otus.spring.microservice.domain.Person; +import ru.otus.spring.microservice.repostory.PersonRepository; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +@RestController +public class PersonsRestController { + + private final PersonRepository repository; + + public PersonsRestController(PersonRepository repository) { + this.repository = repository; + } + + @GetMapping("api/persons") + public ResponseEntity findAllPersons() { + List persons = repository.findAll(); + List resources = persons.stream().map(this::person2Resource) + .collect(Collectors.toList()); + return new ResponseEntity<>(resources, HttpStatus.OK); + } + + @GetMapping("api/persons/{id}") + public ResponseEntity findById(@PathVariable("id") int id) { + Optional person = repository.findById(id); + return new ResponseEntity<>(person2Resource(person.orElseThrow()), HttpStatus.OK); + } + + private PersonResource person2Resource(Person person) { + var resource = new PersonResource(person); + resource.add(linkTo(methodOn(PersonsRestController.class).findById(person.getId())).withSelfRel()); + resource.add(linkTo(methodOn(PersonsRestController.class).findAllPersons()).withRel("all")); + return resource; + } + + private static class PersonResource extends RepresentationModel { + + private final Person person; + + public PersonResource(Person person) { + this.person = person; + } + + public int getId() { + return person.getId(); + } + + public String getName() { + return person.getName(); + } + } + +} diff --git a/2022-02/spring-33/manual-hateoas/src/main/resources/application.yml b/2022-02/spring-33/manual-hateoas/src/main/resources/application.yml new file mode 100644 index 00000000..e69de29b diff --git a/2022-02/spring-33/manual-hateoas/src/main/resources/static/index.html b/2022-02/spring-33/manual-hateoas/src/main/resources/static/index.html new file mode 100644 index 00000000..97be2d13 --- /dev/null +++ b/2022-02/spring-33/manual-hateoas/src/main/resources/static/index.html @@ -0,0 +1,67 @@ + + + + + Пёрсоны + + + +
+ + \ No newline at end of file diff --git a/2022-02/spring-33/plain-api/pom.xml b/2022-02/spring-33/plain-api/pom.xml new file mode 100644 index 00000000..4fbfd9ad --- /dev/null +++ b/2022-02/spring-33/plain-api/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + ru.otus + plain-api + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + + + 11 + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + diff --git a/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/App.java b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/App.java new file mode 100644 index 00000000..045da3f5 --- /dev/null +++ b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/App.java @@ -0,0 +1,27 @@ +package ru.otus.spring.microservice; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.microservice.domain.Person; +import ru.otus.spring.microservice.repostory.PersonRepository; + +import javax.annotation.PostConstruct; + +@SpringBootApplication +public class App { + + @Autowired + private PersonRepository repository; + + public static void main(String[] args) { + SpringApplication.run(App.class); + } + + @PostConstruct + public void init() { + for(int i = 0 ; i < 18; ++i) { + repository.save(new Person("Пёрсона №" + i)); + } + } +} diff --git a/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/domain/Person.java b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/domain/Person.java new file mode 100644 index 00000000..553a8a7d --- /dev/null +++ b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/domain/Person.java @@ -0,0 +1,39 @@ +package ru.otus.spring.microservice.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Person { + + @Id + @GeneratedValue + private int id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java new file mode 100644 index 00000000..5dc34cd8 --- /dev/null +++ b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java @@ -0,0 +1,7 @@ +package ru.otus.spring.microservice.repostory; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.otus.spring.microservice.domain.Person; + +public interface PersonRepository extends JpaRepository { +} diff --git a/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/rest/PersonsRestController.java b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/rest/PersonsRestController.java new file mode 100644 index 00000000..8a7d647e --- /dev/null +++ b/2022-02/spring-33/plain-api/src/main/java/ru/otus/spring/microservice/rest/PersonsRestController.java @@ -0,0 +1,34 @@ +package ru.otus.spring.microservice.rest; + + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import ru.otus.spring.microservice.domain.Person; +import ru.otus.spring.microservice.repostory.PersonRepository; + +import java.util.List; + +@RestController +public class PersonsRestController { + + private final PersonRepository repository; + + public PersonsRestController(PersonRepository repository) { + this.repository = repository; + } + + @GetMapping("api/persons") + public ResponseEntity findAllPersons() { + List persons = repository.findAll(); + return new ResponseEntity<>(persons, HttpStatus.OK); + } + + @GetMapping("api/persons/{id}") + public ResponseEntity findById(@PathVariable("id") int id) { + Person person = repository.findById(id).orElseThrow(); + return new ResponseEntity<>(person, HttpStatus.OK); + } +} diff --git a/2022-02/spring-33/plain-api/src/main/resources/application.yml b/2022-02/spring-33/plain-api/src/main/resources/application.yml new file mode 100644 index 00000000..e69de29b diff --git a/2022-02/spring-33/plain-api/src/main/resources/static/index.html b/2022-02/spring-33/plain-api/src/main/resources/static/index.html new file mode 100644 index 00000000..ef9a23e1 --- /dev/null +++ b/2022-02/spring-33/plain-api/src/main/resources/static/index.html @@ -0,0 +1,62 @@ + + + + + Пёрсоны + + + +
+ + \ No newline at end of file diff --git a/2022-02/spring-33/pom.xml b/2022-02/spring-33/pom.xml new file mode 100644 index 00000000..a4ee7368 --- /dev/null +++ b/2022-02/spring-33/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + ru.otus + spring-data-rest-demo + 1.0 + + pom + + + plain-api + manual-hateoas + spring-data-rest + + diff --git a/2022-02/spring-33/spring-data-rest/pom.xml b/2022-02/spring-33/spring-data-rest/pom.xml new file mode 100644 index 00000000..ae57eeb6 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + ru.otus + spring-data-rest + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + + + 11 + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.h2database + h2 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-data-rest + + + + org.springframework.data + spring-data-rest-hal-explorer + + + + + diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/App.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/App.java new file mode 100644 index 00000000..045da3f5 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/App.java @@ -0,0 +1,27 @@ +package ru.otus.spring.microservice; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.microservice.domain.Person; +import ru.otus.spring.microservice.repostory.PersonRepository; + +import javax.annotation.PostConstruct; + +@SpringBootApplication +public class App { + + @Autowired + private PersonRepository repository; + + public static void main(String[] args) { + SpringApplication.run(App.class); + } + + @PostConstruct + public void init() { + for(int i = 0 ; i < 18; ++i) { + repository.save(new Person("Пёрсона №" + i)); + } + } +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/config/RestConfig.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/config/RestConfig.java new file mode 100644 index 00000000..110f7858 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/config/RestConfig.java @@ -0,0 +1,20 @@ +package ru.otus.spring.microservice.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import ru.otus.spring.microservice.projections.PersonLowerNameProjection; +import ru.otus.spring.microservice.projections.PersonUpperNameProjection; + +//@Configuration +public class RestConfig implements RepositoryRestConfigurer { + + @Override + public void configureRepositoryRestConfiguration(RepositoryRestConfiguration repositoryRestConfiguration, + CorsRegistry cors) { + repositoryRestConfiguration.getProjectionConfiguration() + .addProjection(PersonUpperNameProjection.class) + .addProjection(PersonLowerNameProjection.class); + } +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/domain/Person.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/domain/Person.java new file mode 100644 index 00000000..aa4738a0 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/domain/Person.java @@ -0,0 +1,41 @@ +package ru.otus.spring.microservice.domain; + +import ru.otus.spring.microservice.listeners.PersonEntityEventListener; + +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +@EntityListeners(PersonEntityEventListener.class) +public class Person { + + @Id + @GeneratedValue + private int id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/listeners/PersonEntityEventListener.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/listeners/PersonEntityEventListener.java new file mode 100644 index 00000000..87ca0db7 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/listeners/PersonEntityEventListener.java @@ -0,0 +1,12 @@ +package ru.otus.spring.microservice.listeners; + +import ru.otus.spring.microservice.domain.Person; + +import javax.persistence.PrePersist; + +public class PersonEntityEventListener { + @PrePersist + public void prePersist(Person p) { + p.setName(p.getName() + " (Человек и пароход)"); + } +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/projections/PersonLowerNameProjection.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/projections/PersonLowerNameProjection.java new file mode 100644 index 00000000..8f96c384 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/projections/PersonLowerNameProjection.java @@ -0,0 +1,14 @@ +package ru.otus.spring.microservice.projections; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.rest.core.config.Projection; +import ru.otus.spring.microservice.domain.Person; + +@Projection(name = "withlowername", types = Person.class) +public interface PersonLowerNameProjection { + + String getName(); + + @Value("#{target.name.toLowerCase()}") + String getNameLowerCase(); +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/projections/PersonUpperNameProjection.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/projections/PersonUpperNameProjection.java new file mode 100644 index 00000000..96ddffc5 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/projections/PersonUpperNameProjection.java @@ -0,0 +1,14 @@ +package ru.otus.spring.microservice.projections; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.rest.core.config.Projection; +import ru.otus.spring.microservice.domain.Person; + +@Projection(name = "withuppername", types = Person.class) +public interface PersonUpperNameProjection { + + String getName(); + + @Value("#{target.name.toUpperCase()}") + String getNameUpperCase(); +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java new file mode 100644 index 00000000..b76263b6 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/java/ru/otus/spring/microservice/repostory/PersonRepository.java @@ -0,0 +1,11 @@ +package ru.otus.spring.microservice.repostory; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import ru.otus.spring.microservice.domain.Person; + +import java.util.List; + +@RepositoryRestResource(path = "persons", collectionResourceRel = "persons") +public interface PersonRepository extends JpaRepository { +} diff --git a/2022-02/spring-33/spring-data-rest/src/main/resources/application.yml b/2022-02/spring-33/spring-data-rest/src/main/resources/application.yml new file mode 100644 index 00000000..2db35bd1 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/resources/application.yml @@ -0,0 +1,4 @@ +spring: + data: + rest: + basePath: /api \ No newline at end of file diff --git a/2022-02/spring-33/spring-data-rest/src/main/resources/static/index.html b/2022-02/spring-33/spring-data-rest/src/main/resources/static/index.html new file mode 100644 index 00000000..b8456b35 --- /dev/null +++ b/2022-02/spring-33/spring-data-rest/src/main/resources/static/index.html @@ -0,0 +1,89 @@ + + + + + Пёрсоны + + + +
+
+
+
+ + +
+ + \ No newline at end of file