diff --git a/pom.xml b/pom.xml index 3c77d52fe837068427f592049d402ad0f22a3477..d35db9f34122b7aa268511d3a9f36983dbd927de 100644 --- a/pom.xml +++ b/pom.xml @@ -19,11 +19,16 @@ <properties> <spring-data-jdbc.version>1.2.1.RELEASE</spring-data-jdbc.version> - <springfox-swagger.version>2.9.2</springfox-swagger.version> + <springfox-swagger.version>3.0.0</springfox-swagger.version> <jacoco.version>0.8.5</jacoco.version> - <docker.jib-maven-plugin.version>1.3.0</docker.jib-maven-plugin.version> <docker.image.prefix>springcommunity</docker.image.prefix> + <jsr305.version>3.0.2</jsr305.version> + <jackson-databind-nullable.version>0.2.1</jackson-databind-nullable.version> + <mapstruct.version>1.4.1.Final</mapstruct.version> + <jaxb-api.version>2.3.0</jaxb-api.version> + <openapi-generator-maven-plugin.version>5.2.1</openapi-generator-maven-plugin.version> + <build-helper-maven-plugin.version>3.2.0</build-helper-maven-plugin.version> </properties> <dependencies> @@ -123,16 +128,26 @@ <artifactId>json-path</artifactId> <scope>test</scope> </dependency> - <dependency> <groupId>io.springfox</groupId> - <artifactId>springfox-swagger2</artifactId> + <artifactId>springfox-boot-starter</artifactId> <version>${springfox-swagger.version}</version> </dependency> + <dependency> - <groupId>io.springfox</groupId> - <artifactId>springfox-swagger-ui</artifactId> - <version>${springfox-swagger.version}</version> + <groupId>org.openapitools</groupId> + <artifactId>jackson-databind-nullable</artifactId> + <version>${jackson-databind-nullable.version}</version> + </dependency> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct</artifactId> + <version>${mapstruct.version}</version> + </dependency> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct-processor</artifactId> + <version>${mapstruct.version}</version> </dependency> <dependency> @@ -144,7 +159,7 @@ <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> - <version>2.3.0</version> + <version>${jaxb-api.version}</version> </dependency> </dependencies> @@ -234,7 +249,90 @@ </to> </configuration> </plugin> + + + <plugin> + <groupId>org.openapitools</groupId> + <artifactId>openapi-generator-maven-plugin</artifactId> + <!-- RELEASE_VERSION --> + <version>${openapi-generator-maven-plugin.version}</version> + <!-- /RELEASE_VERSION --> + <executions> + <execution> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <inputSpec>${project.basedir}/src/main/resources/api-docs.yml</inputSpec> + <modelPackage>org.springframework.samples.petclinic.dto</modelPackage> + <generatorName>spring</generatorName> + <library>spring-boot</library> + + <!-- Only enabling model generation --> + <modelNameSuffix>Dto</modelNameSuffix> + <generateApiTests>false</generateApiTests> + <generateModelDocumentation>false</generateModelDocumentation> + <generateModelTests>false</generateModelTests> + <generateApis>false</generateApis> + <generateApiDocumentation>false</generateApiDocumentation> + <generateModels>true</generateModels> + <generateSupportingFiles>false</generateSupportingFiles> + <!-- Activating JAVA8 features --> + <configOptions> + <performBeanValidation>true</performBeanValidation> + <dateLibrary>legacy</dateLibrary> + <java8>true</java8> + <openApiNullable>false</openApiNullable> + <serializationLibrary>jackson</serializationLibrary> + </configOptions> + <!-- override the default library to jersey2 --> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>${build-helper-maven-plugin.version}</version> + <executions> + <execution> + <id>add-source</id> + <phase>generate-sources</phase> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <source>target/generated-sources/openapi/src/main/java</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <annotationProcessorPaths> + <path> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct-processor</artifactId> + <version>${mapstruct.version}</version> + </path> + </annotationProcessorPaths> + <compilerArgs> + <compilerArg> + -Amapstruct.suppressGeneratorTimestamp=true + </compilerArg> + <compilerArg> + -Amapstruct.suppressGeneratorVersionInfoComment=true + </compilerArg> + <compilerArg> + -Amapstruct.defaultComponentModel=spring + </compilerArg> + </compilerArgs> + </configuration> + </plugin> </plugins> </build> - </project> diff --git a/readme.md b/readme.md index 6f2490f9d537805f56e8d0fe28f3aa37300f31a8..8ee0d540164df29c89a40e256109aa246cfc865d 100644 --- a/readme.md +++ b/readme.md @@ -33,8 +33,12 @@ There are actuator health check and info routes as well: * [http://localhost:9966/petclinic/actuator/health](http://localhost:9966/petclinic/actuator/health) * [http://localhost:9966/petclinic/actuator/info](http://localhost:9966/petclinic/actuator/info) -## Swagger REST API documentation presented here (after application start): -[http://localhost:9966/petclinic/swagger-ui.html](http://localhost:9966/petclinic/swagger-ui.html) +## OpenAPI REST API documentation presented here (after application start): + +You can reach the swagger UI with this URL +[http://localhost:9966/petclinic/](http://localhost:9966/petclinic/swagger-ui.html). + +You then can get the Open API description reaching this URL [localhost:9966/petclinic/v3/api-docs](localhost:9966/petclinic/v3/api-docs). ## Screenshot of the Angular client diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/OwnerMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/OwnerMapper.java new file mode 100755 index 0000000000000000000000000000000000000000..193e2f2c96c40dba93b93d668a3ddef90458d4bc --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/OwnerMapper.java @@ -0,0 +1,22 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.OwnerDto; +import org.springframework.samples.petclinic.model.Owner; + +import java.util.Collection; + +/** + * Maps Owner & OwnerDto using Mapstruct + */ +@Mapper(uses = PetMapper.class) +public interface OwnerMapper { + + OwnerDto toOwnerDto(Owner owner); + + Owner toOwner(OwnerDto ownerDto); + + Collection<OwnerDto> toOwnerDtoCollection(Collection<Owner> ownerCollection); + + Collection<Owner> toOwners(Collection<OwnerDto> ownerDtos); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java new file mode 100755 index 0000000000000000000000000000000000000000..a455d33fd15aa670c16d339a2fc30faa19ddcda3 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java @@ -0,0 +1,29 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.PetDto; +import org.springframework.samples.petclinic.dto.PetTypeDto; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; + +import java.util.Collection; + +/** + * Map Pet & PetDto using mapstruct + */ +@Mapper +public interface PetMapper { + PetDto toPetDto(Pet pet); + + Collection<PetDto> toPetsDto(Collection<Pet> pets); + + Collection<Pet> toPets(Collection<PetDto> pets); + + Pet toPet(PetDto petDto); + + PetTypeDto toPetTypeDto(PetType petType); + + PetType toPetType(PetTypeDto petTypeDto); + + Collection<PetTypeDto> toPetTypeDtos(Collection<PetType> petTypes); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/PetTypeMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/PetTypeMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..d8e096f45c9eb4838ede013caa9821cf045eb4ea --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/PetTypeMapper.java @@ -0,0 +1,20 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.PetTypeDto; +import org.springframework.samples.petclinic.model.PetType; + +import java.util.Collection; + +/** + * Map PetType & PetTypeDto using mapstruct + */ +@Mapper +public interface PetTypeMapper { + + PetType toPetType(PetTypeDto petTypeDto); + + PetTypeDto toPetTypeDto(PetType petType); + + Collection<PetTypeDto> toPetTypeDtos(Collection<PetType> petTypes); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/SpecialtyMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/SpecialtyMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..1e0a2c853f24dc244dc46ddadad021ac327962ea --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/SpecialtyMapper.java @@ -0,0 +1,22 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.SpecialtyDto; +import org.springframework.samples.petclinic.model.Specialty; + +import java.util.Collection; + +/** + * Map Specialty & SpecialtyDto using mapstruct + */ +@Mapper +public interface SpecialtyMapper { + Specialty toSpecialty(SpecialtyDto specialtyDto); + + SpecialtyDto toSpecialtyDto(Specialty specialty); + + Collection<SpecialtyDto> toSpecialtyDtos(Collection<Specialty> specialties); + + Collection<Specialty> toSpecialtys(Collection<SpecialtyDto> specialties); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/UserMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/UserMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..a79985e0d136a839c9cfbf381b24c15bff7588fe --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/UserMapper.java @@ -0,0 +1,28 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.RoleDto; +import org.springframework.samples.petclinic.dto.UserDto; +import org.springframework.samples.petclinic.model.Role; +import org.springframework.samples.petclinic.model.User; + +import java.util.Collection; + +/** + * Map User/Role & UserDto/RoleDto using mapstruct + */ +@Mapper +public interface UserMapper { + Role toRole(RoleDto roleDto); + + RoleDto toRoleDto(Role role); + + Collection<RoleDto> toRoleDtos(Collection<Role> roles); + + User toUser(UserDto userDto); + + UserDto toUserDto(User user); + + Collection<Role> toRoles(Collection<RoleDto> roleDtos); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/VetMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/VetMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..79fb0262bb5c9b64bbea8358b080ea6aa4e31853 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/VetMapper.java @@ -0,0 +1,19 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.VetDto; +import org.springframework.samples.petclinic.model.Vet; + +import java.util.Collection; + +/** + * Map Vet & VetoDto using mapstruct + */ +@Mapper(uses = SpecialtyMapper.class) +public interface VetMapper { + Vet toVet(VetDto vetDto); + + VetDto toVetDto(Vet vet); + + Collection<VetDto> toVetDtos(Collection<Vet> vets); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/VisitMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/VisitMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..36fe15768dc7c93144f1c6e36219f395f325523e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/VisitMapper.java @@ -0,0 +1,20 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.dto.VisitDto; +import org.springframework.samples.petclinic.model.Visit; + +import java.util.Collection; + +/** + * Map Visit & VisitDto using mapstruct + */ +@Mapper(uses = PetMapper.class) +public interface VisitMapper { + Visit toVisit(VisitDto visitDto); + + VisitDto toVisitDto(Visit visit); + + Collection<VisitDto> toVisitsDto(Collection<Visit> visits); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java index e957e86aefd0762a13e521317892856d87c9aecd..8591cbfdc27107277b1066ee412ee84c98f959d8 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -15,30 +15,15 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.Digits; -import javax.validation.constraints.NotEmpty; - import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.core.style.ToStringCreator; -import org.springframework.samples.petclinic.rest.JacksonCustomOwnerDeserializer; -import org.springframework.samples.petclinic.rest.JacksonCustomOwnerSerializer; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import javax.persistence.*; +import javax.validation.constraints.Digits; +import javax.validation.constraints.NotEmpty; +import java.util.*; + /** * Simple JavaBean domain object representing an owner. @@ -50,8 +35,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; */ @Entity @Table(name = "owners") -@JsonSerialize(using = JacksonCustomOwnerSerializer.class) -@JsonDeserialize(using = JacksonCustomOwnerDeserializer.class) public class Owner extends Person { @Column(name = "address") @NotEmpty @@ -93,7 +76,7 @@ public class Owner extends Person { public void setTelephone(String telephone) { this.telephone = telephone; } - @JsonIgnore + protected Set<Pet> getPetsInternal() { if (this.pets == null) { this.pets = new HashSet<>(); @@ -111,6 +94,10 @@ public class Owner extends Person { return Collections.unmodifiableList(sortedPets); } + public void setPets(List<Pet> pets) { + this.pets = new HashSet<>(pets); + } + public void addPet(Pet pet) { getPetsInternal().add(pet); pet.setOwner(this); diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java index 329f71872dd4f9a51188e45c79bedc35157d2fd0..bee28ffbdc7222ddd41924afef6a86c5dc3581a5 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -15,33 +15,13 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.samples.petclinic.rest.JacksonCustomPetDeserializer; -import org.springframework.samples.petclinic.rest.JacksonCustomPetSerializer; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import javax.persistence.*; +import java.util.*; + /** * Simple business object representing a pet. @@ -52,8 +32,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; */ @Entity @Table(name = "pets") -@JsonSerialize(using = JacksonCustomPetSerializer.class) -@JsonDeserialize(using = JacksonCustomPetDeserializer.class) public class Pet extends NamedEntity { @Column(name = "birth_date") @@ -72,15 +50,14 @@ public class Pet extends NamedEntity { @OneToMany(cascade = CascadeType.ALL, mappedBy = "pet", fetch = FetchType.EAGER) private Set<Visit> visits; + public Date getBirthDate() { + return this.birthDate; + } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } - public Date getBirthDate() { - return this.birthDate; - } - public PetType getType() { return this.type; } @@ -96,7 +73,7 @@ public class Pet extends NamedEntity { public void setOwner(Owner owner) { this.owner = owner; } - @JsonIgnore + protected Set<Visit> getVisitsInternal() { if (this.visits == null) { this.visits = new HashSet<>(); @@ -114,6 +91,10 @@ public class Pet extends NamedEntity { return Collections.unmodifiableList(sortedVisits); } + public void setVisits(List<Visit> visits) { + this.visits = new HashSet<>(visits); + } + public void addVisit(Visit visit) { getVisitsInternal().add(visit); visit.setPet(this); diff --git a/src/main/java/org/springframework/samples/petclinic/model/Vet.java b/src/main/java/org/springframework/samples/petclinic/model/Vet.java index e7c2aa781b36f3281d7d334f857454161de28289..acda93e939a3eaf70b8230aaad8d72bdcb2d92ef 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Vet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Vet.java @@ -15,24 +15,13 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlElement; - +import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; -import com.fasterxml.jackson.annotation.JsonIgnore; +import javax.persistence.*; +import javax.xml.bind.annotation.XmlElement; +import java.util.*; /** * Simple JavaBean domain object representing a veterinarian. @@ -50,7 +39,7 @@ public class Vet extends Person { @JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"), inverseJoinColumns = @JoinColumn(name = "specialty_id")) private Set<Specialty> specialties; - + @JsonIgnore protected Set<Specialty> getSpecialtiesInternal() { if (this.specialties == null) { @@ -69,6 +58,11 @@ public class Vet extends Person { PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); return Collections.unmodifiableList(sortedSpecs); } + + public void setSpecialties(List<Specialty> specialties) { + this.specialties = new HashSet<>(specialties); + } + @JsonIgnore public int getNrOfSpecialties() { return getSpecialtiesInternal().size(); @@ -77,7 +71,7 @@ public class Vet extends Person { public void addSpecialty(Specialty specialty) { getSpecialtiesInternal().add(specialty); } - + public void clearSpecialties() { getSpecialtiesInternal().clear(); } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java index 05a39cdc1681d13479461e6c1c28640ed6d94164..e030aae1d22e7e3dc7d9a3b0d9493a3fe9e89a5e 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java @@ -15,24 +15,12 @@ */ package org.springframework.samples.petclinic.model; -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import javax.validation.constraints.NotEmpty; +import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.samples.petclinic.rest.JacksonCustomVisitDeserializer; -import org.springframework.samples.petclinic.rest.JacksonCustomVisitSerializer; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import javax.persistence.*; +import javax.validation.constraints.NotEmpty; +import java.util.Date; /** * Simple JavaBean domain object representing a visit. @@ -41,8 +29,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; */ @Entity @Table(name = "visits") -@JsonSerialize(using = JacksonCustomVisitSerializer.class) -@JsonDeserialize(using = JacksonCustomVisitDeserializer.class) public class Visit extends BaseEntity { /** diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java index f4fc842f9710e146907dbfda34442b817e5c4143..0b3bc28a5d44ea5a8e1dde8cd65e5c2f536cfb57 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java @@ -15,14 +15,6 @@ */ package org.springframework.samples.petclinic.repository.jdbc; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.sql.DataSource; -import javax.transaction.Transactional; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.dao.DataAccessException; @@ -40,6 +32,13 @@ import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.util.EntityUtils; import org.springframework.stereotype.Repository; +import javax.sql.DataSource; +import javax.transaction.Transactional; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * A simple JDBC-based implementation of the {@link OwnerRepository} interface. * diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java index a02f9a447b496b3eef478e481515c573069cf191..70c619dbdd872fa1088b427c5a362d2f7d6fdaa1 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java @@ -16,17 +16,15 @@ package org.springframework.samples.petclinic.repository.springdatajpa; -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - import org.springframework.context.annotation.Profile; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.model.Visit; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + /** * @author Vitaliy Fedoriv * diff --git a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomOwnerDeserializer.java b/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomOwnerDeserializer.java deleted file mode 100644 index d629b8b501135cc7aa7b92a7eebfe5f0949090a5..0000000000000000000000000000000000000000 --- a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomOwnerDeserializer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.samples.petclinic.rest; - -import java.io.IOException; - -import org.springframework.samples.petclinic.model.Owner; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -/** - * @author Vitaliy Fedoriv - * - */ - -public class JacksonCustomOwnerDeserializer extends StdDeserializer<Owner> { - - public JacksonCustomOwnerDeserializer(){ - this(null); - } - - public JacksonCustomOwnerDeserializer(Class<Owner> t) { - super(t); - } - - @Override - public Owner deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { - JsonNode node = parser.getCodec().readTree(parser); - Owner owner = new Owner(); - String firstName = node.get("firstName").asText(null); - String lastName = node.get("lastName").asText(null); - String address = node.get("address").asText(null); - String city = node.get("city").asText(null); - String telephone = node.get("telephone").asText(null); - if (node.hasNonNull("id")) { - owner.setId(node.get("id").asInt()); - } - owner.setFirstName(firstName); - owner.setLastName(lastName); - owner.setAddress(address); - owner.setCity(city); - owner.setTelephone(telephone); - return owner; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomOwnerSerializer.java b/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomOwnerSerializer.java deleted file mode 100644 index 594d82a06a9227ca8b2a87ed2deb932902320e1d..0000000000000000000000000000000000000000 --- a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomOwnerSerializer.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.samples.petclinic.rest; - -import java.io.IOException; -import java.text.Format; -import java.text.SimpleDateFormat; - -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.model.Visit; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -/** - * @author Vitaliy Fedoriv - * - */ - -public class JacksonCustomOwnerSerializer extends StdSerializer<Owner> { - - public JacksonCustomOwnerSerializer() { - this(null); - } - - public JacksonCustomOwnerSerializer(Class<Owner> t) { - super(t); - } - - @Override - public void serialize(Owner owner, JsonGenerator jgen, SerializerProvider provider) throws IOException { - Format formatter = new SimpleDateFormat("yyyy/MM/dd"); - jgen.writeStartObject(); - if (owner.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", owner.getId()); - } - - jgen.writeStringField("firstName", owner.getFirstName()); - jgen.writeStringField("lastName", owner.getLastName()); - jgen.writeStringField("address", owner.getAddress()); - jgen.writeStringField("city", owner.getCity()); - jgen.writeStringField("telephone", owner.getTelephone()); - // write pets array - jgen.writeArrayFieldStart("pets"); - for (Pet pet : owner.getPets()) { - jgen.writeStartObject(); // pet - if (pet.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", pet.getId()); - } - jgen.writeStringField("name", pet.getName()); - jgen.writeStringField("birthDate", formatter.format(pet.getBirthDate())); - - PetType petType = pet.getType(); - jgen.writeObjectFieldStart("type"); - jgen.writeNumberField("id", petType.getId()); - jgen.writeStringField("name", petType.getName()); - jgen.writeEndObject(); // type - - if (pet.getOwner().getId() == null) { - jgen.writeNullField("owner"); - } else { - jgen.writeNumberField("owner", pet.getOwner().getId()); - } - // write visits array - jgen.writeArrayFieldStart("visits"); - for (Visit visit : pet.getVisits()) { - jgen.writeStartObject(); // visit - if (visit.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", visit.getId()); - } - jgen.writeStringField("date", formatter.format(visit.getDate())); - jgen.writeStringField("description", visit.getDescription()); - jgen.writeNumberField("pet", visit.getPet().getId()); - jgen.writeEndObject(); // visit - } - jgen.writeEndArray(); // visits - jgen.writeEndObject(); // pet - } - jgen.writeEndArray(); // pets - jgen.writeEndObject(); // owner - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomPetDeserializer.java b/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomPetDeserializer.java deleted file mode 100644 index d879e88ee2439c2dd0145a13ce96bec2ab6d5ef8..0000000000000000000000000000000000000000 --- a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomPetDeserializer.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.samples.petclinic.rest; - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -/** - * @author Vitaliy Fedoriv - * - */ - -public class JacksonCustomPetDeserializer extends StdDeserializer<Pet> { - - public JacksonCustomPetDeserializer() { - this(null); - } - - public JacksonCustomPetDeserializer(Class<Pet> t) { - super(t); - } - - @Override - public Pet deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); - Pet pet = new Pet(); - Owner owner = new Owner(); - PetType petType = new PetType(); - ObjectMapper mapper = new ObjectMapper(); - Date birthDate = null; - JsonNode node = parser.getCodec().readTree(parser); - JsonNode owner_node = node.get("owner"); - JsonNode type_node = node.get("type"); - owner = mapper.treeToValue(owner_node, Owner.class); - petType = mapper.treeToValue(type_node, PetType.class); - int petId = node.get("id").asInt(); - String name = node.get("name").asText(null); - String birthDateStr = node.get("birthDate").asText(null); - try { - birthDate = formatter.parse(birthDateStr); - } catch (ParseException e) { - e.printStackTrace(); - throw new IOException(e); - } - - if (!(petId == 0)) { - pet.setId(petId); - } - pet.setName(name); - pet.setBirthDate(birthDate); - pet.setOwner(owner); - pet.setType(petType); - return pet; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomPetSerializer.java b/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomPetSerializer.java deleted file mode 100644 index 9abb4b86522fdf6d24691a8a3ae62c2a32c113a3..0000000000000000000000000000000000000000 --- a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomPetSerializer.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.samples.petclinic.rest; - -import java.io.IOException; -import java.text.Format; -import java.text.SimpleDateFormat; - -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.model.Visit; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -/** - * @author Vitaliy Fedoriv - * - */ - -public class JacksonCustomPetSerializer extends StdSerializer<Pet> { - - public JacksonCustomPetSerializer() { - this(null); - } - - protected JacksonCustomPetSerializer(Class<Pet> t) { - super(t); - } - - @Override - public void serialize(Pet pet, JsonGenerator jgen, SerializerProvider provider) throws IOException { - Format formatter = new SimpleDateFormat("yyyy/MM/dd"); - jgen.writeStartObject(); // pet - if (pet.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", pet.getId()); - } - jgen.writeStringField("name", pet.getName()); - jgen.writeStringField("birthDate", formatter.format(pet.getBirthDate())); - - PetType petType = pet.getType(); - jgen.writeObjectFieldStart("type"); - jgen.writeNumberField("id", petType.getId()); - jgen.writeStringField("name", petType.getName()); - jgen.writeEndObject(); // type - - Owner owner = pet.getOwner(); - jgen.writeObjectFieldStart("owner"); - jgen.writeNumberField("id", owner.getId()); - jgen.writeStringField("firstName", owner.getFirstName()); - jgen.writeStringField("lastName", owner.getLastName()); - jgen.writeStringField("address", owner.getAddress()); - jgen.writeStringField("city", owner.getCity()); - jgen.writeStringField("telephone", owner.getTelephone()); - jgen.writeEndObject(); // owner - // write visits array - jgen.writeArrayFieldStart("visits"); - for (Visit visit : pet.getVisits()) { - jgen.writeStartObject(); // visit - jgen.writeNumberField("id", visit.getId()); - jgen.writeStringField("date", formatter.format(visit.getDate())); - jgen.writeStringField("description", visit.getDescription()); - jgen.writeNumberField("pet", visit.getPet().getId()); - jgen.writeEndObject(); // visit - } - jgen.writeEndArray(); // visits - jgen.writeEndObject(); // pet - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomVisitDeserializer.java b/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomVisitDeserializer.java deleted file mode 100644 index f71626e21006e5e8c62dd4ecd398d46a7bd27b93..0000000000000000000000000000000000000000 --- a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomVisitDeserializer.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.samples.petclinic.rest; - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.Visit; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -/** - * @author Vitaliy Fedoriv - * - */ - -public class JacksonCustomVisitDeserializer extends StdDeserializer<Visit> { - - public JacksonCustomVisitDeserializer() { - this(null); - } - - public JacksonCustomVisitDeserializer(Class<Visit> t) { - super(t); - } - - @Override - public Visit deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); - Visit visit = new Visit(); - Pet pet = new Pet(); - ObjectMapper mapper = new ObjectMapper(); - Date visitDate = null; - JsonNode node = parser.getCodec().readTree(parser); - JsonNode pet_node = node.get("pet"); - pet = mapper.treeToValue(pet_node, Pet.class); - int visitId = node.get("id").asInt(); - String visitDateStr = node.get("date").asText(null); - String description = node.get("description").asText(null); - try { - visitDate = formatter.parse(visitDateStr); - } catch (ParseException e) { - e.printStackTrace(); - throw new IOException(e); - } - - if (!(visitId == 0)) { - visit.setId(visitId); - } - visit.setDate(visitDate); - visit.setDescription(description); - visit.setPet(pet); - return visit; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomVisitSerializer.java b/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomVisitSerializer.java deleted file mode 100644 index 84d7a8c798261b3fe4d088003d3d6459ba36a1a7..0000000000000000000000000000000000000000 --- a/src/main/java/org/springframework/samples/petclinic/rest/JacksonCustomVisitSerializer.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.samples.petclinic.rest; - -import java.io.IOException; -import java.text.Format; -import java.text.SimpleDateFormat; - -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.model.Visit; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -/** - * @author Vitaliy Fedoriv - * - */ - -public class JacksonCustomVisitSerializer extends StdSerializer<Visit> { - - public JacksonCustomVisitSerializer() { - this(null); - } - - protected JacksonCustomVisitSerializer(Class<Visit> t) { - super(t); - } - - @Override - public void serialize(Visit visit, JsonGenerator jgen, SerializerProvider provider) throws IOException { - if ((visit == null) || (visit.getPet() == null)) { - throw new IOException("Cannot serialize Visit object - visit or visit.pet is null"); - } - Format formatter = new SimpleDateFormat("yyyy/MM/dd"); - jgen.writeStartObject(); // visit - if (visit.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", visit.getId()); - } - jgen.writeStringField("date", formatter.format(visit.getDate())); - jgen.writeStringField("description", visit.getDescription()); - - Pet pet = visit.getPet(); - jgen.writeObjectFieldStart("pet"); - if (pet.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", pet.getId()); - } - jgen.writeStringField("name", pet.getName()); - jgen.writeStringField("birthDate", formatter.format(pet.getBirthDate())); - - PetType petType = pet.getType(); - jgen.writeObjectFieldStart("type"); - if (petType.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", petType.getId()); - } - jgen.writeStringField("name", petType.getName()); - jgen.writeEndObject(); // type - - Owner owner = pet.getOwner(); - jgen.writeObjectFieldStart("owner"); - if (owner.getId() == null) { - jgen.writeNullField("id"); - } else { - jgen.writeNumberField("id", owner.getId()); - } - jgen.writeStringField("firstName", owner.getFirstName()); - jgen.writeStringField("lastName", owner.getLastName()); - jgen.writeStringField("address", owner.getAddress()); - jgen.writeStringField("city", owner.getCity()); - jgen.writeStringField("telephone", owner.getTelephone()); - jgen.writeEndObject(); // owner - jgen.writeEndObject(); // pet - jgen.writeEndObject(); // visit - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java index 341adc0120cb96d68042d2cd3ef325face928553..d56042b243b49adeaea1554bf7359164b03d0a7f 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java @@ -16,28 +16,22 @@ package org.springframework.samples.petclinic.rest; -import java.util.Collection; - -import javax.transaction.Transactional; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.OwnerDto; +import org.springframework.samples.petclinic.mapper.OwnerMapper; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; +import javax.transaction.Transactional; +import javax.validation.Valid; +import java.util.Collection; + /** * @author Vitaliy Fedoriv */ @@ -47,82 +41,89 @@ import org.springframework.web.util.UriComponentsBuilder; @RequestMapping("/api/owners") public class OwnerRestController { - @Autowired - private ClinicService clinicService; + private final ClinicService clinicService; + private final OwnerMapper ownerMapper; + + public OwnerRestController(ClinicService clinicService, OwnerMapper ownerMapper) { + this.clinicService = clinicService; + this.ownerMapper = ownerMapper; + } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/*/lastname/{lastName}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<Owner>> getOwnersList(@PathVariable("lastName") String ownerLastName) { + public ResponseEntity<Collection<OwnerDto>> getOwnersList(@PathVariable("lastName") String ownerLastName) { if (ownerLastName == null) { ownerLastName = ""; } Collection<Owner> owners = this.clinicService.findOwnerByLastName(ownerLastName); if (owners.isEmpty()) { - return new ResponseEntity<Collection<Owner>>(HttpStatus.NOT_FOUND); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - return new ResponseEntity<Collection<Owner>>(owners, HttpStatus.OK); + return new ResponseEntity<>(ownerMapper.toOwnerDtoCollection(owners), HttpStatus.OK); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<Owner>> getOwners() { + public ResponseEntity<Collection<OwnerDto>> getOwners() { Collection<Owner> owners = this.clinicService.findAllOwners(); if (owners.isEmpty()) { - return new ResponseEntity<Collection<Owner>>(HttpStatus.NOT_FOUND); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - return new ResponseEntity<Collection<Owner>>(owners, HttpStatus.OK); + return new ResponseEntity<>(ownerMapper.toOwnerDtoCollection(owners), HttpStatus.OK); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/{ownerId}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Owner> getOwner(@PathVariable("ownerId") int ownerId) { + public ResponseEntity<OwnerDto> getOwner(@PathVariable("ownerId") int ownerId) { Owner owner = null; owner = this.clinicService.findOwnerById(ownerId); if (owner == null) { - return new ResponseEntity<Owner>(HttpStatus.NOT_FOUND); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - return new ResponseEntity<Owner>(owner, HttpStatus.OK); + return new ResponseEntity<>(ownerMapper.toOwnerDto(owner), HttpStatus.OK); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<Owner> addOwner(@RequestBody @Valid Owner owner, BindingResult bindingResult, - UriComponentsBuilder ucBuilder) { + public ResponseEntity<OwnerDto> addOwner(@RequestBody @Valid OwnerDto ownerDto, BindingResult bindingResult, + UriComponentsBuilder ucBuilder) { HttpHeaders headers = new HttpHeaders(); - if (bindingResult.hasErrors() || owner.getId() != null) { - BindingErrorsResponse errors = new BindingErrorsResponse(owner.getId()); + if (bindingResult.hasErrors() || ownerDto.getId() != null) { + BindingErrorsResponse errors = new BindingErrorsResponse(ownerDto.getId()); errors.addAllErrors(bindingResult); headers.add("errors", errors.toJSON()); - return new ResponseEntity<Owner>(headers, HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); } + Owner owner = ownerMapper.toOwner(ownerDto); this.clinicService.saveOwner(owner); + ownerDto.setId(owner.getId()); headers.setLocation(ucBuilder.path("/api/owners/{id}").buildAndExpand(owner.getId()).toUri()); - return new ResponseEntity<Owner>(owner, headers, HttpStatus.CREATED); + return new ResponseEntity<>(ownerDto, headers, HttpStatus.CREATED); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/{ownerId}", method = RequestMethod.PUT, produces = "application/json") - public ResponseEntity<Owner> updateOwner(@PathVariable("ownerId") int ownerId, @RequestBody @Valid Owner owner, - BindingResult bindingResult, UriComponentsBuilder ucBuilder) { - boolean bodyIdMatchesPathId = owner.getId() == null || ownerId == owner.getId(); + public ResponseEntity<OwnerDto> updateOwner(@PathVariable("ownerId") int ownerId, @RequestBody @Valid OwnerDto ownerDto, + BindingResult bindingResult, UriComponentsBuilder ucBuilder) { + boolean bodyIdMatchesPathId = ownerDto.getId() == null || ownerId == ownerDto.getId(); if (bindingResult.hasErrors() || !bodyIdMatchesPathId) { - BindingErrorsResponse errors = new BindingErrorsResponse(ownerId, owner.getId()); + BindingErrorsResponse errors = new BindingErrorsResponse(ownerId, ownerDto.getId()); errors.addAllErrors(bindingResult); HttpHeaders headers = new HttpHeaders(); headers.add("errors", errors.toJSON()); - return new ResponseEntity<Owner>(headers, HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); } Owner currentOwner = this.clinicService.findOwnerById(ownerId); if (currentOwner == null) { - return new ResponseEntity<Owner>(HttpStatus.NOT_FOUND); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - currentOwner.setAddress(owner.getAddress()); - currentOwner.setCity(owner.getCity()); - currentOwner.setFirstName(owner.getFirstName()); - currentOwner.setLastName(owner.getLastName()); - currentOwner.setTelephone(owner.getTelephone()); + currentOwner.setAddress(ownerDto.getAddress()); + currentOwner.setCity(ownerDto.getCity()); + currentOwner.setFirstName(ownerDto.getFirstName()); + currentOwner.setLastName(ownerDto.getLastName()); + currentOwner.setTelephone(ownerDto.getTelephone()); this.clinicService.saveOwner(currentOwner); - return new ResponseEntity<Owner>(currentOwner, HttpStatus.NO_CONTENT); + return new ResponseEntity<>(ownerMapper.toOwnerDto(currentOwner), HttpStatus.NO_CONTENT); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @@ -134,7 +135,7 @@ public class OwnerRestController { return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); } this.clinicService.deleteOwner(owner); - return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } } diff --git a/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java index fa077e91367a16bee024e4b1edefcc0d2ccf05be..f2ec45fd62dfbaeecca813da0a8281c6afe42eac 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java @@ -16,29 +16,23 @@ package org.springframework.samples.petclinic.rest; -import java.util.Collection; - -import javax.transaction.Transactional; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.PetDto; +import org.springframework.samples.petclinic.dto.PetTypeDto; +import org.springframework.samples.petclinic.mapper.PetMapper; import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; +import javax.transaction.Transactional; +import javax.validation.Valid; +import java.util.Collection; + /** * @author Vitaliy Fedoriv */ @@ -48,70 +42,77 @@ import org.springframework.web.util.UriComponentsBuilder; @RequestMapping("api/pets") public class PetRestController { - @Autowired - private ClinicService clinicService; + private final ClinicService clinicService; + + private final PetMapper petMapper; + + public PetRestController(ClinicService clinicService, PetMapper petMapper) { + this.clinicService = clinicService; + this.petMapper = petMapper; + } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/{petId}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Pet> getPet(@PathVariable("petId") int petId) { - Pet pet = this.clinicService.findPetById(petId); + public ResponseEntity<PetDto> getPet(@PathVariable("petId") int petId) { + PetDto pet = petMapper.toPetDto(this.clinicService.findPetById(petId)); if (pet == null) { - return new ResponseEntity<Pet>(HttpStatus.NOT_FOUND); + return new ResponseEntity<PetDto>(HttpStatus.NOT_FOUND); } - return new ResponseEntity<Pet>(pet, HttpStatus.OK); + return new ResponseEntity<PetDto>(pet, HttpStatus.OK); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<Pet>> getPets() { - Collection<Pet> pets = this.clinicService.findAllPets(); + public ResponseEntity<Collection<PetDto>> getPets() { + Collection<PetDto> pets = petMapper.toPetsDto(this.clinicService.findAllPets()); if (pets.isEmpty()) { - return new ResponseEntity<Collection<Pet>>(HttpStatus.NOT_FOUND); + return new ResponseEntity<Collection<PetDto>>(HttpStatus.NOT_FOUND); } - return new ResponseEntity<Collection<Pet>>(pets, HttpStatus.OK); + return new ResponseEntity<Collection<PetDto>>(pets, HttpStatus.OK); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/pettypes", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<PetType>> getPetTypes() { - return new ResponseEntity<Collection<PetType>>(this.clinicService.findPetTypes(), HttpStatus.OK); + public ResponseEntity<Collection<PetTypeDto>> getPetTypes() { + return new ResponseEntity<Collection<PetTypeDto>>(petMapper.toPetTypeDtos(this.clinicService.findPetTypes()), HttpStatus.OK); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<Pet> addPet(@RequestBody @Valid Pet pet, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { + public ResponseEntity<PetDto> addPet(@RequestBody @Valid PetDto petDto, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { BindingErrorsResponse errors = new BindingErrorsResponse(); HttpHeaders headers = new HttpHeaders(); - if (bindingResult.hasErrors() || (pet == null)) { + if (bindingResult.hasErrors() || (petDto == null)) { errors.addAllErrors(bindingResult); headers.add("errors", errors.toJSON()); - return new ResponseEntity<Pet>(headers, HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); } + Pet pet = petMapper.toPet(petDto); this.clinicService.savePet(pet); + petDto.setId(pet.getId()); headers.setLocation(ucBuilder.path("/api/pets/{id}").buildAndExpand(pet.getId()).toUri()); - return new ResponseEntity<Pet>(pet, headers, HttpStatus.CREATED); + return new ResponseEntity<>(petDto, headers, HttpStatus.CREATED); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/{petId}", method = RequestMethod.PUT, produces = "application/json") - public ResponseEntity<Pet> updatePet(@PathVariable("petId") int petId, @RequestBody @Valid Pet pet, BindingResult bindingResult) { + public ResponseEntity<PetDto> updatePet(@PathVariable("petId") int petId, @RequestBody @Valid PetDto pet, BindingResult bindingResult) { BindingErrorsResponse errors = new BindingErrorsResponse(); HttpHeaders headers = new HttpHeaders(); if (bindingResult.hasErrors() || (pet == null)) { errors.addAllErrors(bindingResult); headers.add("errors", errors.toJSON()); - return new ResponseEntity<Pet>(headers, HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); } Pet currentPet = this.clinicService.findPetById(petId); if (currentPet == null) { - return new ResponseEntity<Pet>(HttpStatus.NOT_FOUND); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } currentPet.setBirthDate(pet.getBirthDate()); currentPet.setName(pet.getName()); - currentPet.setType(pet.getType()); - currentPet.setOwner(pet.getOwner()); + currentPet.setType(petMapper.toPetType(pet.getType())); this.clinicService.savePet(currentPet); - return new ResponseEntity<Pet>(currentPet, HttpStatus.NO_CONTENT); + return new ResponseEntity<>(petMapper.toPetDto(currentPet), HttpStatus.NO_CONTENT); } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") diff --git a/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java index ff6728769973dfffbb81a960b4cc1d9fc19d604f..89a5438e81d90ea4c25589c3a8c0f5928e948cd5 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java @@ -16,102 +16,103 @@ package org.springframework.samples.petclinic.rest; -import java.util.ArrayList; -import java.util.Collection; - -import javax.transaction.Transactional; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.PetTypeDto; +import org.springframework.samples.petclinic.mapper.PetTypeMapper; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; +import javax.transaction.Transactional; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Collection; + @RestController @CrossOrigin(exposedHeaders = "errors, content-type") @RequestMapping("api/pettypes") public class PetTypeRestController { - @Autowired - private ClinicService clinicService; + private final ClinicService clinicService; + private final PetTypeMapper petTypeMapper; + + + public PetTypeRestController(ClinicService clinicService, PetTypeMapper petTypeMapper) { + this.clinicService = clinicService; + this.petTypeMapper = petTypeMapper; + } - @PreAuthorize( "hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<PetType>> getAllPetTypes(){ - Collection<PetType> petTypes = new ArrayList<PetType>(); - petTypes.addAll(this.clinicService.findAllPetTypes()); - if (petTypes.isEmpty()){ - return new ResponseEntity<Collection<PetType>>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Collection<PetType>>(petTypes, HttpStatus.OK); - } + @PreAuthorize("hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<Collection<PetTypeDto>> getAllPetTypes() { + Collection<PetType> petTypes = new ArrayList<PetType>(); + petTypes.addAll(this.clinicService.findAllPetTypes()); + if (petTypes.isEmpty()) { + return new ResponseEntity<Collection<PetTypeDto>>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<Collection<PetTypeDto>>(petTypeMapper.toPetTypeDtos(petTypes), HttpStatus.OK); + } - @PreAuthorize( "hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)" ) - @RequestMapping(value = "/{petTypeId}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<PetType> getPetType(@PathVariable("petTypeId") int petTypeId){ - PetType petType = this.clinicService.findPetTypeById(petTypeId); - if(petType == null){ - return new ResponseEntity<PetType>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<PetType>(petType, HttpStatus.OK); - } + @PreAuthorize("hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)") + @RequestMapping(value = "/{petTypeId}", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<PetTypeDto> getPetType(@PathVariable("petTypeId") int petTypeId) { + PetType petType = this.clinicService.findPetTypeById(petTypeId); + if (petType == null) { + return new ResponseEntity<PetTypeDto>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<PetTypeDto>(petTypeMapper.toPetTypeDto(petType), HttpStatus.OK); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<PetType> addPetType(@RequestBody @Valid PetType petType, BindingResult bindingResult, UriComponentsBuilder ucBuilder){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (petType == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<PetType>(headers, HttpStatus.BAD_REQUEST); - } - this.clinicService.savePetType(petType); - headers.setLocation(ucBuilder.path("/api/pettypes/{id}").buildAndExpand(petType.getId()).toUri()); - return new ResponseEntity<PetType>(petType, headers, HttpStatus.CREATED); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") + public ResponseEntity<PetTypeDto> addPetType(@RequestBody @Valid PetTypeDto petType, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (petType == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<PetTypeDto>(headers, HttpStatus.BAD_REQUEST); + } + final PetType type = petTypeMapper.toPetType(petType); + this.clinicService.savePetType(type); + headers.setLocation(ucBuilder.path("/api/pettypes/{id}").buildAndExpand(petType.getId()).toUri()); + return new ResponseEntity<PetTypeDto>(petTypeMapper.toPetTypeDto(type), headers, HttpStatus.CREATED); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{petTypeId}", method = RequestMethod.PUT, produces = "application/json") - public ResponseEntity<PetType> updatePetType(@PathVariable("petTypeId") int petTypeId, @RequestBody @Valid PetType petType, BindingResult bindingResult){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (petType == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<PetType>(headers, HttpStatus.BAD_REQUEST); - } - PetType currentPetType = this.clinicService.findPetTypeById(petTypeId); - if(currentPetType == null){ - return new ResponseEntity<PetType>(HttpStatus.NOT_FOUND); - } - currentPetType.setName(petType.getName()); - this.clinicService.savePetType(currentPetType); - return new ResponseEntity<PetType>(currentPetType, HttpStatus.NO_CONTENT); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{petTypeId}", method = RequestMethod.PUT, produces = "application/json") + public ResponseEntity<PetTypeDto> updatePetType(@PathVariable("petTypeId") int petTypeId, @RequestBody @Valid PetTypeDto petType, BindingResult bindingResult) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (petType == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<PetTypeDto>(headers, HttpStatus.BAD_REQUEST); + } + PetType currentPetType = this.clinicService.findPetTypeById(petTypeId); + if (currentPetType == null) { + return new ResponseEntity<PetTypeDto>(HttpStatus.NOT_FOUND); + } + currentPetType.setName(petType.getName()); + this.clinicService.savePetType(currentPetType); + return new ResponseEntity<PetTypeDto>(petTypeMapper.toPetTypeDto(currentPetType), HttpStatus.NO_CONTENT); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{petTypeId}", method = RequestMethod.DELETE, produces = "application/json") - @Transactional - public ResponseEntity<Void> deletePetType(@PathVariable("petTypeId") int petTypeId){ - PetType petType = this.clinicService.findPetTypeById(petTypeId); - if(petType == null){ - return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); - } - this.clinicService.deletePetType(petType); - return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{petTypeId}", method = RequestMethod.DELETE, produces = "application/json") + @Transactional + public ResponseEntity<Void> deletePetType(@PathVariable("petTypeId") int petTypeId) { + PetType petType = this.clinicService.findPetTypeById(petTypeId); + if (petType == null) { + return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); + } + this.clinicService.deletePetType(petType); + return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java index 6680e72952f846e05c01d26f9dcea4fb3c152543..5d89e1eb323b760ce612242c68f1b18cc9981fa3 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java @@ -16,32 +16,25 @@ package org.springframework.samples.petclinic.rest; -import java.util.ArrayList; -import java.util.Collection; - -import javax.transaction.Transactional; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.SpecialtyDto; +import org.springframework.samples.petclinic.mapper.SpecialtyMapper; import org.springframework.samples.petclinic.model.Specialty; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; +import javax.transaction.Transactional; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Collection; + /** * @author Vitaliy Fedoriv - * */ @RestController @@ -49,74 +42,81 @@ import org.springframework.web.util.UriComponentsBuilder; @RequestMapping("api/specialties") public class SpecialtyRestController { - @Autowired - private ClinicService clinicService; + private final ClinicService clinicService; + + private final SpecialtyMapper specialtyMapper; + + public SpecialtyRestController(ClinicService clinicService, SpecialtyMapper specialtyMapper) { + this.clinicService = clinicService; + this.specialtyMapper = specialtyMapper; + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<Specialty>> getAllSpecialtys(){ - Collection<Specialty> specialties = new ArrayList<Specialty>(); - specialties.addAll(this.clinicService.findAllSpecialties()); - if (specialties.isEmpty()){ - return new ResponseEntity<Collection<Specialty>>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Collection<Specialty>>(specialties, HttpStatus.OK); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<Collection<SpecialtyDto>> getAllSpecialtys() { + Collection<SpecialtyDto> specialties = new ArrayList<SpecialtyDto>(); + specialties.addAll(specialtyMapper.toSpecialtyDtos(this.clinicService.findAllSpecialties())); + if (specialties.isEmpty()) { + return new ResponseEntity<Collection<SpecialtyDto>>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<Collection<SpecialtyDto>>(specialties, HttpStatus.OK); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{specialtyId}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Specialty> getSpecialty(@PathVariable("specialtyId") int specialtyId){ - Specialty specialty = this.clinicService.findSpecialtyById(specialtyId); - if(specialty == null){ - return new ResponseEntity<Specialty>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Specialty>(specialty, HttpStatus.OK); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{specialtyId}", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<SpecialtyDto> getSpecialty(@PathVariable("specialtyId") int specialtyId) { + Specialty specialty = this.clinicService.findSpecialtyById(specialtyId); + if (specialty == null) { + return new ResponseEntity<SpecialtyDto>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<SpecialtyDto>(specialtyMapper.toSpecialtyDto(specialty), HttpStatus.OK); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<Specialty> addSpecialty(@RequestBody @Valid Specialty specialty, BindingResult bindingResult, UriComponentsBuilder ucBuilder){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (specialty == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<Specialty>(headers, HttpStatus.BAD_REQUEST); - } - this.clinicService.saveSpecialty(specialty); - headers.setLocation(ucBuilder.path("/api/specialtys/{id}").buildAndExpand(specialty.getId()).toUri()); - return new ResponseEntity<Specialty>(specialty, headers, HttpStatus.CREATED); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") + public ResponseEntity<SpecialtyDto> addSpecialty(@RequestBody @Valid SpecialtyDto specialtyDto, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (specialtyDto == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<SpecialtyDto>(headers, HttpStatus.BAD_REQUEST); + } + Specialty specialty = specialtyMapper.toSpecialty(specialtyDto); + this.clinicService.saveSpecialty(specialty); + headers.setLocation(ucBuilder.path("/api/specialtys/{id}").buildAndExpand(specialty.getId()).toUri()); + return new ResponseEntity<SpecialtyDto>(specialtyMapper.toSpecialtyDto(specialty), headers, HttpStatus.CREATED); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{specialtyId}", method = RequestMethod.PUT, produces = "application/json") - public ResponseEntity<Specialty> updateSpecialty(@PathVariable("specialtyId") int specialtyId, @RequestBody @Valid Specialty specialty, BindingResult bindingResult){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (specialty == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<Specialty>(headers, HttpStatus.BAD_REQUEST); - } - Specialty currentSpecialty = this.clinicService.findSpecialtyById(specialtyId); - if(currentSpecialty == null){ - return new ResponseEntity<Specialty>(HttpStatus.NOT_FOUND); - } - currentSpecialty.setName(specialty.getName()); - this.clinicService.saveSpecialty(currentSpecialty); - return new ResponseEntity<Specialty>(currentSpecialty, HttpStatus.NO_CONTENT); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{specialtyId}", method = RequestMethod.PUT, produces = "application/json") + public ResponseEntity<SpecialtyDto> updateSpecialty(@PathVariable("specialtyId") int specialtyId, @RequestBody @Valid SpecialtyDto specialtyDto, BindingResult bindingResult) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (specialtyDto == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<SpecialtyDto>(headers, HttpStatus.BAD_REQUEST); + } + Specialty currentSpecialty = this.clinicService.findSpecialtyById(specialtyId); + if (currentSpecialty == null) { + return new ResponseEntity<SpecialtyDto>(HttpStatus.NOT_FOUND); + } + currentSpecialty.setName(specialtyDto.getName()); + this.clinicService.saveSpecialty(currentSpecialty); + return new ResponseEntity<SpecialtyDto>(specialtyMapper.toSpecialtyDto(currentSpecialty), HttpStatus.NO_CONTENT); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{specialtyId}", method = RequestMethod.DELETE, produces = "application/json") - @Transactional - public ResponseEntity<Void> deleteSpecialty(@PathVariable("specialtyId") int specialtyId){ - Specialty specialty = this.clinicService.findSpecialtyById(specialtyId); - if(specialty == null){ - return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); - } - this.clinicService.deleteSpecialty(specialty); - return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{specialtyId}", method = RequestMethod.DELETE, produces = "application/json") + @Transactional + public ResponseEntity<Void> deleteSpecialty(@PathVariable("specialtyId") int specialtyId) { + Specialty specialty = this.clinicService.findSpecialtyById(specialtyId); + if (specialty == null) { + return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteSpecialty(specialty); + return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java index 47ad14b73ab32fd9469f79d59073421a1717934a..915edd60ca2c429083e12523bf0b9e1d6f031094 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java @@ -16,43 +16,45 @@ package org.springframework.samples.petclinic.rest; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.UserDto; +import org.springframework.samples.petclinic.mapper.UserMapper; import org.springframework.samples.petclinic.model.User; import org.springframework.samples.petclinic.service.UserService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; @RestController @CrossOrigin(exposedHeaders = "errors, content-type") @RequestMapping("api/users") public class UserRestController { - @Autowired - private UserService userService; + private final UserService userService; + private final UserMapper userMapper; + + public UserRestController(UserService userService, UserMapper userMapper) { + this.userService = userService; + this.userMapper = userMapper; + } + @PreAuthorize( "hasRole(@roles.ADMIN)" ) @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<User> addOwner(@RequestBody @Valid User user, BindingResult bindingResult) throws Exception { + public ResponseEntity<UserDto> addOwner(@RequestBody @Valid UserDto userDto, BindingResult bindingResult) throws Exception { BindingErrorsResponse errors = new BindingErrorsResponse(); HttpHeaders headers = new HttpHeaders(); - if (bindingResult.hasErrors() || (user == null)) { + if (bindingResult.hasErrors() || (userDto == null)) { errors.addAllErrors(bindingResult); headers.add("errors", errors.toJSON()); - return new ResponseEntity<User>(user, headers, HttpStatus.BAD_REQUEST); + return new ResponseEntity<UserDto>(userDto, headers, HttpStatus.BAD_REQUEST); } - + User user = userMapper.toUser(userDto); this.userService.saveUser(user); - return new ResponseEntity<User>(user, headers, HttpStatus.CREATED); + return new ResponseEntity<UserDto>(userMapper.toUserDto(user), headers, HttpStatus.CREATED); } } diff --git a/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java index 7570173a9118b01e5faa93690fffc9599762bf19..6469062b5552a515d29d56ee5b09091103cec847 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java @@ -15,33 +15,27 @@ */ package org.springframework.samples.petclinic.rest; -import java.util.ArrayList; -import java.util.Collection; - -import javax.transaction.Transactional; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.VetDto; +import org.springframework.samples.petclinic.mapper.SpecialtyMapper; +import org.springframework.samples.petclinic.mapper.VetMapper; import org.springframework.samples.petclinic.model.Specialty; import org.springframework.samples.petclinic.model.Vet; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; +import javax.transaction.Transactional; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Collection; + /** * @author Vitaliy Fedoriv - * */ @RestController @@ -49,81 +43,88 @@ import org.springframework.web.util.UriComponentsBuilder; @RequestMapping("api/vets") public class VetRestController { - @Autowired - private ClinicService clinicService; + private final ClinicService clinicService; + private final VetMapper vetMapper; + private final SpecialtyMapper specialtyMapper; - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<Vet>> getAllVets(){ - Collection<Vet> vets = new ArrayList<Vet>(); - vets.addAll(this.clinicService.findAllVets()); - if (vets.isEmpty()){ - return new ResponseEntity<Collection<Vet>>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Collection<Vet>>(vets, HttpStatus.OK); - } + public VetRestController(ClinicService clinicService, VetMapper vetMapper, SpecialtyMapper specialtyMapper) { + this.clinicService = clinicService; + this.vetMapper = vetMapper; + this.specialtyMapper = specialtyMapper; + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{vetId}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Vet> getVet(@PathVariable("vetId") int vetId){ - Vet vet = this.clinicService.findVetById(vetId); - if(vet == null){ - return new ResponseEntity<Vet>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Vet>(vet, HttpStatus.OK); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<Collection<VetDto>> getAllVets() { + Collection<VetDto> vets = new ArrayList<VetDto>(); + vets.addAll(vetMapper.toVetDtos(this.clinicService.findAllVets())); + if (vets.isEmpty()) { + return new ResponseEntity<Collection<VetDto>>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<Collection<VetDto>>(vets, HttpStatus.OK); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<Vet> addVet(@RequestBody @Valid Vet vet, BindingResult bindingResult, UriComponentsBuilder ucBuilder){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (vet == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<Vet>(headers, HttpStatus.BAD_REQUEST); - } - this.clinicService.saveVet(vet); - headers.setLocation(ucBuilder.path("/api/vets/{id}").buildAndExpand(vet.getId()).toUri()); - return new ResponseEntity<Vet>(vet, headers, HttpStatus.CREATED); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{vetId}", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<VetDto> getVet(@PathVariable("vetId") int vetId) { + Vet vet = this.clinicService.findVetById(vetId); + if (vet == null) { + return new ResponseEntity<VetDto>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<VetDto>(vetMapper.toVetDto(vet), HttpStatus.OK); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{vetId}", method = RequestMethod.PUT, produces = "application/json") - public ResponseEntity<Vet> updateVet(@PathVariable("vetId") int vetId, @RequestBody @Valid Vet vet, BindingResult bindingResult){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (vet == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<Vet>(headers, HttpStatus.BAD_REQUEST); - } - Vet currentVet = this.clinicService.findVetById(vetId); - if(currentVet == null){ - return new ResponseEntity<Vet>(HttpStatus.NOT_FOUND); - } - currentVet.setFirstName(vet.getFirstName()); - currentVet.setLastName(vet.getLastName()); - currentVet.clearSpecialties(); - for(Specialty spec : vet.getSpecialties()) { - currentVet.addSpecialty(spec); - } - this.clinicService.saveVet(currentVet); - return new ResponseEntity<Vet>(currentVet, HttpStatus.NO_CONTENT); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") + public ResponseEntity<VetDto> addVet(@RequestBody @Valid VetDto vetDto, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (vetDto == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<VetDto>(headers, HttpStatus.BAD_REQUEST); + } + Vet vet = vetMapper.toVet(vetDto); + this.clinicService.saveVet(vet); + headers.setLocation(ucBuilder.path("/api/vets/{id}").buildAndExpand(vet.getId()).toUri()); + return new ResponseEntity<VetDto>(vetMapper.toVetDto(vet), headers, HttpStatus.CREATED); + } - @PreAuthorize( "hasRole(@roles.VET_ADMIN)" ) - @RequestMapping(value = "/{vetId}", method = RequestMethod.DELETE, produces = "application/json") - @Transactional - public ResponseEntity<Void> deleteVet(@PathVariable("vetId") int vetId){ - Vet vet = this.clinicService.findVetById(vetId); - if(vet == null){ - return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); - } - this.clinicService.deleteVet(vet); - return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); - } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{vetId}", method = RequestMethod.PUT, produces = "application/json") + public ResponseEntity<VetDto> updateVet(@PathVariable("vetId") int vetId, @RequestBody @Valid VetDto vetDto, BindingResult bindingResult) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (vetDto == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<VetDto>(headers, HttpStatus.BAD_REQUEST); + } + Vet currentVet = this.clinicService.findVetById(vetId); + if (currentVet == null) { + return new ResponseEntity<VetDto>(HttpStatus.NOT_FOUND); + } + currentVet.setFirstName(vetDto.getFirstName()); + currentVet.setLastName(vetDto.getLastName()); + currentVet.clearSpecialties(); + for (Specialty spec : specialtyMapper.toSpecialtys(vetDto.getSpecialties())) { + currentVet.addSpecialty(spec); + } + this.clinicService.saveVet(currentVet); + return new ResponseEntity<VetDto>(vetMapper.toVetDto(currentVet), HttpStatus.NO_CONTENT); + } + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @RequestMapping(value = "/{vetId}", method = RequestMethod.DELETE, produces = "application/json") + @Transactional + public ResponseEntity<Void> deleteVet(@PathVariable("vetId") int vetId) { + Vet vet = this.clinicService.findVetById(vetId); + if (vet == null) { + return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteVet(vet); + return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java index 92fe1531a39b34b292a81b9d5a0b11cbd921efc2..ee92cf38fa98366ce519813067f4f636c6c68f2a 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java @@ -16,32 +16,25 @@ package org.springframework.samples.petclinic.rest; -import java.util.ArrayList; -import java.util.Collection; - -import javax.transaction.Transactional; -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.dto.VisitDto; +import org.springframework.samples.petclinic.mapper.VisitMapper; import org.springframework.samples.petclinic.model.Visit; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; +import javax.transaction.Transactional; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Collection; + /** * @author Vitaliy Fedoriv - * */ @RestController @@ -49,76 +42,85 @@ import org.springframework.web.util.UriComponentsBuilder; @RequestMapping("api/visits") public class VisitRestController { - @Autowired - private ClinicService clinicService; - - @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Collection<Visit>> getAllVisits(){ - Collection<Visit> visits = new ArrayList<Visit>(); - visits.addAll(this.clinicService.findAllVisits()); - if (visits.isEmpty()){ - return new ResponseEntity<Collection<Visit>>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Collection<Visit>>(visits, HttpStatus.OK); - } - - @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" ) - @RequestMapping(value = "/{visitId}", method = RequestMethod.GET, produces = "application/json") - public ResponseEntity<Visit> getVisit(@PathVariable("visitId") int visitId){ - Visit visit = this.clinicService.findVisitById(visitId); - if(visit == null){ - return new ResponseEntity<Visit>(HttpStatus.NOT_FOUND); - } - return new ResponseEntity<Visit>(visit, HttpStatus.OK); - } - - @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" ) - @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<Visit> addVisit(@RequestBody @Valid Visit visit, BindingResult bindingResult, UriComponentsBuilder ucBuilder){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (visit == null) || (visit.getPet() == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<Visit>(headers, HttpStatus.BAD_REQUEST); - } - this.clinicService.saveVisit(visit); - headers.setLocation(ucBuilder.path("/api/visits/{id}").buildAndExpand(visit.getId()).toUri()); - return new ResponseEntity<Visit>(visit, headers, HttpStatus.CREATED); - } - - @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" ) - @RequestMapping(value = "/{visitId}", method = RequestMethod.PUT, produces = "application/json") - public ResponseEntity<Visit> updateVisit(@PathVariable("visitId") int visitId, @RequestBody @Valid Visit visit, BindingResult bindingResult){ - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if(bindingResult.hasErrors() || (visit == null) || (visit.getPet() == null)){ - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<Visit>(headers, HttpStatus.BAD_REQUEST); - } - Visit currentVisit = this.clinicService.findVisitById(visitId); - if(currentVisit == null){ - return new ResponseEntity<Visit>(HttpStatus.NOT_FOUND); - } - currentVisit.setDate(visit.getDate()); - currentVisit.setDescription(visit.getDescription()); - currentVisit.setPet(visit.getPet()); - this.clinicService.saveVisit(currentVisit); - return new ResponseEntity<Visit>(currentVisit, HttpStatus.NO_CONTENT); - } - - @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" ) - @RequestMapping(value = "/{visitId}", method = RequestMethod.DELETE, produces = "application/json") - @Transactional - public ResponseEntity<Void> deleteVisit(@PathVariable("visitId") int visitId){ - Visit visit = this.clinicService.findVisitById(visitId); - if(visit == null){ - return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); - } - this.clinicService.deleteVisit(visit); - return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); - } + private final ClinicService clinicService; + + private final VisitMapper visitMapper; + + public VisitRestController(ClinicService clinicService, VisitMapper visitMapper) { + this.clinicService = clinicService; + this.visitMapper = visitMapper; + } + + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<Collection<VisitDto>> getAllVisitDtos() { + Collection<Visit> visits = new ArrayList<>(); + + visits.addAll(this.clinicService.findAllVisits()); + if (visits.isEmpty()) { + return new ResponseEntity<Collection<VisitDto>>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<Collection<VisitDto>>(visitMapper.toVisitsDto(visits), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @RequestMapping(value = "/{visitId}", method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<VisitDto> getVisitDto(@PathVariable("visitId") int visitId) { + Visit visit = this.clinicService.findVisitById(visitId); + if (visit == null) { + return new ResponseEntity<VisitDto>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<VisitDto>(visitMapper.toVisitDto(visit), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") + public ResponseEntity<VisitDto> addVisit(@RequestBody @Valid VisitDto visitDto, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (visitDto == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<VisitDto>(headers, HttpStatus.BAD_REQUEST); + } + Visit visit = visitMapper.toVisit(visitDto); + this.clinicService.saveVisit(visit); + visitDto = visitMapper.toVisitDto(visit); + headers.setLocation(ucBuilder.path("/api/visits/{id}").buildAndExpand(visit.getId()).toUri()); + return new ResponseEntity<>(visitDto, headers, HttpStatus.CREATED); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @RequestMapping(value = "/{visitId}", method = RequestMethod.PUT, produces = "application/json") + public ResponseEntity<VisitDto> updateVisit(@PathVariable("visitId") int visitId, @RequestBody @Valid VisitDto visitDto, BindingResult bindingResult) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors() || (visitDto == null)) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); + } + Visit currentVisit = this.clinicService.findVisitById(visitId); + if (currentVisit == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentVisit.setDate(visitDto.getDate()); + currentVisit.setDescription(visitDto.getDescription()); + this.clinicService.saveVisit(currentVisit); + return new ResponseEntity<>(visitMapper.toVisitDto(currentVisit), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @RequestMapping(value = "/{visitId}", method = RequestMethod.DELETE, produces = "application/json") + @Transactional + public ResponseEntity<Void> deleteVisit(@PathVariable("visitId") int visitId) { + Visit visit = this.clinicService.findVisitById(visitId); + if (visit == null) { + return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteVisit(visit); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/util/ApplicationSwaggerConfig.java b/src/main/java/org/springframework/samples/petclinic/util/ApplicationSwaggerConfig.java old mode 100644 new mode 100755 diff --git a/src/main/resources/api-docs.yml b/src/main/resources/api-docs.yml new file mode 100755 index 0000000000000000000000000000000000000000..86063c6beaa536dbcc51ea0aacf089bbad9f42a1 --- /dev/null +++ b/src/main/resources/api-docs.yml @@ -0,0 +1,913 @@ +openapi: 3.0.1 +info: + title: Spring PetClinic + description: Spring PetClinic Sample Application. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0 + version: '1.0' +servers: + - url: http://localhost:8080/api +tags: + - name: failing + description: Endpoint which always returns an error. + - name: owner + description: Endpoints related to pet owners. + - name: pet + description: Endpoints related to pets. + - name: vet + description: Endpoints related to vets. + - name: visit + description: Endpoints related to vet visits. +paths: + /oops: + get: + tags: + - failing + operationId: failingRequest + summary: Always fails + description: Produces sample error response. + parameters: + - name: If-None-Match + in: header + description: A list of ETags of the responses the client has cached. + schema: + type: string + responses: + 200: + description: Never returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + text/plain: + schema: + type: string + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owner: + post: + tags: + - owner + operationId: addOwner + summary: Adds a pet owner + description: Records the details of a new pet owner. + requestBody: + description: The pet owner + content: + application/json: + schema: + $ref: '#/components/schemas/OwnerFields' + required: true + responses: + 201: + description: The pet owner was sucessfully added. + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + get: + tags: + - owner + operationId: listOwners + summary: Lists pet owners + description: Returns an array of pet owners. + parameters: + - name: lastName + in: query + description: Last name. + required: false + schema: + type: string + example: Davis + - name: If-None-Match + in: header + description: A list of ETags of the responses the client has cached. + schema: + type: string + responses: + 200: + description: Owner details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Owner' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owner/{ownerId}: + get: + tags: + - owner + operationId: getOwner + summary: Get a pet owner by ID + description: Returns the pet owner or a 404 error. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: If-None-Match + in: header + description: A list of ETags of the responses the client has cached. + schema: + type: string + responses: + 200: + description: Owner details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - owner + operationId: updateOwner + summary: Update a pet owner's details + description: Updates the pet owner record with the specified details. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet owner details to use for the update. + content: + application/json: + schema: + $ref: '#/components/schemas/OwnerFields' + required: true + responses: + 200: + description: Update successful. + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owner/{ownerId}/pet: + post: + tags: + - pet + operationId: addPet + summary: Adds a pet + description: Records the details of a new pet. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The details of the new pet. + content: + application/json: + schema: + $ref: '#/components/schemas/PetFields' + required: true + responses: + 201: + description: The pet was sucessfully added. + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owner/{ownerId}/pet/{petId}: + get: + tags: + - pet + operationId: getPet + summary: Get a pet by ID + description: Returns the pet or a 404 error. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: If-None-Match + in: header + description: A list of ETags of the responses the client has cached. + schema: + type: string + responses: + 200: + description: Pet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - pet + operationId: updatePet + summary: Update a pet's details + description: Updates the pet record with the specified details. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet details to use for the update. + content: + application/json: + schema: + $ref: '#/components/schemas/PetFields' + required: true + responses: + 204: + description: Update successful. + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found for this owner. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owner/{ownerId}/pet/{petId}/visit: + post: + tags: + - visit + operationId: addVisit + summary: Adds a vet visit + description: Records the details of a new vet visit. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The details of the new vet visit. + content: + application/json: + schema: + $ref: '#/components/schemas/VisitFields' + required: true + responses: + 201: + description: The vet visit was sucessfully added. + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found for this owner. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /pet-type: + get: + tags: + - pet + operationId: listPetTypes + summary: Lists pet types + description: Returns an array of pet types. + parameters: + - name: If-None-Match + in: header + description: A list of ETags of the responses the client has cached. + schema: + type: string + responses: + 200: + description: Pet types found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/PetType' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /vet: + get: + tags: + - vet + operationId: listVets + summary: Lists vets + description: Returns an array of vets. + parameters: + - name: If-None-Match + in: header + description: A list of ETags of the responses the client has cached. + schema: + type: string + responses: + 200: + description: Vets found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Vet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' +components: + schemas: + RestError: + title: REST Error + description: The schema for all error responses. + type: object + properties: + status: + title: Status + description: The HTTP status code. + type: integer + format: int32 + example: 400 + readOnly: true + error: + title: Error + description: The short error message. + type: string + example: Bad Request + readOnly: true + path: + title: Path + description: The path of the URL for this request. + type: string + format: uri + example: '/api/owner' + readOnly: true + timestamp: + title: Timestamp + description: The time the error occured. + type: string + format: date-time + example: '2019-08-21T21:41:46.158+0000' + readOnly: true + message: + title: Message + description: The long error message. + type: string + example: 'Request failed schema validation' + readOnly: true + schemaValidationErrors: + title: Schema validation errors + description: Validation errors against the OpenAPI schema. + type: array + items: + $ref: '#/components/schemas/ValidationMessage' + trace: + title: Trace + description: The stacktrace for this error. + type: string + example: 'com.atlassian.oai.validator.springmvc.InvalidRequestException: ...' + readOnly: true + required: + - status + - error + - path + - timestamp + - message + - schemaValidationErrors + ValidationMessage: + title: Validation message + description: Messages describing a validation error. + type: object + properties: + message: + title: Message + description: The valiation message. + type: string + example: "[Path '/lastName'] Instance type (null) does not match any allowed primitive type (allowed: [\"string\"])" + readOnly: true + required: + - message + additionalProperties: true + Specialty: + title: Specialty + description: Fields of specialty of vets. + type: object + properties: + id: + title: ID + description: The ID of the specialty. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + name: + title: Name + description: The name of the specialty. + type: string + maxLength: 80 + minLength: 1 + example: radiology + required: + - id + - name + OwnerFields: + title: Owner fields + description: Editable fields of a pet owner. + type: object + properties: + firstName: + title: First name + description: The first name of the pet owner. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: George + lastName: + title: Last name + description: The last name of the pet owner. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: Franklin + address: + title: Address + description: The postal address of the pet owner. + type: string + minLength: 1 + maxLength: 255 + example: '110 W. Liberty St.' + city: + title: City + description: The city of the pet owner. + type: string + minLength: 1 + maxLength: 80 + example: Madison + telephone: + title: Telephone number + description: The telephone number of the pet owner. + type: string + minLength: 1 + maxLength: 20 + pattern: '^[0-9]*$' + example: '6085551023' + required: + - firstName + - lastName + - address + - city + - telephone + Owner: + title: Owner + description: A pet owner. + allOf: + - $ref: '#/components/schemas/OwnerFields' + - type: object + properties: + id: + title: ID + description: The ID of the pet owner. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + pets: + title: Pets + description: The pets owned by this individual including any booked vet visits. + type: array + items: + $ref: '#/components/schemas/Pet' + readOnly: true + required: + - pets + PetFields: + title: Pet fields + description: Editable fields of a pet. + type: object + properties: + name: + title: Name + description: The name of the pet. + type: string + maxLength: 30 + example: Leo + birthDate: + title: Birth date + description: The date of birth of the pet. + type: string + format: date + example: '2010-09-07' + typeId: + title: Type + description: The type of the pet. + type: integer + format: int32 + example: 1 + required: + - name + Pet: + title: Pet + description: A pet. + allOf: + - $ref: '#/components/schemas/PetFields' + - type: object + properties: + id: + title: ID + description: The ID of the pet. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + type: + $ref: '#/components/schemas/PetType' + visits: + title: Visits + description: Vet visit bookings for this pet. + type: array + items: + $ref: '#/components/schemas/Visit' + readOnly: true + required: + - id + - type + - visits + Vet: + title: Vet + description: A veterinarian. + type: object + properties: + id: + title: ID + description: The ID of the vet. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + firstName: + title: First name + description: The first name of the vet. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: 'James' + lastName: + title: Last name + description: The last name of the vet. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: 'Carter' + specialties: + title: Specialties + description: The specialties of the vet. + type: array + items: + $ref: '#/components/schemas/Specialty' + required: + - id + - firstName + - lastName + - specialties + VisitFields: + title: Visit fields + description: Editable fields of a vet visit. + type: object + properties: + date: + title: Date + description: The date of the visit. + type: string + format: date + example: '2013-01-01' + description: + title: Description + description: The description for the visit. + type: string + minLength: 1 + maxLength: 255 + example: 'rabies shot' + required: + - description + Visit: + title: Visit + description: A booking for a vet visit. + allOf: + - $ref: '#/components/schemas/VisitFields' + - type: object + properties: + id: + title: ID + description: The ID of the visit. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + required: + - id + PetType: + title: Pet type + description: A pet type. + type: object + properties: + id: + title: ID + description: The ID of the pet type. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + name: + title: Name + description: The name of the pet type. + type: string + maxLength: 80 + minLength: 1 + example: cat + required: + - id + User: + title: User + description: An user. + type: object + properties: + username: + title: username + description: The username + type: string + maxLength: 80 + minLength: 1 + example: john.doe + password: + title: Password + description: The password + type: string + maxLength: 80 + minLength: 1 + example: 1234 + enabled: + title: enabled + description: Indicates if the user is enabled + type: boolean + example: true + roles: + title: Roles + description: The roles of an user + type: array + items: + $ref: '#/components/schemas/Role' + required: + - username + Role: + title: Role + description: A role. + type: object + properties: + name: + title: name + description: The role's name + type: string + maxLength: 80 + minLength: 1 + example: admin + required: + - name diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index bbc8958923e241e2f7e2c57813db53bb8ed0d937..e3669c9bcd67ff7000abec1fdf3340ff57c413a9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -34,3 +34,8 @@ logging.level.org.springframework=INFO # enable the desired authentication type # by default the authentication is disabled petclinic.security.enable=false + +# ------------------------------------------------ +# Spring doc configuration +springdoc.api-docs.enabled=true +springdoc.writer-with-default-pretty-printer= true diff --git a/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java index 57147a55211a1a2db7e7bd96d09addecc32a411a..cc59b20e84f78bbeb57f82937ae59b574453fdf5 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java @@ -16,17 +16,7 @@ package org.springframework.samples.petclinic.rest; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,12 +24,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.samples.petclinic.dto.OwnerDto; +import org.springframework.samples.petclinic.dto.PetDto; +import org.springframework.samples.petclinic.dto.PetTypeDto; +import org.springframework.samples.petclinic.dto.VisitDto; +import org.springframework.samples.petclinic.mapper.OwnerMapper; import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -47,7 +39,13 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** @@ -57,94 +55,95 @@ import com.fasterxml.jackson.databind.ObjectMapper; */ @SpringBootTest @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes=ApplicationTestConfig.class) +@ContextConfiguration(classes = ApplicationTestConfig.class) @WebAppConfiguration public class OwnerRestControllerTests { @Autowired private OwnerRestController ownerRestController; + @Autowired + OwnerMapper ownerMapper; + @MockBean private ClinicService clinicService; private MockMvc mockMvc; - private List<Owner> owners; + private List<OwnerDto> owners; @Before - public void initOwners(){ - this.mockMvc = MockMvcBuilders.standaloneSetup(ownerRestController) - .setControllerAdvice(new ExceptionControllerAdvice()) - .build(); - owners = new ArrayList<Owner>(); - - Owner ownerWithPet = new Owner(); - ownerWithPet.setId(1); - ownerWithPet.setFirstName("George"); - ownerWithPet.setLastName("Franklin"); - ownerWithPet.setAddress("110 W. Liberty St."); - ownerWithPet.setCity("Madison"); - ownerWithPet.setTelephone("6085551023"); - ownerWithPet.addPet(getTestPetWithIdAndName(ownerWithPet, 1, "Rosy")); - owners.add(ownerWithPet); - - Owner owner = new Owner(); - owner.setId(2); - owner.setFirstName("Betty"); - owner.setLastName("Davis"); - owner.setAddress("638 Cardinal Ave."); - owner.setCity("Sun Prairie"); - owner.setTelephone("6085551749"); - owners.add(owner); - - owner = new Owner(); - owner.setId(3); - owner.setFirstName("Eduardo"); - owner.setLastName("Rodriquez"); - owner.setAddress("2693 Commerce St."); - owner.setCity("McFarland"); - owner.setTelephone("6085558763"); - owners.add(owner); - - owner = new Owner(); - owner.setId(4); - owner.setFirstName("Harold"); - owner.setLastName("Davis"); - owner.setAddress("563 Friendly St."); - owner.setCity("Windsor"); - owner.setTelephone("6085553198"); - owners.add(owner); + public void initOwners() { + this.mockMvc = MockMvcBuilders.standaloneSetup(ownerRestController) + .setControllerAdvice(new ExceptionControllerAdvice()) + .build(); + owners = new ArrayList<OwnerDto>(); + + OwnerDto ownerWithPet = new OwnerDto(); + ownerWithPet.setId(1); + ownerWithPet.setFirstName("George"); + ownerWithPet.setLastName("Franklin"); + ownerWithPet.setAddress("110 W. Liberty St."); + ownerWithPet.setCity("Madison"); + ownerWithPet.setTelephone("6085551023"); + ownerWithPet.addPetsItem(getTestPetWithIdAndName(ownerWithPet, 1, "Rosy")); + owners.add(ownerWithPet); + + OwnerDto owner = new OwnerDto(); + owner.setId(2); + owner.setFirstName("Betty"); + owner.setLastName("Davis"); + owner.setAddress("638 Cardinal Ave."); + owner.setCity("Sun Prairie"); + owner.setTelephone("6085551749"); + owners.add(owner); + + owner = new OwnerDto(); + owner.setId(3); + owner.setFirstName("Eduardo"); + owner.setLastName("Rodriquez"); + owner.setAddress("2693 Commerce St."); + owner.setCity("McFarland"); + owner.setTelephone("6085558763"); + owners.add(owner); + + owner = new OwnerDto(); + owner.setId(4); + owner.setFirstName("Harold"); + owner.setLastName("Davis"); + owner.setAddress("563 Friendly St."); + owner.setCity("Windsor"); + owner.setTelephone("6085553198"); + owners.add(owner); } - private Pet getTestPetWithIdAndName(final Owner owner, final int id, final String name) { - PetType petType = new PetType(); + private PetDto getTestPetWithIdAndName(final OwnerDto owner, final int id, final String name) { + PetTypeDto petType = new PetTypeDto(); petType.setId(2); petType.setName("dog"); - Pet pet = new Pet(); + PetDto pet = new PetDto(); pet.setId(id); pet.setName(name); pet.setBirthDate(new Date()); - pet.setOwner(owner); pet.setType(petType); - pet.addVisit(getTestVisitForPet(pet, 1)); + pet.addVisitsItem(getTestVisitForPet(pet, 1)); return pet; } - private Visit getTestVisitForPet(final Pet pet, final int id) { - Visit visit = new Visit(); + private VisitDto getTestVisitForPet(final PetDto pet, final int id) { + VisitDto visit = new VisitDto(); visit.setId(id); - visit.setPet(pet); visit.setDate(new Date()); visit.setDescription("test" + id); return visit; } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testGetOwnerSuccess() throws Exception { - given(this.clinicService.findOwnerById(1)).willReturn(owners.get(0)); + given(this.clinicService.findOwnerById(1)).willReturn(ownerMapper.toOwner(owners.get(0))); this.mockMvc.perform(get("/api/owners/1") - .accept(MediaType.APPLICATION_JSON_VALUE)) + .accept(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.id").value(1)) @@ -152,22 +151,22 @@ public class OwnerRestControllerTests { } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testGetOwnerNotFound() throws Exception { - given(this.clinicService.findOwnerById(-1)).willReturn(null); + given(this.clinicService.findOwnerById(-1)).willReturn(null); this.mockMvc.perform(get("/api/owners/-1") - .accept(MediaType.APPLICATION_JSON)) + .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testGetOwnersListSuccess() throws Exception { - owners.remove(0); - owners.remove(1); - given(this.clinicService.findOwnerByLastName("Davis")).willReturn(owners); + owners.remove(0); + owners.remove(1); + given(this.clinicService.findOwnerByLastName("Davis")).willReturn(ownerMapper.toOwners(owners)); this.mockMvc.perform(get("/api/owners/*/lastname/Davis") - .accept(MediaType.APPLICATION_JSON)) + .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.[0].id").value(2)) @@ -177,23 +176,23 @@ public class OwnerRestControllerTests { } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testGetOwnersListNotFound() throws Exception { - owners.clear(); - given(this.clinicService.findOwnerByLastName("0")).willReturn(owners); + owners.clear(); + given(this.clinicService.findOwnerByLastName("0")).willReturn(ownerMapper.toOwners(owners)); this.mockMvc.perform(get("/api/owners/?lastName=0") - .accept(MediaType.APPLICATION_JSON)) + .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testGetAllOwnersSuccess() throws Exception { - owners.remove(0); - owners.remove(1); - given(this.clinicService.findAllOwners()).willReturn(owners); + owners.remove(0); + owners.remove(1); + given(this.clinicService.findAllOwners()).willReturn(ownerMapper.toOwners(owners)); this.mockMvc.perform(get("/api/owners/") - .accept(MediaType.APPLICATION_JSON)) + .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.[0].id").value(2)) @@ -203,164 +202,167 @@ public class OwnerRestControllerTests { } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testGetAllOwnersNotFound() throws Exception { - owners.clear(); - given(this.clinicService.findAllOwners()).willReturn(owners); + owners.clear(); + given(this.clinicService.findAllOwners()).willReturn(ownerMapper.toOwners(owners)); this.mockMvc.perform(get("/api/owners/") - .accept(MediaType.APPLICATION_JSON)) + .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testCreateOwnerSuccess() throws Exception { - Owner newOwner = owners.get(0); - newOwner.setId(null); - ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(newOwner); - this.mockMvc.perform(post("/api/owners/") - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isCreated()); + OwnerDto newOwnerDto = owners.get(0); + newOwnerDto.setId(null); + ObjectMapper mapper = new ObjectMapper(); + String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto); + this.mockMvc.perform(post("/api/owners/") + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testCreateOwnerErrorIdSpecified() throws Exception { - Owner newOwner = owners.get(0); - newOwner.setId(999); + OwnerDto newOwnerDto = owners.get(0); + newOwnerDto.setId(999); ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(newOwner); + String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto); this.mockMvc.perform(post("/api/owners/") - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()) .andExpect(header().string("errors", "[{\"objectName\":\"body\",\"fieldName\":\"id\",\"fieldValue\":\"999\",\"errorMessage\":\"must not be specified\"}]")); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testCreateOwnerError() throws Exception { - Owner newOwner = owners.get(0); - newOwner.setId(null); - newOwner.setFirstName(null); - ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(newOwner); - this.mockMvc.perform(post("/api/owners/") - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isBadRequest()); - } + OwnerDto newOwnerDto = owners.get(0); + newOwnerDto.setId(null); + newOwnerDto.setFirstName(null); + ObjectMapper mapper = new ObjectMapper(); + String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto); + this.mockMvc.perform(post("/api/owners/") + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()); + } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testUpdateOwnerSuccess() throws Exception { - given(this.clinicService.findOwnerById(1)).willReturn(owners.get(0)); + given(this.clinicService.findOwnerById(1)).willReturn(ownerMapper.toOwner(owners.get(0))); int ownerId = owners.get(0).getId(); - Owner updatedOwner = new Owner(); + OwnerDto updatedOwnerDto = new OwnerDto(); // body.id = ownerId which is used in url path - updatedOwner.setId(ownerId); - updatedOwner.setFirstName("George I"); - updatedOwner.setLastName("Franklin"); - updatedOwner.setAddress("110 W. Liberty St."); - updatedOwner.setCity("Madison"); - updatedOwner.setTelephone("6085551023"); + updatedOwnerDto.setId(ownerId); + updatedOwnerDto.setFirstName("GeorgeI"); + updatedOwnerDto.setLastName("Franklin"); + updatedOwnerDto.setAddress("110 W. Liberty St."); + updatedOwnerDto.setCity("Madison"); + updatedOwnerDto.setTelephone("6085551023"); ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(updatedOwner); + String newOwnerAsJSON = mapper.writeValueAsString(updatedOwnerDto); this.mockMvc.perform(put("/api/owners/" + ownerId) - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType("application/json")) .andExpect(status().isNoContent()); this.mockMvc.perform(get("/api/owners/" + ownerId) - .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE)) + .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.id").value(ownerId)) - .andExpect(jsonPath("$.firstName").value("George I")); + .andExpect(jsonPath("$.firstName").value("GeorgeI")); } + @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testUpdateOwnerSuccessNoBodyId() throws Exception { - given(this.clinicService.findOwnerById(1)).willReturn(owners.get(0)); + given(this.clinicService.findOwnerById(1)).willReturn(ownerMapper.toOwner(owners.get(0))); int ownerId = owners.get(0).getId(); - Owner updatedOwner = new Owner(); - updatedOwner.setFirstName("George I"); - updatedOwner.setLastName("Franklin"); - updatedOwner.setAddress("110 W. Liberty St."); - updatedOwner.setCity("Madison"); - updatedOwner.setTelephone("6085551023"); - ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(updatedOwner); - this.mockMvc.perform(put("/api/owners/" + ownerId) - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(content().contentType("application/json")) - .andExpect(status().isNoContent()); - - this.mockMvc.perform(get("/api/owners/" + ownerId) - .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE)) + OwnerDto updatedOwnerDto = new OwnerDto(); + updatedOwnerDto.setFirstName("GeorgeI"); + updatedOwnerDto.setLastName("Franklin"); + updatedOwnerDto.setAddress("110 W. Liberty St."); + updatedOwnerDto.setCity("Madison"); + + updatedOwnerDto.setTelephone("6085551023"); + ObjectMapper mapper = new ObjectMapper(); + String newOwnerAsJSON = mapper.writeValueAsString(updatedOwnerDto); + this.mockMvc.perform(put("/api/owners/" + ownerId) + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(content().contentType("application/json")) + .andExpect(status().isNoContent()); + + this.mockMvc.perform(get("/api/owners/" + ownerId) + .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.id").value(ownerId)) - .andExpect(jsonPath("$.firstName").value("George I")); + .andExpect(jsonPath("$.firstName").value("GeorgeI")); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testUpdateOwnerErrorBodyIdMismatchWithPathId() throws Exception { int ownerId = owners.get(0).getId(); - Owner updatedOwner = new Owner(); + OwnerDto updatedOwnerDto = new OwnerDto(); // body.id != ownerId - updatedOwner.setId(-1); - updatedOwner.setFirstName("George I"); - updatedOwner.setLastName("Franklin"); - updatedOwner.setAddress("110 W. Liberty St."); - updatedOwner.setCity("Madison"); - updatedOwner.setTelephone("6085551023"); + updatedOwnerDto.setId(-1); + updatedOwnerDto.setFirstName("GeorgeI"); + updatedOwnerDto.setLastName("Franklin"); + updatedOwnerDto.setAddress("110 W. Liberty St."); + updatedOwnerDto.setCity("Madison"); + updatedOwnerDto.setTelephone("6085551023"); ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(updatedOwner); + String newOwnerAsJSON = mapper.writeValueAsString(updatedOwnerDto); this.mockMvc.perform(put("/api/owners/" + ownerId) - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()) .andExpect(header().string("errors", - "[{\"objectName\":\"body\",\"fieldName\":\"id\",\"fieldValue\":\"-1\",\"errorMessage\":\"does not match pathId: 1\"}]")); + "[{\"objectName\":\"body\",\"fieldName\":\"id\",\"fieldValue\":\"-1\",\"errorMessage\":\"does not match pathId: 1\"},{\"objectName\":\"ownerDto\",\"fieldName\":\"id\",\"fieldValue\":\"-1\",\"errorMessage\":\"must be greater than or equal to 0\"}]")); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testUpdateOwnerError() throws Exception { - Owner newOwner = owners.get(0); - newOwner.setFirstName(""); - ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(newOwner); - this.mockMvc.perform(put("/api/owners/1") - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isBadRequest()); - } + OwnerDto newOwnerDto = owners.get(0); + newOwnerDto.setFirstName(""); + ObjectMapper mapper = new ObjectMapper(); + String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto); + this.mockMvc.perform(put("/api/owners/1") + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()); + } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testDeleteOwnerSuccess() throws Exception { - Owner newOwner = owners.get(0); - ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(newOwner); - given(this.clinicService.findOwnerById(1)).willReturn(owners.get(0)); - this.mockMvc.perform(delete("/api/owners/1") - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isNoContent()); + OwnerDto newOwnerDto = owners.get(0); + ObjectMapper mapper = new ObjectMapper(); + String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto); + final Owner owner = ownerMapper.toOwner(owners.get(0)); + given(this.clinicService.findOwnerById(1)).willReturn(owner); + this.mockMvc.perform(delete("/api/owners/1") + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isNoContent()); } @Test - @WithMockUser(roles="OWNER_ADMIN") + @WithMockUser(roles = "OWNER_ADMIN") public void testDeleteOwnerError() throws Exception { - Owner newOwner = owners.get(0); - ObjectMapper mapper = new ObjectMapper(); - String newOwnerAsJSON = mapper.writeValueAsString(newOwner); - given(this.clinicService.findOwnerById(-1)).willReturn(null); - this.mockMvc.perform(delete("/api/owners/-1") - .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isNotFound()); + OwnerDto newOwnerDto = owners.get(0); + ObjectMapper mapper = new ObjectMapper(); + String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto); + given(this.clinicService.findOwnerById(-1)).willReturn(null); + this.mockMvc.perform(delete("/api/owners/-1") + .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isNotFound()); } } diff --git a/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java index 9513f34b461e84b2e98d5f997130db43245fe424..be3bddd13f357bcdb128e05c1f4ddb1c7cf79264 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java @@ -16,19 +16,8 @@ package org.springframework.samples.petclinic.rest; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,11 +25,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.dto.OwnerDto; +import org.springframework.samples.petclinic.dto.PetDto; +import org.springframework.samples.petclinic.dto.PetTypeDto; +import org.springframework.samples.petclinic.mapper.PetMapper; import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -49,7 +40,16 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** @@ -67,21 +67,24 @@ public class PetRestControllerTests { @Autowired private PetRestController petRestController; + @Autowired + private PetMapper petMapper; + @MockBean protected ClinicService clinicService; private MockMvc mockMvc; - private List<Pet> pets; + private List<PetDto> pets; @Before public void initPets(){ this.mockMvc = MockMvcBuilders.standaloneSetup(petRestController) .setControllerAdvice(new ExceptionControllerAdvice()) .build(); - pets = new ArrayList<Pet>(); + pets = new ArrayList<>(); - Owner owner = new Owner(); + OwnerDto owner = new OwnerDto(); owner.setId(1); owner.setFirstName("Eduardo"); owner.setLastName("Rodriquez"); @@ -89,23 +92,21 @@ public class PetRestControllerTests { owner.setCity("McFarland"); owner.setTelephone("6085558763"); - PetType petType = new PetType(); + PetTypeDto petType = new PetTypeDto(); petType.setId(2); petType.setName("dog"); - Pet pet = new Pet(); + PetDto pet = new PetDto(); pet.setId(3); pet.setName("Rosy"); pet.setBirthDate(new Date()); - pet.setOwner(owner); pet.setType(petType); pets.add(pet); - pet = new Pet(); + pet = new PetDto(); pet.setId(4); pet.setName("Jewel"); pet.setBirthDate(new Date()); - pet.setOwner(owner); pet.setType(petType); pets.add(pet); } @@ -113,7 +114,7 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testGetPetSuccess() throws Exception { - given(this.clinicService.findPetById(3)).willReturn(pets.get(0)); + given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0))); this.mockMvc.perform(get("/api/pets/3") .accept(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()) @@ -125,7 +126,7 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testGetPetNotFound() throws Exception { - given(this.clinicService.findPetById(-1)).willReturn(null); + given(petMapper.toPetDto(this.clinicService.findPetById(-1))).willReturn(null); this.mockMvc.perform(get("/api/pets/-1") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); @@ -134,7 +135,10 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testGetAllPetsSuccess() throws Exception { - given(this.clinicService.findAllPets()).willReturn(pets); + final Collection<Pet> pets = petMapper.toPets(this.pets); + System.err.println(pets); + when(this.clinicService.findAllPets()).thenReturn(pets); + //given(this.clinicService.findAllPets()).willReturn(petMapper.toPets(pets)); this.mockMvc.perform(get("/api/pets/") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) @@ -149,7 +153,7 @@ public class PetRestControllerTests { @WithMockUser(roles="OWNER_ADMIN") public void testGetAllPetsNotFound() throws Exception { pets.clear(); - given(this.clinicService.findAllPets()).willReturn(pets); + given(this.clinicService.findAllPets()).willReturn(petMapper.toPets(pets)); this.mockMvc.perform(get("/api/pets/") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); @@ -158,10 +162,13 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testCreatePetSuccess() throws Exception { - Pet newPet = pets.get(0); + PetDto newPet = pets.get(0); newPet.setId(999); ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); String newPetAsJSON = mapper.writeValueAsString(newPet); + System.err.println("--> newPetAsJSON="+newPetAsJSON); this.mockMvc.perform(post("/api/pets/") .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isCreated()); @@ -170,10 +177,12 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testCreatePetError() throws Exception { - Pet newPet = pets.get(0); + PetDto newPet = pets.get(0); newPet.setId(null); newPet.setName(null); ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); String newPetAsJSON = mapper.writeValueAsString(newPet); this.mockMvc.perform(post("/api/pets/") .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -183,10 +192,13 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testUpdatePetSuccess() throws Exception { - given(this.clinicService.findPetById(3)).willReturn(pets.get(0)); - Pet newPet = pets.get(0); + given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0))); + PetDto newPet = pets.get(0); newPet.setName("Rosy I"); ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + String newPetAsJSON = mapper.writeValueAsString(newPet); this.mockMvc.perform(put("/api/pets/3") .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -205,10 +217,13 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testUpdatePetError() throws Exception { - Pet newPet = pets.get(0); - newPet.setName(""); + PetDto newPet = pets.get(0); + newPet.setName(null); ObjectMapper mapper = new ObjectMapper(); - String newPetAsJSON = mapper.writeValueAsString(newPet); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + String newPetAsJSON = mapper.writeValueAsString(newPet); + this.mockMvc.perform(put("/api/pets/3") .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -217,10 +232,10 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testDeletePetSuccess() throws Exception { - Pet newPet = pets.get(0); + PetDto newPet = pets.get(0); ObjectMapper mapper = new ObjectMapper(); String newPetAsJSON = mapper.writeValueAsString(newPet); - given(this.clinicService.findPetById(3)).willReturn(pets.get(0)); + given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0))); this.mockMvc.perform(delete("/api/pets/3") .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isNoContent()); @@ -229,7 +244,7 @@ public class PetRestControllerTests { @Test @WithMockUser(roles="OWNER_ADMIN") public void testDeletePetError() throws Exception { - Pet newPet = pets.get(0); + PetDto newPet = pets.get(0); ObjectMapper mapper = new ObjectMapper(); String newPetAsJSON = mapper.writeValueAsString(newPet); given(this.clinicService.findPetById(-1)).willReturn(null); diff --git a/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java index 089cebfbbc1fa19c4b6ddac5ee9d83054dcaa285..baeb6983cd07d377996df862a4ad1f3f7c95af81 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java @@ -16,18 +16,7 @@ package org.springframework.samples.petclinic.rest; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.ArrayList; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,9 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.samples.petclinic.mapper.PetTypeMapper; import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -45,7 +35,12 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** @@ -62,6 +57,9 @@ public class PetTypeRestControllerTests { @Autowired private PetTypeRestController petTypeRestController; + @Autowired + private PetTypeMapper petTypeMapper; + @MockBean private ClinicService clinicService; @@ -178,7 +176,7 @@ public class PetTypeRestControllerTests { PetType newPetType = petTypes.get(0); newPetType.setId(999); ObjectMapper mapper = new ObjectMapper(); - String newPetTypeAsJSON = mapper.writeValueAsString(newPetType); + String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType)); this.mockMvc.perform(post("/api/pettypes/") .content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isCreated()); @@ -191,7 +189,7 @@ public class PetTypeRestControllerTests { newPetType.setId(null); newPetType.setName(null); ObjectMapper mapper = new ObjectMapper(); - String newPetTypeAsJSON = mapper.writeValueAsString(newPetType); + String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType)); this.mockMvc.perform(post("/api/pettypes/") .content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -204,7 +202,7 @@ public class PetTypeRestControllerTests { PetType newPetType = petTypes.get(1); newPetType.setName("dog I"); ObjectMapper mapper = new ObjectMapper(); - String newPetTypeAsJSON = mapper.writeValueAsString(newPetType); + String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType)); this.mockMvc.perform(put("/api/pettypes/2") .content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType("application/json")) @@ -224,7 +222,7 @@ public class PetTypeRestControllerTests { PetType newPetType = petTypes.get(0); newPetType.setName(""); ObjectMapper mapper = new ObjectMapper(); - String newPetTypeAsJSON = mapper.writeValueAsString(newPetType); + String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType)); this.mockMvc.perform(put("/api/pettypes/1") .content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -247,7 +245,7 @@ public class PetTypeRestControllerTests { public void testDeletePetTypeError() throws Exception { PetType newPetType = petTypes.get(0); ObjectMapper mapper = new ObjectMapper(); - String newPetTypeAsJSON = mapper.writeValueAsString(newPetType); + String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType)); given(this.clinicService.findPetTypeById(-1)).willReturn(null); this.mockMvc.perform(delete("/api/pettypes/-1") .content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) diff --git a/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java index c4592101d597836257dc449e53a9cefe65a91d2b..023a8663dc5d27998dd549d1ad292118359497d3 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java @@ -16,18 +16,7 @@ package org.springframework.samples.petclinic.rest; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.ArrayList; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,9 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.samples.petclinic.mapper.SpecialtyMapper; import org.springframework.samples.petclinic.model.Specialty; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -45,7 +35,12 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** * Test class for {@link SpecialtyRestController} @@ -61,6 +56,9 @@ public class SpecialtyRestControllerTests { @Autowired private SpecialtyRestController specialtyRestController; + @Autowired + private SpecialtyMapper specialtyMapper; + @MockBean private ClinicService clinicService; @@ -144,7 +142,7 @@ public class SpecialtyRestControllerTests { Specialty newSpecialty = specialties.get(0); newSpecialty.setId(999); ObjectMapper mapper = new ObjectMapper(); - String newSpecialtyAsJSON = mapper.writeValueAsString(newSpecialty); + String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty)); this.mockMvc.perform(post("/api/specialties/") .content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isCreated()); @@ -157,7 +155,7 @@ public class SpecialtyRestControllerTests { newSpecialty.setId(null); newSpecialty.setName(null); ObjectMapper mapper = new ObjectMapper(); - String newSpecialtyAsJSON = mapper.writeValueAsString(newSpecialty); + String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty)); this.mockMvc.perform(post("/api/specialties/") .content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -170,7 +168,7 @@ public class SpecialtyRestControllerTests { Specialty newSpecialty = specialties.get(1); newSpecialty.setName("surgery I"); ObjectMapper mapper = new ObjectMapper(); - String newSpecialtyAsJSON = mapper.writeValueAsString(newSpecialty); + String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty)); this.mockMvc.perform(put("/api/specialties/2") .content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType("application/json")) @@ -190,7 +188,7 @@ public class SpecialtyRestControllerTests { Specialty newSpecialty = specialties.get(0); newSpecialty.setName(""); ObjectMapper mapper = new ObjectMapper(); - String newSpecialtyAsJSON = mapper.writeValueAsString(newSpecialty); + String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty)); this.mockMvc.perform(put("/api/specialties/1") .content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -201,7 +199,7 @@ public class SpecialtyRestControllerTests { public void testDeleteSpecialtySuccess() throws Exception { Specialty newSpecialty = specialties.get(0); ObjectMapper mapper = new ObjectMapper(); - String newSpecialtyAsJSON = mapper.writeValueAsString(newSpecialty); + String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty)); given(this.clinicService.findSpecialtyById(1)).willReturn(specialties.get(0)); this.mockMvc.perform(delete("/api/specialties/1") .content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -213,7 +211,7 @@ public class SpecialtyRestControllerTests { public void testDeleteSpecialtyError() throws Exception { Specialty newSpecialty = specialties.get(0); ObjectMapper mapper = new ObjectMapper(); - String newSpecialtyAsJSON = mapper.writeValueAsString(newSpecialty); + String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty)); given(this.clinicService.findSpecialtyById(-1)).willReturn(null); this.mockMvc.perform(delete("/api/specialties/-1") .content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) diff --git a/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java index c16676407ec4a00a3967d6f473c1f527b34a6c8b..72d70c36149a98e711c9f941c04aece4e48c59bc 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java @@ -1,9 +1,6 @@ package org.springframework.samples.petclinic.rest; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -11,9 +8,10 @@ import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; +import org.springframework.samples.petclinic.mapper.UserMapper; import org.springframework.samples.petclinic.model.User; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.UserService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -21,7 +19,8 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @RunWith(SpringJUnit4ClassRunner.class) @@ -32,6 +31,9 @@ public class UserRestControllerTests { @Mock private UserService userService; + @Autowired + private UserMapper userMapper; + @Autowired private UserRestController userRestController; @@ -44,29 +46,29 @@ public class UserRestControllerTests { } @Test - @WithMockUser(roles="ADMIN") + @WithMockUser(roles = "ADMIN") public void testCreateUserSuccess() throws Exception { User user = new User(); user.setUsername("username"); user.setPassword("password"); user.setEnabled(true); - user.addRole( "OWNER_ADMIN" ); + user.addRole("OWNER_ADMIN"); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(user); + String newVetAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); this.mockMvc.perform(post("/api/users/") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isCreated()); } @Test - @WithMockUser(roles="ADMIN") + @WithMockUser(roles = "ADMIN") public void testCreateUserError() throws Exception { User user = new User(); user.setUsername("username"); user.setPassword("password"); user.setEnabled(true); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(user); + String newVetAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user)); this.mockMvc.perform(post("/api/users/") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); diff --git a/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java index a6ab35ced9b47b6317a34b9a69c8904ce7df8cbe..7b90a41f60a04e21eedd2f0e0dcd019ff264f850 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java @@ -16,18 +16,7 @@ package org.springframework.samples.petclinic.rest; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.ArrayList; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,9 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.samples.petclinic.mapper.VetMapper; import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -45,7 +35,12 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** * Test class for {@link VetRestController} @@ -61,6 +56,9 @@ public class VetRestControllerTests { @Autowired private VetRestController vetRestController; + @Autowired + private VetMapper vetMapper; + @MockBean private ClinicService clinicService; @@ -146,7 +144,7 @@ public class VetRestControllerTests { Vet newVet = vets.get(0); newVet.setId(999); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(newVet); + String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet)); this.mockMvc.perform(post("/api/vets/") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isCreated()); @@ -159,7 +157,7 @@ public class VetRestControllerTests { newVet.setId(null); newVet.setFirstName(null); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(newVet); + String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet)); this.mockMvc.perform(post("/api/vets/") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -172,7 +170,7 @@ public class VetRestControllerTests { Vet newVet = vets.get(0); newVet.setFirstName("James"); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(newVet); + String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet)); this.mockMvc.perform(put("/api/vets/1") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType("application/json")) @@ -191,9 +189,9 @@ public class VetRestControllerTests { @WithMockUser(roles="VET_ADMIN") public void testUpdateVetError() throws Exception { Vet newVet = vets.get(0); - newVet.setFirstName(""); + newVet.setFirstName(null); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(newVet); + String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet)); this.mockMvc.perform(put("/api/vets/1") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -204,7 +202,7 @@ public class VetRestControllerTests { public void testDeleteVetSuccess() throws Exception { Vet newVet = vets.get(0); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(newVet); + String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet)); given(this.clinicService.findVetById(1)).willReturn(vets.get(0)); this.mockMvc.perform(delete("/api/vets/1") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -216,7 +214,7 @@ public class VetRestControllerTests { public void testDeleteVetError() throws Exception { Vet newVet = vets.get(0); ObjectMapper mapper = new ObjectMapper(); - String newVetAsJSON = mapper.writeValueAsString(newVet); + String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet)); given(this.clinicService.findVetById(-1)).willReturn(null); this.mockMvc.perform(delete("/api/vets/-1") .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -224,4 +222,3 @@ public class VetRestControllerTests { } } - diff --git a/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java index e318080e28887a10f4bb1d98a163320d078141d2..cd51385e9980ec2ea5d1a72a3fa750d92fb88d85 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java @@ -16,20 +16,7 @@ package org.springframework.samples.petclinic.rest; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,12 +24,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.samples.petclinic.mapper.VisitMapper; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -50,7 +38,14 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** * Test class for {@link VisitRestController} @@ -69,6 +64,9 @@ public class VisitRestControllerTests { @MockBean private ClinicService clinicService; + @Autowired + private VisitMapper visitMapper; + private MockMvc mockMvc; private List<Visit> visits; @@ -79,7 +77,7 @@ public class VisitRestControllerTests { .setControllerAdvice(new ExceptionControllerAdvice()) .build(); - visits = new ArrayList<Visit>(); + visits = new ArrayList<>(); Owner owner = new Owner(); owner.setId(1); @@ -169,21 +167,20 @@ public class VisitRestControllerTests { Visit newVisit = visits.get(0); newVisit.setId(999); ObjectMapper mapper = new ObjectMapper(); - String newVisitAsJSON = mapper.writeValueAsString(newVisit); + String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit)); System.out.println("newVisitAsJSON " + newVisitAsJSON); this.mockMvc.perform(post("/api/visits/") .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isCreated()); } - @Test(expected = IOException.class) @WithMockUser(roles="OWNER_ADMIN") public void testCreateVisitError() throws Exception { Visit newVisit = visits.get(0); newVisit.setId(null); - newVisit.setPet(null); + newVisit.setDescription(null); ObjectMapper mapper = new ObjectMapper(); - String newVisitAsJSON = mapper.writeValueAsString(newVisit); + String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit)); this.mockMvc.perform(post("/api/visits/") .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -196,7 +193,7 @@ public class VisitRestControllerTests { Visit newVisit = visits.get(0); newVisit.setDescription("rabies shot test"); ObjectMapper mapper = new ObjectMapper(); - String newVisitAsJSON = mapper.writeValueAsString(newVisit); + String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit)); this.mockMvc.perform(put("/api/visits/2") .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType("application/json")) @@ -210,13 +207,12 @@ public class VisitRestControllerTests { .andExpect(jsonPath("$.description").value("rabies shot test")); } - @Test(expected = IOException.class) @WithMockUser(roles="OWNER_ADMIN") public void testUpdateVisitError() throws Exception { Visit newVisit = visits.get(0); - newVisit.setPet(null); + newVisit.setDescription(null); ObjectMapper mapper = new ObjectMapper(); - String newVisitAsJSON = mapper.writeValueAsString(newVisit); + String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit)); this.mockMvc.perform(put("/api/visits/2") .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isBadRequest()); @@ -227,7 +223,7 @@ public class VisitRestControllerTests { public void testDeleteVisitSuccess() throws Exception { Visit newVisit = visits.get(0); ObjectMapper mapper = new ObjectMapper(); - String newVisitAsJSON = mapper.writeValueAsString(newVisit); + String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit)); given(this.clinicService.findVisitById(2)).willReturn(visits.get(0)); this.mockMvc.perform(delete("/api/visits/2") .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -239,7 +235,7 @@ public class VisitRestControllerTests { public void testDeleteVisitError() throws Exception { Visit newVisit = visits.get(0); ObjectMapper mapper = new ObjectMapper(); - String newVisitAsJSON = mapper.writeValueAsString(newVisit); + String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit)); given(this.clinicService.findVisitById(-1)).willReturn(null); this.mockMvc.perform(delete("/api/visits/-1") .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 59e2ae413a2e719a7801a482f03d0bb0551175b9..d14cb703554f8dcc4d856aa34e47064cbe1a39aa 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -24,7 +24,6 @@ server.port=9966 server.context-path=/petclinic/ spring.messages.basename=messages/messages - logging.level.org.springframework=INFO #logging.level.org.springframework=DEBUG @@ -35,3 +34,7 @@ logging.level.org.springframework=INFO # by default the authentication is disabled security.ignored=/** basic.authentication.enabled=true +# ------------------------------------------------ +# Spring doc configuration +springdoc.api-docs.enabled=true +springdoc.writer-with-default-pretty-printer=true