From 162d8d8e45613610b6b28e78ed94c44054c2914e Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Thu, 24 Aug 2017 18:26:45 +0200 Subject: [PATCH 001/131] Add Apache 2.0 license #260 --- pom.xml | 12 ++++++++++-- readme.md | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index f64e6d122..6fdc4d17e 100644 --- a/pom.xml +++ b/pom.xml @@ -124,7 +124,7 @@ spring-boot-maven-plugin - build-info @@ -157,7 +157,7 @@ - pl.project13.maven @@ -225,4 +225,12 @@ + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + diff --git a/readme.md b/readme.md index ac30d6392..c43ef63f9 100644 --- a/readme.md +++ b/readme.md @@ -100,6 +100,6 @@ The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . +# License - - +The Spring PetClinic sample application is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0). From fa3b7f9a4c6a4b2cab8f2492bf1ef187fdd8e619 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Nov 2017 11:18:15 +0000 Subject: [PATCH 002/131] Add CLA link to readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index c43ef63f9..34161874a 100644 --- a/readme.md +++ b/readme.md @@ -98,7 +98,7 @@ Here is a list of them: The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) is the preferred channel for bug reports, features requests and submitting pull requests. -For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . +For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . If you have not previously done so, please fill out and submit the https://cla.pivotal.io/sign/spring[Contributor License Agreement]. # License From 05e891cec11e7afa6d2d7230113ffcf5a948815b Mon Sep 17 00:00:00 2001 From: Aditya Ketkar Date: Sun, 29 Oct 2017 19:02:39 +0530 Subject: [PATCH 003/131] Removed redundant javadoc comments --- .../samples/petclinic/visit/Visit.java | 45 +++---------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index 25e7cc5ad..251d027df 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -37,24 +37,16 @@ import org.springframework.samples.petclinic.model.BaseEntity; @Table(name = "visits") public class Visit extends BaseEntity { - /** - * Holds value of property date. - */ @Column(name = "visit_date") @Temporal(TemporalType.TIMESTAMP) @DateTimeFormat(pattern = "yyyy/MM/dd") private Date date; - /** - * Holds value of property description. - */ @NotEmpty @Column(name = "description") private String description; - /** - * Holds value of property pet. - */ + @Column(name = "pet_id") private Integer petId; @@ -67,56 +59,31 @@ public class Visit extends BaseEntity { } - /** - * Getter for property date. - * - * @return Value of property date. - */ public Date getDate() { return this.date; } - /** - * Setter for property date. - * - * @param date New value of property date. - */ + public void setDate(Date date) { this.date = date; } - /** - * Getter for property description. - * - * @return Value of property description. - */ + public String getDescription() { return this.description; } - /** - * Setter for property description. - * - * @param description New value of property description. - */ + public void setDescription(String description) { this.description = description; } - /** - * Getter for property pet id. - * - * @return Value of property pet id. - */ + public Integer getPetId() { return this.petId; } - /** - * Setter for property pet id. - * - * @param petId New value of property pet id. - */ + public void setPetId(Integer petId) { this.petId = petId; } From 4b3d6abfed2054ba54d3b044dcb993b7e1d6b92e Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Sat, 2 Sep 2017 11:17:02 +0200 Subject: [PATCH 004/131] Reference new forks: spring-petclinic-kotlin, spring-petclinic-graphql and spring-petclinic-rest --- readme.md | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 34161874a..3f4c376ec 100644 --- a/readme.md +++ b/readme.md @@ -73,13 +73,17 @@ you have a special interest in a different technology stack that could be used to implement the Pet Clinic then please join the community there. -| Link | Main technologies | -|----------------|-------------------| -| [spring-framework-petclinic](https://github.com/spring-petclinic/spring-framework-petclinic) | Spring Framework XML configuration, JSP pages, 3 persistence layers: JDBC, JPA and Spring Data JPA | -| [javaconfig branch](https://github.com/spring-petclinic/spring-framework-petclinic/tree/javaconfig) | Same frameworks as the [spring-framework-petclinic](https://github.com/spring-petclinic/spring-framework-petclinic) but with Java Configuration instead of XML | -| [spring-petclinic-angular](https://github.com/spring-petclinic/spring-petclinic-angularjs) | AngularJS 1.x, Spring Boot and Spring Data JPA | -| [spring-petclinic-microservices](https://github.com/spring-petclinic/spring-petclinic-microservices) | Distributed version of Spring Petclinic built with Spring Cloud | -| [spring-petclinic-reactjs](https://github.com/spring-petclinic/spring-petclinic-reactjs) | ReactJS (with TypeScript) and Spring Boot | +| Link | Main technologies | +|------------------------------------|-------------------| +| [spring-framework-petclinic][] | Spring Framework XML configuration, JSP pages, 3 persistence layers: JDBC, JPA and Spring Data JPA | +| [javaconfig branch][] | Same frameworks as the [spring-framework-petclinic][] but with Java Configuration instead of XML | +| [spring-petclinic-angularjs][] | AngularJS 1.x, Spring Boot and Spring Data JPA | +| [spring-petclinic-angular][] | Angular 4 front-end of the Petclinic REST API [spring-petclinic-rest][] | +| [spring-petclinic-microservices][] | Distributed version of Spring Petclinic built with Spring Cloud | +| [spring-petclinic-reactjs][] | ReactJS (with TypeScript) and Spring Boot | +| [spring-petclinic-graphql][] | GraphQL version based on React Appolo, TypeScript and GraphQL Spring boot starter | +| [spring-petclinic-kotlin][] | Kotlin version of [spring-petclinic][] | +| [spring-petclinic-rest][] | Backend REST API | ## Interaction with other open source projects @@ -103,3 +107,13 @@ For pull requests, editor preferences are available in the [editor config](.edit # License The Spring PetClinic sample application is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0). + +[spring-petclinic]: https://github.com/spring-projects/spring-petclinic +[spring-framework-petclinic]: https://github.com/spring-petclinic/spring-framework-petclinic +[spring-petclinic-angularjs]: https://github.com/spring-petclinic/spring-petclinic-angularjs +[javaconfig branch]: https://github.com/spring-petclinic/spring-framework-petclinic/tree/javaconfig +[spring-petclinic-angular]: https://github.com/spring-petclinic/spring-petclinic-angular +[spring-petclinic-microservices]: https://github.com/spring-petclinic/spring-petclinic-microservices +[spring-petclinic-reactjs]: https://github.com/spring-petclinic/spring-petclinic-reactjs +[spring-petclinic-graphql]: https://github.com/spring-petclinic/spring-petclinic-graphql +[spring-petclinic-kotlin]: https://github.com/spring-petclinic/spring-petclinic-kotlin From 4be8ba2c4349616e1da9d8232250e20da2daec47 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Wed, 23 Aug 2017 18:38:39 +0200 Subject: [PATCH 005/131] Replace @RequestMapping by their corresponding shortcut @GetMapping and @PostMapping --- .../petclinic/owner/OwnerController.java | 27 +++++++++---------- .../petclinic/owner/PetController.java | 21 ++++++--------- .../petclinic/owner/VisitController.java | 17 +++++------- .../petclinic/system/CrashController.java | 3 ++- .../petclinic/system/WelcomeController.java | 4 +-- .../samples/petclinic/vet/VetController.java | 10 +++---- 6 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index ef3169b70..d914ed745 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -15,22 +15,21 @@ */ package org.springframework.samples.petclinic.owner; -import java.util.Collection; -import java.util.Map; - -import javax.validation.Valid; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; +import javax.validation.Valid; +import java.util.Collection; +import java.util.Map; + /** * @author Juergen Hoeller * @author Ken Krebs @@ -54,14 +53,14 @@ class OwnerController { dataBinder.setDisallowedFields("id"); } - @RequestMapping(value = "/owners/new", method = RequestMethod.GET) + @GetMapping("/owners/new") public String initCreationForm(Map model) { Owner owner = new Owner(); model.put("owner", owner); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } - @RequestMapping(value = "/owners/new", method = RequestMethod.POST) + @PostMapping("/owners/new") public String processCreationForm(@Valid Owner owner, BindingResult result) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; @@ -71,13 +70,13 @@ class OwnerController { } } - @RequestMapping(value = "/owners/find", method = RequestMethod.GET) + @GetMapping("/owners/find") public String initFindForm(Map model) { model.put("owner", new Owner()); return "owners/findOwners"; } - @RequestMapping(value = "/owners", method = RequestMethod.GET) + @GetMapping("/owners") public String processFindForm(Owner owner, BindingResult result, Map model) { // allow parameterless GET request for /owners to return all records @@ -102,14 +101,14 @@ class OwnerController { } } - @RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.GET) + @GetMapping("/owners/{ownerId}/edit") public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { Owner owner = this.owners.findById(ownerId); model.addAttribute(owner); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } - @RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.POST) + @PostMapping("/owners/{ownerId}/edit") public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; @@ -126,7 +125,7 @@ class OwnerController { * @param ownerId the ID of the owner to display * @return a ModelMap with the model attributes for the view */ - @RequestMapping("/owners/{ownerId}") + @GetMapping("/owners/{ownerId}") public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { ModelAndView mav = new ModelAndView("owners/ownerDetails"); mav.addObject(this.owners.findById(ownerId)); diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java index 45b87c6b1..9c52e0309 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java @@ -15,21 +15,16 @@ */ package org.springframework.samples.petclinic.owner; -import java.util.Collection; - -import javax.validation.Valid; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.Collection; /** * @author Juergen Hoeller @@ -70,7 +65,7 @@ class PetController { dataBinder.setValidator(new PetValidator()); } - @RequestMapping(value = "/pets/new", method = RequestMethod.GET) + @GetMapping("/pets/new") public String initCreationForm(Owner owner, ModelMap model) { Pet pet = new Pet(); owner.addPet(pet); @@ -78,7 +73,7 @@ class PetController { return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } - @RequestMapping(value = "/pets/new", method = RequestMethod.POST) + @PostMapping("/pets/new") public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){ result.rejectValue("name", "duplicate", "already exists"); @@ -93,14 +88,14 @@ class PetController { } } - @RequestMapping(value = "/pets/{petId}/edit", method = RequestMethod.GET) + @GetMapping("/pets/{petId}/edit") public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { Pet pet = this.pets.findById(petId); model.put("pet", pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } - @RequestMapping(value = "/pets/{petId}/edit", method = RequestMethod.POST) + @PostMapping("/pets/{petId}/edit") public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { if (result.hasErrors()) { pet.setOwner(owner); diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index d98c5dd0f..d7afed12e 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -15,21 +15,16 @@ */ package org.springframework.samples.petclinic.owner; -import java.util.Map; - -import javax.validation.Valid; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.Map; /** * @author Juergen Hoeller @@ -76,13 +71,13 @@ class VisitController { } // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called - @RequestMapping(value = "/owners/*/pets/{petId}/visits/new", method = RequestMethod.GET) + @GetMapping("/owners/*/pets/{petId}/visits/new") public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { return "pets/createOrUpdateVisitForm"; } // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called - @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/visits/new", method = RequestMethod.POST) + @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") public String processNewVisitForm(@Valid Visit visit, BindingResult result) { if (result.hasErrors()) { return "pets/createOrUpdateVisitForm"; diff --git a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java index a702cfc8f..c18c04dd8 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java @@ -16,6 +16,7 @@ package org.springframework.samples.petclinic.system; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -29,7 +30,7 @@ import org.springframework.web.bind.annotation.RequestMethod; @Controller class CrashController { - @RequestMapping(value = "/oups", method = RequestMethod.GET) + @GetMapping("/oups") public String triggerException() { throw new RuntimeException( "Expected: controller used to showcase what " + "happens when an exception is thrown"); diff --git a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java index b5af0f7d7..00430a790 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java @@ -2,12 +2,12 @@ package org.springframework.samples.petclinic.system; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; @Controller class WelcomeController { - @RequestMapping("/") + @GetMapping("/") public String welcome() { return "welcome"; } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index 8ddcca60a..7ce8374ec 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -15,13 +15,13 @@ */ package org.springframework.samples.petclinic.vet; -import java.util.Map; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.Map; + /** * @author Juergen Hoeller * @author Mark Fisher @@ -38,7 +38,7 @@ class VetController { this.vets = clinicService; } - @RequestMapping(value = { "/vets.html" }) + @GetMapping("/vets.html") public String showVetList(Map model) { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for Object-Xml mapping @@ -48,7 +48,7 @@ class VetController { return "vets/vetList"; } - @RequestMapping(value = { "/vets.json", "/vets.xml" }) + @GetMapping({ "/vets.json", "/vets.xml" }) public @ResponseBody Vets showResourcesVetList() { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for JSon/Object mapping From 4ab6a800c84657b8c8fad5611f7ba2ebf87ee219 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Wed, 23 Aug 2017 18:17:57 +0200 Subject: [PATCH 006/131] Removing .springBeans --- .springBeans | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 .springBeans diff --git a/.springBeans b/.springBeans deleted file mode 100644 index 44f18becd..000000000 --- a/.springBeans +++ /dev/null @@ -1,20 +0,0 @@ - - - 1 - - - - - - - src/main/resources/spring/datasource-config.xml - src/main/resources/spring/mvc-core-config.xml - src/main/resources/spring/mvc-view-config.xml - src/main/resources/spring/business-config.xml - - - src/main/resources/spring/tools-config.xml - - - - From 3e65dee2371d4517fa29d6de44d2a77f0ff3065c Mon Sep 17 00:00:00 2001 From: dastier Date: Sun, 9 Jul 2017 23:45:42 +0300 Subject: [PATCH 007/131] fix button text in createOrUpdatePetForm.html in case of new pet (issue #252) --- src/main/resources/templates/pets/createOrUpdatePetForm.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/pets/createOrUpdatePetForm.html b/src/main/resources/templates/pets/createOrUpdatePetForm.html index bfa07d1ff..e4726e155 100644 --- a/src/main/resources/templates/pets/createOrUpdatePetForm.html +++ b/src/main/resources/templates/pets/createOrUpdatePetForm.html @@ -26,7 +26,7 @@
From 5b0f037d06de2c9ad3be4fdf52402ddb5667e2da Mon Sep 17 00:00:00 2001 From: thetric Date: Fri, 19 May 2017 12:16:02 +0200 Subject: [PATCH 008/131] fix: make id 'lastName' in findOwners.html unique previously the div.control-group and the containing input shared the same id --- src/main/resources/templates/owners/findOwners.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/owners/findOwners.html b/src/main/resources/templates/owners/findOwners.html index 911ac9581..982be5e81 100644 --- a/src/main/resources/templates/owners/findOwners.html +++ b/src/main/resources/templates/owners/findOwners.html @@ -8,7 +8,7 @@
-
+
Date: Mon, 5 Dec 2016 21:32:44 +0100 Subject: [PATCH 009/131] Fix date formatting --- .../java/org/springframework/samples/petclinic/owner/Pet.java | 2 +- .../java/org/springframework/samples/petclinic/visit/Visit.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 src/main/java/org/springframework/samples/petclinic/owner/Pet.java diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java old mode 100644 new mode 100755 index e8df85e91..5e226a180 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -53,7 +53,7 @@ public class Pet extends NamedEntity { @Column(name = "birth_date") @Temporal(TemporalType.DATE) - @DateTimeFormat(pattern = "yyyy/MM/dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthDate; @ManyToOne diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index 251d027df..f83d1463c 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -39,7 +39,7 @@ public class Visit extends BaseEntity { @Column(name = "visit_date") @Temporal(TemporalType.TIMESTAMP) - @DateTimeFormat(pattern = "yyyy/MM/dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") private Date date; @NotEmpty From 23f65ba7d0101adeb32f36fd8f634549ee3d6e40 Mon Sep 17 00:00:00 2001 From: Oscar Utbult Date: Mon, 5 Dec 2016 22:18:58 +0100 Subject: [PATCH 010/131] Fix broken tests --- .../samples/petclinic/owner/PetControllerTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java old mode 100644 new mode 100755 index f56931cb6..64876906c --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -75,7 +75,7 @@ public class PetControllerTests { mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) .param("name", "Betty") .param("type", "hamster") - .param("birthDate", "2015/02/12") + .param("birthDate", "2015-02-12") ) .andExpect(status().is3xxRedirection()) .andExpect(view().name("redirect:/owners/{ownerId}")); @@ -85,7 +85,7 @@ public class PetControllerTests { public void testProcessCreationFormHasErrors() throws Exception { mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) .param("name", "Betty") - .param("birthDate", "2015/02/12") + .param("birthDate", "2015-02-12") ) .andExpect(model().attributeHasNoErrors("owner")) .andExpect(model().attributeHasErrors("pet")) @@ -106,7 +106,7 @@ public class PetControllerTests { mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) .param("name", "Betty") .param("type", "hamster") - .param("birthDate", "2015/02/12") + .param("birthDate", "2015-02-12") ) .andExpect(status().is3xxRedirection()) .andExpect(view().name("redirect:/owners/{ownerId}")); From e20b43b0090bc7a13de4b177ff02c3900f168a05 Mon Sep 17 00:00:00 2001 From: sunflower2014 Date: Sun, 15 Oct 2017 16:08:44 +0800 Subject: [PATCH 011/131] Update PetControllerTests.java correct testProcessCreationFormHasErrors method's post url --- .../samples/petclinic/owner/PetControllerTests.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index 64876906c..f95d7c87c 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -83,12 +83,14 @@ public class PetControllerTests { @Test public void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) .param("name", "Betty") .param("birthDate", "2015-02-12") ) .andExpect(model().attributeHasNoErrors("owner")) .andExpect(model().attributeHasErrors("pet")) + .andExpect(model().attributeHasFieldErrors("pet", "type")) + .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")) .andExpect(status().isOk()) .andExpect(view().name("pets/createOrUpdatePetForm")); } From c36452a2c34443ae26b4ecbba4f149906af14717 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Nov 2017 14:17:04 +0000 Subject: [PATCH 012/131] Use leading / in app URL Fixes gh-267 --- src/main/resources/templates/owners/ownersList.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/owners/ownersList.html b/src/main/resources/templates/owners/ownersList.html index dc4c44635..478b37e5d 100644 --- a/src/main/resources/templates/owners/ownersList.html +++ b/src/main/resources/templates/owners/ownersList.html @@ -19,7 +19,7 @@ - + From 14ef611d7008248b181282c441a1769ba955047e Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 9 Jan 2018 17:50:14 +0000 Subject: [PATCH 013/131] Update to Spring Boot 2.0 snapshots --- pom.xml | 9 +-------- src/main/resources/application.properties | 4 ++-- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 6fdc4d17e..6e1d8e682 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.4.RELEASE + 2.0.0.BUILD-SNAPSHOT petclinic @@ -26,7 +26,6 @@ 1.11.4 2.2.4 1.8.0 - 3.0.6.RELEASE 2.7 @@ -53,12 +52,6 @@ org.springframework.boot spring-boot-starter-thymeleaf - - - nz.net.ultraq.thymeleaf - thymeleaf-layout-dialect - - org.springframework.boot diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index fb07c6c50..ed5392afe 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,9 +13,9 @@ spring.jpa.hibernate.ddl-auto=none spring.messages.basename=messages/messages # Actuator / Management -management.contextPath=/manage +management.endpoints.web.base-path=/manage # Spring Boot 1.5 makes actuator secure by default -management.security.enabled=false +management.endpoints.web.enabled=true # Logging logging.level.org.springframework=INFO From cf352663366ecabc4ed9aad125e7373e040bca45 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 11 Jan 2018 09:15:18 +0000 Subject: [PATCH 014/131] Tidy up compiler warnings --- .../samples/petclinic/model/Person.java | 3 +-- .../samples/petclinic/owner/Owner.java | 18 +++++++----------- .../petclinic/system/CrashController.java | 6 ++---- .../samples/petclinic/visit/Visit.java | 10 +--------- .../petclinic/model/ValidatorTests.java | 15 ++++++++------- .../petclinic/owner/PetTypeFormatterTests.java | 13 +++++-------- 6 files changed, 24 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index 4cb7481e0..5d23523bd 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -17,8 +17,7 @@ package org.springframework.samples.petclinic.model; import javax.persistence.Column; import javax.persistence.MappedSuperclass; - -import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.NotEmpty; /** * Simple JavaBean domain object representing an person. diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java index f6fcae7ac..89aad2c2c 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -27,8 +27,8 @@ import javax.persistence.Entity; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.Digits; +import javax.validation.constraints.NotEmpty; -import org.hibernate.validator.constraints.NotEmpty; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.core.style.ToStringCreator; @@ -61,7 +61,6 @@ public class Owner extends Person { @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") private Set pets; - public String getAddress() { return this.address; } @@ -99,7 +98,8 @@ public class Owner extends Person { public List getPets() { List sortedPets = new ArrayList<>(getPetsInternal()); - PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true)); + PropertyComparator.sort(sortedPets, + new MutableSortDefinition("name", true, true)); return Collections.unmodifiableList(sortedPets); } @@ -144,13 +144,9 @@ public class Owner extends Person { public String toString() { return new ToStringCreator(this) - .append("id", this.getId()) - .append("new", this.isNew()) - .append("lastName", this.getLastName()) - .append("firstName", this.getFirstName()) - .append("address", this.address) - .append("city", this.city) - .append("telephone", this.telephone) - .toString(); + .append("id", this.getId()).append("new", this.isNew()) + .append("lastName", this.getLastName()) + .append("firstName", this.getFirstName()).append("address", this.address) + .append("city", this.city).append("telephone", this.telephone).toString(); } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java index c18c04dd8..2f5e7a348 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java @@ -17,8 +17,6 @@ package org.springframework.samples.petclinic.system; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; /** * Controller used to showcase what happens when an exception is thrown @@ -32,8 +30,8 @@ class CrashController { @GetMapping("/oups") public String triggerException() { - throw new RuntimeException( - "Expected: controller used to showcase what " + "happens when an exception is thrown"); + throw new RuntimeException("Expected: controller used to showcase what " + + "happens when an exception is thrown"); } } diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index f83d1463c..ce10d7b12 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -22,8 +22,8 @@ import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import javax.validation.constraints.NotEmpty; -import org.hibernate.validator.constraints.NotEmpty; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.samples.petclinic.model.BaseEntity; @@ -46,11 +46,9 @@ public class Visit extends BaseEntity { @Column(name = "description") private String description; - @Column(name = "pet_id") private Integer petId; - /** * Creates a new instance of Visit for the current date */ @@ -58,32 +56,26 @@ public class Visit extends BaseEntity { this.date = new Date(); } - public Date getDate() { return this.date; } - public void setDate(Date date) { this.date = date; } - public String getDescription() { return this.description; } - public void setDescription(String description) { this.description = description; } - public Integer getPetId() { return this.petId; } - public void setPetId(Integer petId) { this.petId = petId; } diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index b836d0cc2..7da0d3dea 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -1,7 +1,5 @@ package org.springframework.samples.petclinic.model; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Locale; import java.util.Set; @@ -9,13 +7,15 @@ import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.junit.Test; + import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import static org.assertj.core.api.Assertions.assertThat; + /** - * @author Michael Isvy - * Simple test to make sure that Bean Validation is working - * (useful when upgrading to a new version of Hibernate Validator/ Bean Validation) + * @author Michael Isvy Simple test to make sure that Bean Validation is working (useful + * when upgrading to a new version of Hibernate Validator/ Bean Validation) */ public class ValidatorTests { @@ -34,12 +34,13 @@ public class ValidatorTests { person.setLastName("smith"); Validator validator = createValidator(); - Set> constraintViolations = validator.validate(person); + Set> constraintViolations = validator + .validate(person); assertThat(constraintViolations.size()).isEqualTo(1); ConstraintViolation violation = constraintViolations.iterator().next(); assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName"); - assertThat(violation.getMessage()).isEqualTo("may not be empty"); + assertThat(violation.getMessage()).isEqualTo("must not be empty"); } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index f332257bc..4e8e36c14 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -1,7 +1,5 @@ package org.springframework.samples.petclinic.owner; -import static org.junit.Assert.assertEquals; - import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; @@ -13,10 +11,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.samples.petclinic.owner.PetRepository; -import org.springframework.samples.petclinic.owner.PetType; -import org.springframework.samples.petclinic.owner.PetTypeFormatter; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.junit.Assert.assertEquals; /** * Test class for {@link PetTypeFormatter} @@ -64,12 +61,12 @@ public class PetTypeFormatterTests { */ private List makePetTypes() { List petTypes = new ArrayList<>(); - petTypes.add(new PetType(){ + petTypes.add(new PetType() { { setName("Dog"); } }); - petTypes.add(new PetType(){ + petTypes.add(new PetType() { { setName("Bird"); } From c91b73e75e5e2d9dc13fa2646757834a50ac07ca Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 11 Jan 2018 09:16:04 +0000 Subject: [PATCH 015/131] Update version of Petclinic --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6e1d8e682..fa5e4df94 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.springframework.samples spring-petclinic - 1.5.1 + 2.0.0 org.springframework.boot From 6730a229a0cf22562fe148d68c3f33d03c44e539 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 20 Jan 2018 09:38:36 +0000 Subject: [PATCH 016/131] Add repository declarations for snapshots --- pom.xml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pom.xml b/pom.xml index fa5e4df94..bdb939f31 100644 --- a/pom.xml +++ b/pom.xml @@ -226,4 +226,42 @@ + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + From cdd802eeee36f8083580a6cd0368b007cb4a0bad Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 21 Feb 2018 10:48:01 +0100 Subject: [PATCH 017/131] Update webjars-locator dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bdb939f31..a68944300 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ org.webjars - webjars-locator + webjars-locator-core org.webjars From a52cbe93a25dce015be5d63a17988bdfa0aeb992 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 21 Feb 2018 09:09:48 +0000 Subject: [PATCH 018/131] Add ignores for vscode --- .gitignore | 6 ++++++ .vscode/launch.json | 26 ++++++++++++++++++++++++++ .vscode/settings.json | 3 +++ .vscode/tasks.json | 19 +++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json diff --git a/.gitignore b/.gitignore index b00af803d..8cdbd1ff4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ target/* .idea *.iml /target +.sts4-cache/ +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json _site/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..559c53805 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Debug (Launch)-PetClinicApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "console": "internalConsole", + "stopOnEntry": false, + "mainClass": "org.springframework.samples.petclinic.PetClinicApplication", + "projectName": "spring-petclinic", + "args": "" + }, + { + "type": "java", + "name": "Debug (Attach)", + "request": "attach", + "hostName": "localhost", + "port": 0 + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..c5f3f6b9c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..fabd5c416 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "verify", + "type": "shell", + "command": "mvn -B verify", + "group": "build" + }, + { + "label": "test", + "type": "shell", + "command": "mvn -B test", + "group": "test" + } + ] +} From c5abf45cbc78ca997a1a5934673b93077ca4e907 Mon Sep 17 00:00:00 2001 From: Ray Tsang Date: Mon, 5 Feb 2018 19:19:38 +0100 Subject: [PATCH 019/131] Fix datasource initialization property Closes gh-301 --- src/main/resources/application-mysql.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index fd561fa90..c2c654fe4 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -3,5 +3,5 @@ database=mysql spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=root spring.datasource.password=root - # Uncomment this the first time the app runs -# spring.datasource.initialize=true \ No newline at end of file +# Uncomment this the first time the app runs +# spring.datasource.initialization-mode=always From dfcd30be601439c933785456a5551578467b9573 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 22 Feb 2018 10:46:09 +0100 Subject: [PATCH 020/131] Fix project's version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a68944300..fe07d59b6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.0.0 + 2.0.0.BUILD-SNAPSHOT org.springframework.boot From 106226929b527c27359b0215bc2569121cd80401 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 22 Feb 2018 10:57:12 +0100 Subject: [PATCH 021/131] Fix actuator exposure --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ed5392afe..c8d5a5c1a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -14,8 +14,7 @@ spring.messages.basename=messages/messages # Actuator / Management management.endpoints.web.base-path=/manage -# Spring Boot 1.5 makes actuator secure by default -management.endpoints.web.enabled=true +management.endpoints.web.exposure.include=* # Logging logging.level.org.springframework=INFO From 0d847edfdb6447c45e98205a102980f7e3a9c4ea Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Sat, 4 Nov 2017 11:59:48 +0100 Subject: [PATCH 022/131] Add spring-petclinic-rest URL Closes gh-278 --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 3f4c376ec..78e4ac828 100644 --- a/readme.md +++ b/readme.md @@ -117,3 +117,4 @@ The Spring PetClinic sample application is released under version 2.0 of the [Ap [spring-petclinic-reactjs]: https://github.com/spring-petclinic/spring-petclinic-reactjs [spring-petclinic-graphql]: https://github.com/spring-petclinic/spring-petclinic-graphql [spring-petclinic-kotlin]: https://github.com/spring-petclinic/spring-petclinic-kotlin +[spring-petclinic-rest]: https://github.com/spring-petclinic/spring-petclinic-rest From d92a4218dd6678261f17b4b8a3ab0838d6241ea1 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Thu, 15 Feb 2018 17:44:48 +0100 Subject: [PATCH 023/131] Add placeholder YYYY-MM-DD for date input field Closes gh-303 --- src/main/resources/templates/fragments/inputField.html | 10 +++++++--- .../templates/owners/createOrUpdateOwnerForm.html | 10 +++++----- .../templates/pets/createOrUpdatePetForm.html | 4 ++-- .../templates/pets/createOrUpdateVisitForm.html | 4 ++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/resources/templates/fragments/inputField.html b/src/main/resources/templates/fragments/inputField.html index 7cef1ee9e..c3373bea0 100644 --- a/src/main/resources/templates/fragments/inputField.html +++ b/src/main/resources/templates/fragments/inputField.html @@ -1,14 +1,18 @@ - +
- +
+ + +
diff --git a/src/main/resources/templates/owners/createOrUpdateOwnerForm.html b/src/main/resources/templates/owners/createOrUpdateOwnerForm.html index a34a39c7f..ca22d9de1 100644 --- a/src/main/resources/templates/owners/createOrUpdateOwnerForm.html +++ b/src/main/resources/templates/owners/createOrUpdateOwnerForm.html @@ -7,15 +7,15 @@
+ th:replace="~{fragments/inputField :: input ('First Name', 'firstName', 'text')}" /> + th:replace="~{fragments/inputField :: input ('Last Name', 'lastName', 'text')}" /> + th:replace="~{fragments/inputField :: input ('Address', 'address', 'text')}" /> + th:replace="~{fragments/inputField :: input ('City', 'city', 'text')}" /> + th:replace="~{fragments/inputField :: input ('Telephone', 'telephone', 'text')}" />
diff --git a/src/main/resources/templates/pets/createOrUpdatePetForm.html b/src/main/resources/templates/pets/createOrUpdatePetForm.html index e4726e155..a0c182aa5 100644 --- a/src/main/resources/templates/pets/createOrUpdatePetForm.html +++ b/src/main/resources/templates/pets/createOrUpdatePetForm.html @@ -17,9 +17,9 @@
+ th:replace="~{fragments/inputField :: input ('Name', 'name', 'text')}" /> + th:replace="~{fragments/inputField :: input ('Birth Date', 'birthDate', 'date')}" />
diff --git a/src/main/resources/templates/pets/createOrUpdateVisitForm.html b/src/main/resources/templates/pets/createOrUpdateVisitForm.html index 26a71378f..4401d36ce 100644 --- a/src/main/resources/templates/pets/createOrUpdateVisitForm.html +++ b/src/main/resources/templates/pets/createOrUpdateVisitForm.html @@ -31,9 +31,9 @@
+ th:replace="~{fragments/inputField :: input ('Date', 'date', 'date')}" /> + th:replace="~{fragments/inputField :: input ('Description', 'description', 'text')}" />
From b527de52f5fd19f9fe550372c017d145a3b2a809 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 14 Mar 2018 16:32:27 -0400 Subject: [PATCH 024/131] Upgrade to Spring Boot 2.0.0.RELEASE --- pom.xml | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/pom.xml b/pom.xml index fe07d59b6..0b8f9c273 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.RELEASE petclinic @@ -226,42 +226,4 @@ - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - From 932f17ddaea2cc752bf41f7d0cbf64636596c892 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 26 Mar 2018 14:00:56 +0200 Subject: [PATCH 025/131] Fix dead links Closes gh-314 --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 78e4ac828..66aee0c28 100644 --- a/readme.md +++ b/readme.md @@ -34,12 +34,12 @@ docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306: ### prerequisites The following items should be installed in your system: -* Maven 3 (http://www.sonatype.com/books/mvnref-book/reference/installation.html) +* Apache Maven (https://maven.apache.org/install.html) * git command line tool (https://help.github.com/articles/set-up-git) * Eclipse with the m2e plugin (m2e is installed by default when using the STS (http://www.springsource.org/sts) distribution of Eclipse) Note: when m2e is available, there is an m2 icon in Help -> About dialog. -If m2e is not there, just follow the install process here: http://eclipse.org/m2e/download/ +If m2e is not there, just follow the install process here: http://www.eclipse.org/m2e/m2e-downloads.html ### Steps: From d568bcaf0bdb9d84ce1b60711dabcbbca5c94974 Mon Sep 17 00:00:00 2001 From: Alan Drozd Date: Tue, 10 Apr 2018 21:15:07 +0200 Subject: [PATCH 026/131] Fix including template in layout fragment Closes gh-319 --- src/main/resources/templates/fragments/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/fragments/layout.html b/src/main/resources/templates/fragments/layout.html index c9094b2f0..7cb5f4697 100755 --- a/src/main/resources/templates/fragments/layout.html +++ b/src/main/resources/templates/fragments/layout.html @@ -71,7 +71,7 @@
-
+

From 6905e38c1f58b05ff148d8b840f47f64efd01415 Mon Sep 17 00:00:00 2001 From: trisberg Date: Sat, 12 May 2018 12:28:44 -0400 Subject: [PATCH 027/131] Make MySQL configuration files/docs consistent - use petclinic as the db name and root password Fixes #322 --- docker-compose.yml | 8 ++++---- src/main/resources/application-mysql.properties | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1631ec9fa..0f4a7fc30 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ mysql: - image: mysql + image: mysql:5.7 ports: - "3306:3306" environment: - - MYSQL_ROOT_PASSWORD=root - - MYSQL_DATABASE=test + - MYSQL_ROOT_PASSWORD=petclinic + - MYSQL_DATABASE=petclinic volumes: - - "./conf.d:/etc/mysql/conf.d:ro" \ No newline at end of file + - "./conf.d:/etc/mysql/conf.d:ro" diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index c2c654fe4..823b32b69 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -1,7 +1,7 @@ # database init, supports mysql too database=mysql -spring.datasource.url=jdbc:mysql://localhost/test +spring.datasource.url=jdbc:mysql://localhost/petclinic spring.datasource.username=root -spring.datasource.password=root +spring.datasource.password=petclinic # Uncomment this the first time the app runs # spring.datasource.initialization-mode=always From 8eb5074770eb8d943e0aee0bcdc28f62149e7344 Mon Sep 17 00:00:00 2001 From: Aiden-at-508687582768 Date: Sun, 27 May 2018 01:40:43 -0400 Subject: [PATCH 028/131] Fix content negotiation for /vets See gh-326 --- .../springframework/samples/petclinic/vet/VetController.java | 2 +- src/main/resources/templates/vets/vetList.html | 3 +-- .../samples/petclinic/vet/VetControllerTests.java | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index 7ce8374ec..562bbfca3 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -48,7 +48,7 @@ class VetController { return "vets/vetList"; } - @GetMapping({ "/vets.json", "/vets.xml" }) + @GetMapping({ "/vets" }) public @ResponseBody Vets showResourcesVetList() { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for JSon/Object mapping diff --git a/src/main/resources/templates/vets/vetList.html b/src/main/resources/templates/vets/vetList.html index 842411ecd..4c1c1c9f3 100644 --- a/src/main/resources/templates/vets/vetList.html +++ b/src/main/resources/templates/vets/vetList.html @@ -26,8 +26,7 @@ - - +
View as XMLView as JSONView as XML
diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index ce6adf8e0..bc3b6c0a7 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -65,7 +65,7 @@ public class VetControllerTests { @Test public void testShowResourcesVetList() throws Exception { - ResultActions actions = mockMvc.perform(get("/vets.json").accept(MediaType.APPLICATION_JSON)) + ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); actions.andExpect(content().contentType("application/json;charset=UTF-8")) .andExpect(jsonPath("$.vetList[0].id").value(1)); @@ -73,7 +73,7 @@ public class VetControllerTests { @Test public void testShowVetListXml() throws Exception { - mockMvc.perform(get("/vets.xml").accept(MediaType.APPLICATION_XML)) + mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_XML)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_XML_VALUE)) .andExpect(content().node(hasXPath("/vets/vetList[id=1]/id"))); From eebca43df803aeb08754f43a86d6996630063500 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 4 Jun 2018 10:48:39 +0200 Subject: [PATCH 029/131] Polish "Fix content negotiation for /vets" Closes gh-326 --- .../samples/petclinic/vet/VetController.java | 2 +- src/main/resources/templates/vets/vetList.html | 7 ------- .../samples/petclinic/vet/VetControllerTests.java | 8 ++------ 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index 562bbfca3..1bc9e22f7 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 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. diff --git a/src/main/resources/templates/vets/vetList.html b/src/main/resources/templates/vets/vetList.html index 4c1c1c9f3..1961ad405 100644 --- a/src/main/resources/templates/vets/vetList.html +++ b/src/main/resources/templates/vets/vetList.html @@ -23,12 +23,5 @@ - - - - - -
View as XML
- diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index bc3b6c0a7..bd20ca79a 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -17,10 +17,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.vet.Specialty; -import org.springframework.samples.petclinic.vet.Vet; -import org.springframework.samples.petclinic.vet.VetController; -import org.springframework.samples.petclinic.vet.VetRepository; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; @@ -65,8 +61,8 @@ public class VetControllerTests { @Test public void testShowResourcesVetList() throws Exception { - ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); + ResultActions actions = mockMvc.perform(get("/vets") + .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); actions.andExpect(content().contentType("application/json;charset=UTF-8")) .andExpect(jsonPath("$.vetList[0].id").value(1)); } From 4d6ee8410dd4b1d4a672982bec968519fa196eb8 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 4 Jun 2018 10:49:45 +0200 Subject: [PATCH 030/131] Upgrade to Spring Boot 2.0.2.RELEASE --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b8f9c273..9bf98447b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.RELEASE + 2.0.2.RELEASE petclinic From 5270246eb587ca4837889aefb37f26b8019aca4f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 4 Jun 2018 10:54:27 +0200 Subject: [PATCH 031/131] Polish --- .../samples/petclinic/PetClinicApplication.java | 6 +++--- .../samples/petclinic/owner/OwnerController.java | 4 +--- .../samples/petclinic/owner/PetController.java | 4 +--- .../samples/petclinic/owner/VisitController.java | 4 +--- .../samples/petclinic/vet/VetController.java | 4 +--- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index 224c326c7..83b118095 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2012-2018 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. @@ -21,14 +21,14 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; /** * PetClinic Spring Boot Application. - * + * * @author Dave Syer * */ @SpringBootApplication public class PetClinicApplication { - public static void main(String[] args) throws Exception { + public static void main(String[] args) { SpringApplication.run(PetClinicApplication.class, args); } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index d914ed745..5d11bff4c 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2018 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. @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.owner; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -43,7 +42,6 @@ class OwnerController { private final OwnerRepository owners; - @Autowired public OwnerController(OwnerRepository clinicService) { this.owners = clinicService; } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java index 9c52e0309..e0c1feeed 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2018 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. @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.owner; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; @@ -39,7 +38,6 @@ class PetController { private final PetRepository pets; private final OwnerRepository owners; - @Autowired public PetController(PetRepository pets, OwnerRepository owners) { this.pets = pets; this.owners = owners; diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index d7afed12e..19e42c78e 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2018 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. @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.owner; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; @@ -40,7 +39,6 @@ class VisitController { private final PetRepository pets; - @Autowired public VisitController(VisitRepository visits, PetRepository pets) { this.visits = visits; this.pets = pets; diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index 1bc9e22f7..c54b3b92d 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2012-2018 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. @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.vet; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -33,7 +32,6 @@ class VetController { private final VetRepository vets; - @Autowired public VetController(VetRepository clinicService) { this.vets = clinicService; } From 38bd3280cbb765c5e3045f646f9c09523d0ba051 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 20 Jun 2018 13:58:30 +0100 Subject: [PATCH 032/131] Update to Boot 2.0.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9bf98447b..70820e046 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.2.RELEASE + 2.0.3.RELEASE petclinic From c0748e3e8224ab91bb7fea41a5bc0c71158e2ce8 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Wed, 27 Jun 2018 18:34:37 +0200 Subject: [PATCH 033/131] Use Java 8 LocalDate instead of java.util.Date See gh-328 --- .../samples/petclinic/owner/Pet.java | 11 ++++------- .../samples/petclinic/visit/Visit.java | 13 +++++-------- .../resources/templates/owners/ownerDetails.html | 6 +++--- .../templates/pets/createOrUpdateVisitForm.html | 6 +++--- .../petclinic/service/ClinicServiceTests.java | 4 ++-- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java index 5e226a180..795e2a94e 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -15,9 +15,9 @@ */ package org.springframework.samples.petclinic.owner; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -31,8 +31,6 @@ 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; @@ -52,9 +50,8 @@ import org.springframework.samples.petclinic.visit.Visit; public class Pet extends NamedEntity { @Column(name = "birth_date") - @Temporal(TemporalType.DATE) @DateTimeFormat(pattern = "yyyy-MM-dd") - private Date birthDate; + private LocalDate birthDate; @ManyToOne @JoinColumn(name = "type_id") @@ -67,11 +64,11 @@ public class Pet extends NamedEntity { @OneToMany(cascade = CascadeType.ALL, mappedBy = "petId", fetch = FetchType.EAGER) private Set visits = new LinkedHashSet<>(); - public void setBirthDate(Date birthDate) { + public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; } - public Date getBirthDate() { + public LocalDate getBirthDate() { return this.birthDate; } diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index ce10d7b12..d21f60dfc 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -15,13 +15,11 @@ */ package org.springframework.samples.petclinic.visit; -import java.util.Date; +import java.time.LocalDate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; import javax.validation.constraints.NotEmpty; import org.springframework.format.annotation.DateTimeFormat; @@ -38,9 +36,8 @@ import org.springframework.samples.petclinic.model.BaseEntity; public class Visit extends BaseEntity { @Column(name = "visit_date") - @Temporal(TemporalType.TIMESTAMP) @DateTimeFormat(pattern = "yyyy-MM-dd") - private Date date; + private LocalDate date; @NotEmpty @Column(name = "description") @@ -53,14 +50,14 @@ public class Visit extends BaseEntity { * Creates a new instance of Visit for the current date */ public Visit() { - this.date = new Date(); + this.date = LocalDate.now(); } - public Date getDate() { + public LocalDate getDate() { return this.date; } - public void setDate(Date date) { + public void setDate(LocalDate date) { this.date = date; } diff --git a/src/main/resources/templates/owners/ownerDetails.html b/src/main/resources/templates/owners/ownerDetails.html index 746d569be..ed89462b3 100644 --- a/src/main/resources/templates/owners/ownerDetails.html +++ b/src/main/resources/templates/owners/ownerDetails.html @@ -47,7 +47,7 @@
Birth Date
+ th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}" />
Type
@@ -61,7 +61,7 @@ - + @@ -80,4 +80,4 @@ - \ No newline at end of file + diff --git a/src/main/resources/templates/pets/createOrUpdateVisitForm.html b/src/main/resources/templates/pets/createOrUpdateVisitForm.html index 4401d36ce..609a735f9 100644 --- a/src/main/resources/templates/pets/createOrUpdateVisitForm.html +++ b/src/main/resources/templates/pets/createOrUpdateVisitForm.html @@ -21,7 +21,7 @@ + th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}" /> @@ -52,10 +52,10 @@ Description - + - \ No newline at end of file + diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index 7ed5bf8a5..6ea694120 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -2,8 +2,8 @@ package org.springframework.samples.petclinic.service; import static org.assertj.core.api.Assertions.assertThat; +import java.time.LocalDate; import java.util.Collection; -import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; @@ -140,7 +140,7 @@ public class ClinicServiceTests { pet.setName("bowser"); Collection types = this.pets.findPetTypes(); pet.setType(EntityUtils.getById(types, PetType.class, 2)); - pet.setBirthDate(new Date()); + pet.setBirthDate(LocalDate.now()); owner6.addPet(pet); assertThat(owner6.getPets().size()).isEqualTo(found + 1); From 4c22d010ea92796f61be2d814ebc3c03beb9d4cf Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 9 Jul 2018 16:47:34 +0200 Subject: [PATCH 034/131] Polish "Use Java 8 LocalDate instead of java.util.Date" Closes gh-328 --- .../samples/petclinic/owner/Pet.java | 2 +- .../samples/petclinic/visit/Visit.java | 2 +- .../petclinic/service/ClinicServiceTests.java | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java index 795e2a94e..c225b8d8a 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 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. diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index d21f60dfc..ab6e3319c 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 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. diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index 6ea694120..9f12151d9 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2018 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.service; import static org.assertj.core.api.Assertions.assertThat; From e7eabca111bfc9eb6909767f41992e9b67c941c1 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Thu, 5 Jul 2018 17:05:41 +0200 Subject: [PATCH 035/131] Adapt JMeter script to recent changes Closes gh-330 --- src/test/jmeter/petclinic_test_plan.jmx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/jmeter/petclinic_test_plan.jmx b/src/test/jmeter/petclinic_test_plan.jmx index 5e942b138..0a9a3a5f9 100644 --- a/src/test/jmeter/petclinic_test_plan.jmx +++ b/src/test/jmeter/petclinic_test_plan.jmx @@ -135,7 +135,7 @@ - ${CONTEXT_WEB}/vendors/jquery/jquery.js + ${CONTEXT_WEB}/webjars/jquery/jquery.min.js GET true false @@ -175,7 +175,7 @@ - ${CONTEXT_WEB}/owners/find.html + ${CONTEXT_WEB}/owners/find GET true false @@ -195,7 +195,7 @@ - ${CONTEXT_WEB}/owners.html?lastName= + ${CONTEXT_WEB}/owners?lastName= GET true false @@ -215,7 +215,7 @@ - ${CONTEXT_WEB}/owners/${count}.html + ${CONTEXT_WEB}/owners/${count} GET true false @@ -235,7 +235,7 @@ - ${CONTEXT_WEB}/owners/${count}/edit.html + ${CONTEXT_WEB}/owners/${count}/edit GET true false @@ -262,7 +262,7 @@ - ${CONTEXT_WEB}/owners/${count}/edit.html + ${CONTEXT_WEB}/owners/${count}/edit POST true false @@ -329,7 +329,7 @@ - ${CONTEXT_WEB}/owners/${count}.html + ${CONTEXT_WEB}/owners/${count} GET true false From 415bd73893f2cfec1135c484491193fac0c87bbe Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 10 Jul 2018 08:43:13 +0200 Subject: [PATCH 036/131] Fix devtools module declaration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 70820e046..793e39e1a 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ org.springframework.boot spring-boot-devtools - runtime + true From 5ff057d90baf36d40bdf81b69752143dc46782ee Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 10 Jul 2018 08:50:58 +0200 Subject: [PATCH 037/131] Remove misleading production profile Closes gh-333 --- .../samples/petclinic/system/CacheConfig.java | 5 --- src/main/resources/application.properties | 3 -- .../petclinic/PetclinicIntegrationTests.java | 39 +++++++++++++++++++ .../system/ProductionConfigurationTests.java | 23 ----------- 4 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java delete mode 100644 src/test/java/org/springframework/samples/petclinic/system/ProductionConfigurationTests.java diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java index 13e194c35..ff71d5c98 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java @@ -6,14 +6,9 @@ import javax.cache.configuration.MutableConfiguration; import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Profile; -/** - * Cache could be disabled in unit test. - */ @org.springframework.context.annotation.Configuration @EnableCaching -@Profile("production") class CacheConfig { @Bean diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c8d5a5c1a..ffaf41f23 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -20,6 +20,3 @@ management.endpoints.web.exposure.include=* logging.level.org.springframework=INFO # logging.level.org.springframework.web=DEBUG # logging.level.org.springframework.context.annotation=TRACE - -# Active Spring profiles -spring.profiles.active=production diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java new file mode 100644 index 000000000..3f48c0d4a --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2018 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; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.samples.petclinic.vet.VetRepository; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class PetclinicIntegrationTests { + + @Autowired + private VetRepository vets; + + @Test + public void testFindAll() throws Exception { + vets.findAll(); + vets.findAll(); // served from cache + } +} diff --git a/src/test/java/org/springframework/samples/petclinic/system/ProductionConfigurationTests.java b/src/test/java/org/springframework/samples/petclinic/system/ProductionConfigurationTests.java deleted file mode 100644 index 9636e3623..000000000 --- a/src/test/java/org/springframework/samples/petclinic/system/ProductionConfigurationTests.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.springframework.samples.petclinic.system; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.samples.petclinic.vet.VetRepository; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class ProductionConfigurationTests { - - @Autowired - private VetRepository vets; - - @Test - public void testFindAll() throws Exception { - vets.findAll(); - vets.findAll(); // served from cache - } -} From 3c9afdc138bd120e8396aacadb2da2d55e462f8a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 10 Jul 2018 08:55:27 +0200 Subject: [PATCH 038/131] Polish --- ...acheConfig.java => CacheConfiguration.java} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename src/main/java/org/springframework/samples/petclinic/system/{CacheConfig.java => CacheConfiguration.java} (50%) diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java similarity index 50% rename from src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java rename to src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index ff71d5c98..e4d7b4242 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -1,27 +1,27 @@ package org.springframework.samples.petclinic.system; -import javax.cache.configuration.Configuration; import javax.cache.configuration.MutableConfiguration; import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; -@org.springframework.context.annotation.Configuration +@Configuration @EnableCaching -class CacheConfig { +class CacheConfiguration { @Bean - public JCacheManagerCustomizer cacheManagerCustomizer() { + public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { return cm -> { - Configuration cacheConfiguration = createCacheConfiguration(); - cm.createCache("vets", cacheConfiguration); + cm.createCache("vets", cacheConfiguration()); }; } - private Configuration createCacheConfiguration() { - // Create a cache using infinite heap. A real application will want to use an - // implementation dependent configuration that will better fit your needs + private javax.cache.configuration.Configuration cacheConfiguration() { + // Create a cache using infinite heap. A real application will want to use a more fine-grained configuration, + // possibly using an implementation-dependent API return new MutableConfiguration<>().setStatisticsEnabled(true); } + } From 46babdad7c0b82416f5a6781daf527fa8a454656 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Tue, 10 Jul 2018 08:32:03 +0200 Subject: [PATCH 039/131] Enable caching of static resources See gh-332 --- src/main/resources/application.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ffaf41f23..f9c02d188 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -20,3 +20,6 @@ management.endpoints.web.exposure.include=* logging.level.org.springframework=INFO # logging.level.org.springframework.web=DEBUG # logging.level.org.springframework.context.annotation=TRACE + +# Maximum time the static resources (css, js, fonts and images) should be cached +spring.resources.cache.cachecontrol.max-age=12h From 895422b8c8ddb1d0f94a51da2c66a3c86b09e930 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 10 Jul 2018 09:10:03 +0200 Subject: [PATCH 040/131] Polish "Enable caching of static resources" Closes gh-332 --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f9c02d188..b93ff4de3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -21,5 +21,5 @@ logging.level.org.springframework=INFO # logging.level.org.springframework.web=DEBUG # logging.level.org.springframework.context.annotation=TRACE -# Maximum time the static resources (css, js, fonts and images) should be cached +# Maximum time static resources should be cached spring.resources.cache.cachecontrol.max-age=12h From 02ef5939f93fdd6e7d418fde915e906c5b41c70c Mon Sep 17 00:00:00 2001 From: Jens Wilke Date: Thu, 12 Jul 2018 14:02:22 +0200 Subject: [PATCH 041/131] Fix wrong link for CacheConfiguration Closes gh-334 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 66aee0c28..29565ec43 100644 --- a/readme.md +++ b/readme.md @@ -60,7 +60,7 @@ File -> Import -> Maven -> Existing Maven project |--------------------------|---| |The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) | |Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources) | -|Caching | [CacheConfig](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java) | +|Caching | [CacheConfiguration](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) | ## Interesting Spring Petclinic branches and forks From 22ff39853d7c53a4e13319729275f0e8cdae2c99 Mon Sep 17 00:00:00 2001 From: Jens Wilke Date: Thu, 12 Jul 2018 14:14:28 +0200 Subject: [PATCH 042/131] Clarify cache configuration See gh-335 --- .../petclinic/system/CacheConfiguration.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index e4d7b4242..adde2bebd 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -7,10 +7,38 @@ import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Cache configuration intended for caches providing the JCache API. This configuration + * creates the used cache for the application and enables statistics that + * become accessible via JMX. + * + *

This is a minimal configuration that makes use of the JCache API to enable + * caching with any JCache implementation out of the box. The utilized JCache implementation + * is specified by the dependency in the {@code pom.xml}. + * + *

If the used cache implementation is configured via its specific and non standard mechanism, + * this example configuration might be redundant and can be removed or replaced by + * a programmatic configuration via the implementation specific methods. + * + *

In case no programmatic cache configuration is needed for the selected caching + * implementation this configuration class can be removed and the {@link EnableCaching} + * annotation can be put on the application class. + * + * @author Jens Wilke + */ @Configuration @EnableCaching class CacheConfiguration { + /** + * A customizer that creates the the cache used by the application. + * This implies that the cache is not existent before the application start and the + * cache must be created. This is the default behavior of a JCache implemenation, in case + * no additional configuration is present and typically will create a transient in memory cache. + * If a persistent cache implementation is used, creating the cache on startup + * may lead to a failure, when the cache was created before. If the cache life time + * is controlled separately, the call of {@code createCache} must be removed. + */ @Bean public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { return cm -> { @@ -18,9 +46,14 @@ class CacheConfiguration { }; } + /** + * Enable statistics via the JCache programmatic configuration API. + * Within the configuration object that is provided by the JCache API standard, there is only + * a very limited set of configuration options. The really relevant configuration options + * (like the size limit) must be set via a configuration mechanism that is provided by the + * selected JCache implementation. + */ private javax.cache.configuration.Configuration cacheConfiguration() { - // Create a cache using infinite heap. A real application will want to use a more fine-grained configuration, - // possibly using an implementation-dependent API return new MutableConfiguration<>().setStatisticsEnabled(true); } From 893a18f595b24d518c1d5923ee64e8a41a64b7d3 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 13 Jul 2018 16:57:48 +0200 Subject: [PATCH 043/131] Polish "Clarify cache configuration" Closes gh-335 --- .../petclinic/system/CacheConfiguration.java | 42 ++++--------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index adde2bebd..f5f659482 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -1,44 +1,20 @@ package org.springframework.samples.petclinic.system; -import javax.cache.configuration.MutableConfiguration; - import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import javax.cache.configuration.MutableConfiguration; + /** - * Cache configuration intended for caches providing the JCache API. This configuration - * creates the used cache for the application and enables statistics that - * become accessible via JMX. - * - *

This is a minimal configuration that makes use of the JCache API to enable - * caching with any JCache implementation out of the box. The utilized JCache implementation - * is specified by the dependency in the {@code pom.xml}. - * - *

If the used cache implementation is configured via its specific and non standard mechanism, - * this example configuration might be redundant and can be removed or replaced by - * a programmatic configuration via the implementation specific methods. - * - *

In case no programmatic cache configuration is needed for the selected caching - * implementation this configuration class can be removed and the {@link EnableCaching} - * annotation can be put on the application class. - * - * @author Jens Wilke + * Cache configuration intended for caches providing the JCache API. This configuration creates the used cache for the + * application and enables statistics that become accessible via JMX. */ @Configuration @EnableCaching class CacheConfiguration { - /** - * A customizer that creates the the cache used by the application. - * This implies that the cache is not existent before the application start and the - * cache must be created. This is the default behavior of a JCache implemenation, in case - * no additional configuration is present and typically will create a transient in memory cache. - * If a persistent cache implementation is used, creating the cache on startup - * may lead to a failure, when the cache was created before. If the cache life time - * is controlled separately, the call of {@code createCache} must be removed. - */ @Bean public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { return cm -> { @@ -47,11 +23,11 @@ class CacheConfiguration { } /** - * Enable statistics via the JCache programmatic configuration API. - * Within the configuration object that is provided by the JCache API standard, there is only - * a very limited set of configuration options. The really relevant configuration options - * (like the size limit) must be set via a configuration mechanism that is provided by the - * selected JCache implementation. + * Create a simple configuration that enable statistics via the JCache programmatic configuration API. + *

+ * Within the configuration object that is provided by the JCache API standard, there is only a very limited set of + * configuration options. The really relevant configuration options (like the size limit) must be set via a + * configuration mechanism that is provided by the selected JCache implementation. */ private javax.cache.configuration.Configuration cacheConfiguration() { return new MutableConfiguration<>().setStatisticsEnabled(true); From 73c9ac5acbe8d333b30d4445a9cf4bacffd0a009 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 9 Aug 2018 10:12:57 +0200 Subject: [PATCH 044/131] Upgrade to Spring Boot 2.0.4.RELEASE --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 793e39e1a..b4d2190b1 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.3.RELEASE + 2.0.4.RELEASE petclinic From 60105d5d9a8b64d29927b98cd06d6d811fd4bb52 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 9 Aug 2018 10:47:13 +0200 Subject: [PATCH 045/131] Use Jacoco rather than cobertura --- pom.xml | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/pom.xml b/pom.xml index b4d2190b1..0469ceaf7 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 2.2.4 1.8.0 - 2.7 + 0.8.1 @@ -134,17 +134,20 @@ - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.version} - - - + org.jacoco + jacoco-maven-plugin + ${jacoco.version} - clean - check + prepare-agent + + + + report + prepare-package + + report @@ -201,22 +204,6 @@ - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.version} - - - html - - - - - - From e823df36578106e73db93bc8bfccd058d41764b5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 5 Oct 2018 11:36:56 +0100 Subject: [PATCH 046/131] Update to Spring Boot 2.1 --- .mvn/wrapper/maven-wrapper.properties | 2 +- pom.xml | 30 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 25cc8af3c..6c8c0e080 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip diff --git a/pom.xml b/pom.xml index 0469ceaf7..70bb29209 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.0.0.BUILD-SNAPSHOT + 2.1.0.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.0.4.RELEASE + 2.1.0.BUILD-SNAPSHOT petclinic @@ -27,7 +27,7 @@ 2.2.4 1.8.0 - 0.8.1 + 0.8.2 @@ -200,6 +200,11 @@ bootstrap ${webjars-bootstrap.version} + + org.mockito + mockito-core + ${mockito.version} + @@ -213,4 +218,23 @@ + + + java11+ + + [11,) + + + + javax.xml.bind + jaxb-api + + + org.glassfish.jaxb + jaxb-runtime + + + + + From b982e66834c5b76c5bd978086bc74c8623d3f272 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 5 Oct 2018 15:38:11 +0100 Subject: [PATCH 047/131] Clarify docs on MySql and STS --- readme.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 29565ec43..05bbbe986 100644 --- a/readme.md +++ b/readme.md @@ -22,9 +22,9 @@ Our issue tracker is available here: https://github.com/spring-projects/spring-p In its default configuration, Petclinic uses an in-memory database (HSQLDB) which gets populated at startup with data. A similar setup is provided for MySql in case a persistent database configuration is needed. -Note that whenever the database type is changed, the data-access.properties file needs to be updated and the mysql-connector-java artifact from the pom.xml needs to be uncommented. +Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. -You could start a MySql database with docker: +You could start MySql locally with whatever installer works for your OS, or with docker: ``` docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 @@ -34,7 +34,7 @@ docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306: ### prerequisites The following items should be installed in your system: -* Apache Maven (https://maven.apache.org/install.html) +* Java 8 or newer. * git command line tool (https://help.github.com/articles/set-up-git) * Eclipse with the m2e plugin (m2e is installed by default when using the STS (http://www.springsource.org/sts) distribution of Eclipse) @@ -53,6 +53,8 @@ git clone https://github.com/spring-projects/spring-petclinic.git File -> Import -> Maven -> Existing Maven project ``` +Then either build on the command line `./mvnw install` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. Visit [http://localhost:8080](http://localhost:8080) in your browser. + ## Looking for something in particular? From 1feea1f44177901bd87ef53ba2c06445316a863c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 6 Oct 2018 16:37:33 +0200 Subject: [PATCH 048/131] Polish --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 70bb29209..338cefa32 100644 --- a/pom.xml +++ b/pom.xml @@ -225,10 +225,6 @@ [11,) - - javax.xml.bind - jaxb-api - org.glassfish.jaxb jaxb-runtime From d49cc42ae5b0bb7532edeb96686959aeb2cad5dd Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 6 Oct 2018 16:40:10 +0200 Subject: [PATCH 049/131] Add missing repository definition --- pom.xml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pom.xml b/pom.xml index 338cefa32..1f7b9a263 100644 --- a/pom.xml +++ b/pom.xml @@ -233,4 +233,42 @@ + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + From 895730caf9699fa7a258594678c28bd3acca44e8 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 7 Oct 2018 13:40:45 +0200 Subject: [PATCH 050/131] Simplify build definition --- pom.xml | 15 --------------- .../samples/petclinic/vet/VetControllerTests.java | 9 --------- 2 files changed, 24 deletions(-) diff --git a/pom.xml b/pom.xml index 1f7b9a263..12462197e 100644 --- a/pom.xml +++ b/pom.xml @@ -218,21 +218,6 @@ - - - java11+ - - [11,) - - - - org.glassfish.jaxb - jaxb-runtime - - - - - spring-snapshots diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index bd20ca79a..21f2edaa4 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -1,6 +1,5 @@ package org.springframework.samples.petclinic.vet; -import static org.hamcrest.xml.HasXPath.hasXPath; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -67,12 +66,4 @@ public class VetControllerTests { .andExpect(jsonPath("$.vetList[0].id").value(1)); } - @Test - public void testShowVetListXml() throws Exception { - mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_XML)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_XML_VALUE)) - .andExpect(content().node(hasXPath("/vets/vetList[id=1]/id"))); - } - } From f31ead5f7953aa0d8096eb4b531d4b442f257322 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 8 Oct 2018 09:05:39 +0100 Subject: [PATCH 051/131] Add notes on building a jar See #339 --- readme.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 05bbbe986..25c7d6f88 100644 --- a/readme.md +++ b/readme.md @@ -4,16 +4,26 @@ See the presentation here ## Running petclinic locally +Petclinic is a https://spring.io/guides/gs/spring-boot[Spring Boot] application built using https://spring.io/guides/gs/maven/[Maven]. You can build a jar file and run it from the command line: + + ``` git clone https://github.com/spring-projects/spring-petclinic.git cd spring-petclinic - ./mvnw spring-boot:run + ./mvnw package + java -jar target/*.jar ``` You can then access petclinic here: http://localhost:8080/ petclinic-screenshot +Or you can run it from Maven directly using the Spring Boot Maven plugin. If you do this it will pick up changes that you make in the project immediately (changes to Java source files require a compile as well - most people use an IDE for this): + +``` + ./mvnw spring-boot:run +``` + ## In case you find a bug/suggested improvement for Spring Petclinic Our issue tracker is available here: https://github.com/spring-projects/spring-petclinic/issues From e0684bfd5e3adb1815e32675f384085644dad076 Mon Sep 17 00:00:00 2001 From: Olivier Truong Date: Mon, 8 Oct 2018 21:50:50 +0200 Subject: [PATCH 052/131] Fix indent in readme.md Closes gh-359 --- readme.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 25c7d6f88..b6fd602bc 100644 --- a/readme.md +++ b/readme.md @@ -8,10 +8,10 @@ Petclinic is a https://spring.io/guides/gs/spring-boot[Spring Boot] application ``` - git clone https://github.com/spring-projects/spring-petclinic.git - cd spring-petclinic - ./mvnw package - java -jar target/*.jar +git clone https://github.com/spring-projects/spring-petclinic.git +cd spring-petclinic +./mvnw package +java -jar target/*.jar ``` You can then access petclinic here: http://localhost:8080/ @@ -21,7 +21,7 @@ You can then access petclinic here: http://localhost:8080/ Or you can run it from Maven directly using the Spring Boot Maven plugin. If you do this it will pick up changes that you make in the project immediately (changes to Java source files require a compile as well - most people use an IDE for this): ``` - ./mvnw spring-boot:run +./mvnw spring-boot:run ``` ## In case you find a bug/suggested improvement for Spring Petclinic From 6de956210e7b72d527d49e0d375d7b2311dbde59 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Mon, 8 Oct 2018 10:10:41 +0200 Subject: [PATCH 053/131] Add documentation for IntelliJ IDEA See gh-358 --- readme.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/readme.md b/readme.md index b6fd602bc..bc4111c42 100644 --- a/readme.md +++ b/readme.md @@ -40,17 +40,16 @@ You could start MySql locally with whatever installer works for your OS, or with docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 ``` -## Working with Petclinic in Eclipse/STS +## Working with Petclinic in your IDE ### prerequisites The following items should be installed in your system: * Java 8 or newer. * git command line tool (https://help.github.com/articles/set-up-git) -* Eclipse with the m2e plugin (m2e is installed by default when using the STS (http://www.springsource.org/sts) distribution of Eclipse) - -Note: when m2e is available, there is an m2 icon in Help -> About dialog. -If m2e is not there, just follow the install process here: http://www.eclipse.org/m2e/m2e-downloads.html - +* Your prefered IDE + * Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in Help -> About dialog. If m2e is not there, just follow the install process here: http://www.eclipse.org/m2e/ + * or [Spring Tools Suite](https://spring.io/tools) (STS) + * or IntelliJ IDEA ### Steps: @@ -58,12 +57,22 @@ If m2e is not there, just follow the install process here: http://www.eclipse.or ``` git clone https://github.com/spring-projects/spring-petclinic.git ``` -2) Inside Eclipse +2) Inside Eclipse or STS ``` File -> Import -> Maven -> Existing Maven project ``` -Then either build on the command line `./mvnw install` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. Visit [http://localhost:8080](http://localhost:8080) in your browser. +Then either build on the command line `./mvnw install` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. + +3) Or inside IntelliJ IDEA + +On the main menu, select `File -> Open`. Select the Petclinic [pom.xml](pom.xml). Click on the `Open as Project` button. +Then either build on the command line `./mvnw install` or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders` to generate the CSS. +Run the application by right clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`. + +4) Navigate to Petclinic + +Visit [http://localhost:8080](http://localhost:8080) in your browser. ## Looking for something in particular? From 8bee2f888db7c7347cd419fe61064398f7a93ee6 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 9 Oct 2018 08:44:25 +0200 Subject: [PATCH 054/131] Polish "Add documentation for IntelliJ IDEA" Closes gh-358 --- readme.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/readme.md b/readme.md index bc4111c42..42ee7376a 100644 --- a/readme.md +++ b/readme.md @@ -48,12 +48,12 @@ The following items should be installed in your system: * git command line tool (https://help.github.com/articles/set-up-git) * Your prefered IDE * Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in Help -> About dialog. If m2e is not there, just follow the install process here: http://www.eclipse.org/m2e/ - * or [Spring Tools Suite](https://spring.io/tools) (STS) - * or IntelliJ IDEA + * [Spring Tools Suite](https://spring.io/tools) (STS) + * IntelliJ IDEA ### Steps: -1) In the command line +1) On the command line ``` git clone https://github.com/spring-projects/spring-petclinic.git ``` @@ -62,13 +62,18 @@ git clone https://github.com/spring-projects/spring-petclinic.git File -> Import -> Maven -> Existing Maven project ``` -Then either build on the command line `./mvnw install` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. +Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. -3) Or inside IntelliJ IDEA +3) Inside IntelliJ IDEA -On the main menu, select `File -> Open`. Select the Petclinic [pom.xml](pom.xml). Click on the `Open as Project` button. -Then either build on the command line `./mvnw install` or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders` to generate the CSS. -Run the application by right clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`. +In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button. + +CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` +or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`. + +A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate +version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing +`Run 'PetClinicApplication'`. 4) Navigate to Petclinic From 3b36b80741187865ddd4347b7cc13b1b3c041d51 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 22 Oct 2018 14:59:52 +0200 Subject: [PATCH 055/131] Add reference to Spring Petclinic Forks See gh-361 --- readme.md | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/readme.md b/readme.md index 42ee7376a..598b626bb 100644 --- a/readme.md +++ b/readme.md @@ -90,26 +90,11 @@ Visit [http://localhost:8080](http://localhost:8080) in your browser. ## Interesting Spring Petclinic branches and forks -The Spring Petclinic master branch in the main -[spring-projects](https://github.com/spring-projects/spring-petclinic) -GitHub org is the "canonical" implementation, currently based on -Spring Boot and Thymeleaf. There are quite a few forks in a special -GitHub org [spring-petclinic](https://github.com/spring-petclinic). If -you have a special interest in a different technology stack that could -be used to implement the Pet Clinic then please join the community -there. - -| Link | Main technologies | -|------------------------------------|-------------------| -| [spring-framework-petclinic][] | Spring Framework XML configuration, JSP pages, 3 persistence layers: JDBC, JPA and Spring Data JPA | -| [javaconfig branch][] | Same frameworks as the [spring-framework-petclinic][] but with Java Configuration instead of XML | -| [spring-petclinic-angularjs][] | AngularJS 1.x, Spring Boot and Spring Data JPA | -| [spring-petclinic-angular][] | Angular 4 front-end of the Petclinic REST API [spring-petclinic-rest][] | -| [spring-petclinic-microservices][] | Distributed version of Spring Petclinic built with Spring Cloud | -| [spring-petclinic-reactjs][] | ReactJS (with TypeScript) and Spring Boot | -| [spring-petclinic-graphql][] | GraphQL version based on React Appolo, TypeScript and GraphQL Spring boot starter | -| [spring-petclinic-kotlin][] | Kotlin version of [spring-petclinic][] | -| [spring-petclinic-rest][] | Backend REST API | +The Spring Petclinic master branch in the main [spring-projects](https://github.com/spring-projects/spring-petclinic) +GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are +[quite a few forks](https://spring-petclinic.github.io/docs/forks.html) in a special GitHub org +[spring-petclinic](https://github.com/spring-petclinic). If you have a special interest in a different technology stack +that could be used to implement the Pet Clinic then please join the community there. ## Interaction with other open source projects From 8869750c25611f05db2ba86f6c0cf5fd5092df84 Mon Sep 17 00:00:00 2001 From: figueroaRicardo <41128440+figueroaRicardo@users.noreply.github.com> Date: Wed, 7 Nov 2018 11:37:14 -0600 Subject: [PATCH 056/131] Fix links Closes gh-369 --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 598b626bb..cf6d1aa7f 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ See the presentation here ## Running petclinic locally -Petclinic is a https://spring.io/guides/gs/spring-boot[Spring Boot] application built using https://spring.io/guides/gs/maven/[Maven]. You can build a jar file and run it from the command line: +Petclinic is a [Spring Boot](https://spring.io/guides/gs/spring-boot) application built using [Maven](https://spring.io/guides/gs/maven/). You can build a jar file and run it from the command line: ``` @@ -42,7 +42,7 @@ docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306: ## Working with Petclinic in your IDE -### prerequisites +### Prerequisites The following items should be installed in your system: * Java 8 or newer. * git command line tool (https://help.github.com/articles/set-up-git) @@ -113,7 +113,7 @@ Here is a list of them: The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) is the preferred channel for bug reports, features requests and submitting pull requests. -For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . If you have not previously done so, please fill out and submit the https://cla.pivotal.io/sign/spring[Contributor License Agreement]. +For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . If you have not previously done so, please fill out and submit the [Contributor License Agreement](https://cla.pivotal.io/sign/spring). # License From 13f1bfb079210ace2fc1e460dfbb7aedcafdee8c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 15 Nov 2018 04:24:58 +0800 Subject: [PATCH 057/131] Update to Boot 2.1.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 12462197e..96ab1323e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.0.BUILD-SNAPSHOT + 2.1.0.RELEASE petclinic From df359ab1bc39b15fa7ba5144993a9c9f33f42a91 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 4 Dec 2018 13:53:23 +0000 Subject: [PATCH 058/131] Update to Boot 2.1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96ab1323e..b5378287e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.0.RELEASE + 2.1.1.RELEASE petclinic From ab567242851166983e5f0140ab7593fd04c7d365 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 17 Dec 2018 16:41:44 +0000 Subject: [PATCH 059/131] Remove redundant component scan filter The @DataJpaTests creates all the repositories. There's no need for a filter (and there aren't any matching @Service beans anyway). --- .gitignore | 2 ++ .../petclinic/service/ClinicServiceTests.java | 36 +++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 8cdbd1ff4..559982f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ target/* .settings/* .classpath .project +.factorypath +.attach_pid* .idea *.iml /target diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index 9f12151d9..b5626fae5 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -16,16 +16,14 @@ package org.springframework.samples.petclinic.service; -import static org.assertj.core.api.Assertions.assertThat; - import java.time.LocalDate; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.ComponentScan; import org.springframework.samples.petclinic.owner.Owner; import org.springframework.samples.petclinic.owner.OwnerRepository; import org.springframework.samples.petclinic.owner.Pet; @@ -35,22 +33,32 @@ import org.springframework.samples.petclinic.vet.Vet; import org.springframework.samples.petclinic.vet.VetRepository; import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; -import org.springframework.stereotype.Service; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; +import static org.assertj.core.api.Assertions.assertThat; + /** * Integration test of the Service and the Repository layer. *

- * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided by the Spring - * TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up - * time between test execution.
  • Dependency Injection of test fixture instances, meaning that - * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the {@link - * ClinicServiceTests#clinicService clinicService} instance variable, which uses autowiring by - * type.
  • Transaction management, meaning each test method is executed in its own transaction, - * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there - * is no need for a teardown or cleanup script.
  • An {@link org.springframework.context.ApplicationContext - * ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary.
+ * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided + * by the Spring TestContext Framework: + *

+ *
    + *
  • Spring IoC container caching which spares us unnecessary set up + * time between test execution.
  • + *
  • Dependency Injection of test fixture instances, meaning that we + * don't need to perform application context lookups. See the use of + * {@link Autowired @Autowired} on the {@link + * ClinicServiceTests#clinicService clinicService} instance variable, which uses + * autowiring by type. + *
  • Transaction management, meaning each test method is executed in + * its own transaction, which is automatically rolled back by default. Thus, even if tests + * insert or otherwise change database state, there is no need for a teardown or cleanup + * script. + *
  • An {@link org.springframework.context.ApplicationContext ApplicationContext} is + * also inherited and can be used for explicit bean lookup if necessary.
  • + *
* * @author Ken Krebs * @author Rod Johnson @@ -61,7 +69,7 @@ import org.springframework.transaction.annotation.Transactional; */ @RunWith(SpringRunner.class) -@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) +@DataJpaTest public class ClinicServiceTests { @Autowired From dbbd3ea80e896ac9f64d15ab302d194b10cb7364 Mon Sep 17 00:00:00 2001 From: Mustafa Ulu Date: Sun, 13 Jan 2019 11:03:02 +0300 Subject: [PATCH 060/131] Remove SonarQube configuration file Closes gh-383 --- sonar-project.properties | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100755 sonar-project.properties diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100755 index d84ed7c2d..000000000 --- a/sonar-project.properties +++ /dev/null @@ -1,13 +0,0 @@ -# Required metadata -sonar.projectKey=java-sonar-runner-simple -sonar.projectName=Simple Java project analyzed with the SonarQube Runner -sonar.projectVersion=1.0 - -# Comma-separated paths to directories with sources (required) -sonar.sources=src - -# Language -sonar.language=java - -# Encoding of the source files -sonar.sourceEncoding=UTF-8 \ No newline at end of file From 8472aa039ebd022065e1b66e97e2bab7f5b6b546 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 31 Jan 2019 11:30:16 +0100 Subject: [PATCH 061/131] Upgrade to Spring Boot 2.1.2.RELEASE --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b5378287e..8bce6c286 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.1.RELEASE + 2.1.2.RELEASE petclinic From 827dc12325c91a297952c7e55bbddd555ade5c81 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 11 Feb 2019 08:07:52 +0000 Subject: [PATCH 062/131] Revert "Remove redundant component scan filter" This reverts commit ab567242851166983e5f0140ab7593fd04c7d365. --- .gitignore | 2 -- .../petclinic/service/ClinicServiceTests.java | 36 ++++++++----------- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 559982f3d..8cdbd1ff4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,6 @@ target/* .settings/* .classpath .project -.factorypath -.attach_pid* .idea *.iml /target diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index b5626fae5..9f12151d9 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -16,14 +16,16 @@ package org.springframework.samples.petclinic.service; +import static org.assertj.core.api.Assertions.assertThat; + import java.time.LocalDate; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; import org.springframework.samples.petclinic.owner.Owner; import org.springframework.samples.petclinic.owner.OwnerRepository; import org.springframework.samples.petclinic.owner.Pet; @@ -33,32 +35,22 @@ import org.springframework.samples.petclinic.vet.Vet; import org.springframework.samples.petclinic.vet.VetRepository; import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; +import org.springframework.stereotype.Service; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; -import static org.assertj.core.api.Assertions.assertThat; - /** * Integration test of the Service and the Repository layer. *

- * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided - * by the Spring TestContext Framework: - *

- *
    - *
  • Spring IoC container caching which spares us unnecessary set up - * time between test execution.
  • - *
  • Dependency Injection of test fixture instances, meaning that we - * don't need to perform application context lookups. See the use of - * {@link Autowired @Autowired} on the {@link - * ClinicServiceTests#clinicService clinicService} instance variable, which uses - * autowiring by type. - *
  • Transaction management, meaning each test method is executed in - * its own transaction, which is automatically rolled back by default. Thus, even if tests - * insert or otherwise change database state, there is no need for a teardown or cleanup - * script. - *
  • An {@link org.springframework.context.ApplicationContext ApplicationContext} is - * also inherited and can be used for explicit bean lookup if necessary.
  • - *
+ * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided by the Spring + * TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up + * time between test execution.
  • Dependency Injection of test fixture instances, meaning that + * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the {@link + * ClinicServiceTests#clinicService clinicService} instance variable, which uses autowiring by + * type.
  • Transaction management, meaning each test method is executed in its own transaction, + * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there + * is no need for a teardown or cleanup script.
  • An {@link org.springframework.context.ApplicationContext + * ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary.
* * @author Ken Krebs * @author Rod Johnson @@ -69,7 +61,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ @RunWith(SpringRunner.class) -@DataJpaTest +@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) public class ClinicServiceTests { @Autowired From 91fa97102ff17280f6b00d65ebc8e4a6499b484a Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 11 Mar 2019 10:16:57 +0000 Subject: [PATCH 063/131] Update to latest Boot and add some gitignores --- .gitignore | 2 ++ pom.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8cdbd1ff4..559982f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ target/* .settings/* .classpath .project +.factorypath +.attach_pid* .idea *.iml /target diff --git a/pom.xml b/pom.xml index 8bce6c286..74ff0665b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.2.RELEASE + 2.1.3.RELEASE petclinic From eef57abd78533120f65b9d83c7d3b54a1b2bc5d7 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 19 Mar 2019 22:47:49 -0500 Subject: [PATCH 064/131] URL Cleanup Closes gh-396 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74ff0665b..bd21cc90a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.springframework.samples spring-petclinic From 0c59090c1a805923f01bebde87004a3d3e8948e8 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 20 Mar 2019 11:13:21 +0100 Subject: [PATCH 065/131] Polish --- readme.md | 5 +++-- .../samples/petclinic/owner/OwnerRepository.java | 5 +++-- .../samples/petclinic/owner/PetTypeFormatter.java | 7 ++----- src/main/resources/db/mysql/petclinic_db_setup_mysql.txt | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/readme.md b/readme.md index cf6d1aa7f..37d09817f 100644 --- a/readme.md +++ b/readme.md @@ -47,7 +47,8 @@ The following items should be installed in your system: * Java 8 or newer. * git command line tool (https://help.github.com/articles/set-up-git) * Your prefered IDE - * Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in Help -> About dialog. If m2e is not there, just follow the install process here: http://www.eclipse.org/m2e/ + * Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in `Help -> About` dialog. If m2e is + not there, just follow the install process here: https://www.eclipse.org/m2e/ * [Spring Tools Suite](https://spring.io/tools) (STS) * IntelliJ IDEA @@ -113,7 +114,7 @@ Here is a list of them: The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) is the preferred channel for bug reports, features requests and submitting pull requests. -For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . If you have not previously done so, please fill out and submit the [Contributor License Agreement](https://cla.pivotal.io/sign/spring). +For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . If you have not previously done so, please fill out and submit the [Contributor License Agreement](https://cla.pivotal.io/sign/spring). # License diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java index 068f5245d..61941e3b2 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 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. @@ -24,7 +24,8 @@ import org.springframework.transaction.annotation.Transactional; /** * Repository class for Owner domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data. + * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java index 78451ca28..ccca33913 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 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. @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.owner; - import java.text.ParseException; import java.util.Collection; import java.util.Locale; @@ -27,9 +26,7 @@ import org.springframework.stereotype.Component; /** * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The - * Spring ref doc: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#format-Formatter-SPI - * - A nice blog entry from Gordon Dickens: http://gordondickens.com/wordpress/2010/09/30/using-spring-3-0-custom-type-converter/ - *

+ * Spring ref doc: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format * * @author Mark Fisher * @author Juergen Hoeller diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index 6733a9337..d489a1744 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -9,7 +9,7 @@ -------------------------------------------------------------------------------- 1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), - which can be found here: http://dev.mysql.com/downloads/. Or run the + which can be found here: https://dev.mysql.com/downloads/. Or run the "docker-compose.yml" from the root of the project (if you have docker installed locally). From f4bed3cc17948bde8408e371bc58d5694534cefb Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Wed, 20 Mar 2019 22:15:09 -0500 Subject: [PATCH 066/131] URL Cleanup See gh-397 --- .../springframework/samples/petclinic/owner/PetRepository.java | 2 +- .../springframework/samples/petclinic/vet/VetRepository.java | 2 +- .../samples/petclinic/visit/VisitRepository.java | 2 +- src/main/resources/templates/error.html | 2 +- .../resources/templates/owners/createOrUpdateOwnerForm.html | 2 +- src/main/resources/templates/owners/findOwners.html | 2 +- src/main/resources/templates/owners/ownerDetails.html | 2 +- src/main/resources/templates/owners/ownersList.html | 2 +- src/main/resources/templates/pets/createOrUpdatePetForm.html | 2 +- src/main/resources/templates/pets/createOrUpdateVisitForm.html | 2 +- src/main/resources/templates/vets/vetList.html | 2 +- src/main/resources/templates/welcome.html | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java index b0ec5db23..5ad150af7 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java @@ -23,7 +23,7 @@ import org.springframework.transaction.annotation.Transactional; /** * Repository class for Pet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data See here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java index 20863ce76..c3594feee 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java @@ -24,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional; /** * Repository class for Vet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data See here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java index c7853d170..25a117e94 100644 --- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java @@ -23,7 +23,7 @@ import org.springframework.samples.petclinic.model.BaseEntity; /** * Repository class for Visit domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data See here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller diff --git a/src/main/resources/templates/error.html b/src/main/resources/templates/error.html index 2b40d7f98..b9026690e 100644 --- a/src/main/resources/templates/error.html +++ b/src/main/resources/templates/error.html @@ -1,6 +1,6 @@ - + diff --git a/src/main/resources/templates/owners/createOrUpdateOwnerForm.html b/src/main/resources/templates/owners/createOrUpdateOwnerForm.html index ca22d9de1..c835f8ccb 100644 --- a/src/main/resources/templates/owners/createOrUpdateOwnerForm.html +++ b/src/main/resources/templates/owners/createOrUpdateOwnerForm.html @@ -1,4 +1,4 @@ - diff --git a/src/main/resources/templates/owners/findOwners.html b/src/main/resources/templates/owners/findOwners.html index 982be5e81..134e687fd 100644 --- a/src/main/resources/templates/owners/findOwners.html +++ b/src/main/resources/templates/owners/findOwners.html @@ -1,4 +1,4 @@ - diff --git a/src/main/resources/templates/owners/ownerDetails.html b/src/main/resources/templates/owners/ownerDetails.html index ed89462b3..fa2b71ee9 100644 --- a/src/main/resources/templates/owners/ownerDetails.html +++ b/src/main/resources/templates/owners/ownerDetails.html @@ -1,6 +1,6 @@ - diff --git a/src/main/resources/templates/owners/ownersList.html b/src/main/resources/templates/owners/ownersList.html index 478b37e5d..acf7e02d0 100644 --- a/src/main/resources/templates/owners/ownersList.html +++ b/src/main/resources/templates/owners/ownersList.html @@ -1,6 +1,6 @@ - + diff --git a/src/main/resources/templates/pets/createOrUpdatePetForm.html b/src/main/resources/templates/pets/createOrUpdatePetForm.html index a0c182aa5..af87f3876 100644 --- a/src/main/resources/templates/pets/createOrUpdatePetForm.html +++ b/src/main/resources/templates/pets/createOrUpdatePetForm.html @@ -1,4 +1,4 @@ - diff --git a/src/main/resources/templates/pets/createOrUpdateVisitForm.html b/src/main/resources/templates/pets/createOrUpdateVisitForm.html index 609a735f9..d7589c3bc 100644 --- a/src/main/resources/templates/pets/createOrUpdateVisitForm.html +++ b/src/main/resources/templates/pets/createOrUpdateVisitForm.html @@ -1,4 +1,4 @@ - diff --git a/src/main/resources/templates/vets/vetList.html b/src/main/resources/templates/vets/vetList.html index 1961ad405..4fc961793 100644 --- a/src/main/resources/templates/vets/vetList.html +++ b/src/main/resources/templates/vets/vetList.html @@ -1,6 +1,6 @@ - diff --git a/src/main/resources/templates/welcome.html b/src/main/resources/templates/welcome.html index 6b4ff0480..4fa1cd328 100644 --- a/src/main/resources/templates/welcome.html +++ b/src/main/resources/templates/welcome.html @@ -1,6 +1,6 @@ - + From 765680c010663db4ee6e48f8c11ee6db2c4d61ac Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 21 Mar 2019 11:05:45 +0100 Subject: [PATCH 067/131] Polish "URL Cleanup" Closes gh-397 --- .../samples/petclinic/owner/PetRepository.java | 5 +++-- .../springframework/samples/petclinic/vet/VetRepository.java | 5 +++-- .../samples/petclinic/visit/VisitRepository.java | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java index 5ad150af7..15d6d8e4f 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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. @@ -23,7 +23,8 @@ import org.springframework.transaction.annotation.Transactional; /** * Repository class for Pet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data. + * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java index c3594feee..c598e5f3d 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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. @@ -24,7 +24,8 @@ import org.springframework.transaction.annotation.Transactional; /** * Repository class for Vet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data. + * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java index 25a117e94..0a37796b7 100644 --- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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. @@ -23,7 +23,8 @@ import org.springframework.samples.petclinic.model.BaseEntity; /** * Repository class for Visit domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data See here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation + * conventions so this interface can easily be extended for Spring Data. + * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller From be24e0c15ea8efa093055901426508604bba76ab Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 21 Mar 2019 11:08:00 +0100 Subject: [PATCH 068/131] Fix Apache license headers --- mvnw | 2 +- mvnw.cmd | 286 +++++++++--------- pom.xml | 2 +- readme.md | 2 +- .../petclinic/PetClinicApplication.java | 4 +- .../samples/petclinic/model/BaseEntity.java | 4 +- .../samples/petclinic/model/NamedEntity.java | 4 +- .../samples/petclinic/model/Person.java | 4 +- .../samples/petclinic/model/package-info.java | 16 + .../samples/petclinic/owner/Owner.java | 4 +- .../petclinic/owner/OwnerController.java | 4 +- .../petclinic/owner/OwnerRepository.java | 4 +- .../samples/petclinic/owner/Pet.java | 4 +- .../petclinic/owner/PetController.java | 4 +- .../petclinic/owner/PetRepository.java | 2 +- .../samples/petclinic/owner/PetType.java | 4 +- .../petclinic/owner/PetTypeFormatter.java | 4 +- .../samples/petclinic/owner/PetValidator.java | 4 +- .../petclinic/owner/VisitController.java | 4 +- .../petclinic/system/CacheConfiguration.java | 16 + .../petclinic/system/CrashController.java | 4 +- .../petclinic/system/WelcomeController.java | 16 + .../samples/petclinic/vet/Specialty.java | 4 +- .../samples/petclinic/vet/Vet.java | 4 +- .../samples/petclinic/vet/VetController.java | 4 +- .../samples/petclinic/vet/VetRepository.java | 2 +- .../samples/petclinic/vet/Vets.java | 4 +- .../samples/petclinic/visit/Visit.java | 4 +- .../petclinic/visit/VisitRepository.java | 2 +- src/main/less/petclinic.less | 2 +- .../petclinic/PetclinicIntegrationTests.java | 4 +- .../petclinic/model/ValidatorTests.java | 16 + .../petclinic/owner/OwnerControllerTests.java | 16 + .../petclinic/owner/PetControllerTests.java | 16 + .../owner/PetTypeFormatterTests.java | 16 + .../petclinic/owner/VisitControllerTests.java | 16 + .../petclinic/service/ClinicServiceTests.java | 4 +- .../petclinic/service/EntityUtils.java | 4 +- .../system/CrashControllerTests.java | 16 + .../petclinic/vet/VetControllerTests.java | 16 + .../samples/petclinic/vet/VetTests.java | 4 +- 41 files changed, 356 insertions(+), 196 deletions(-) diff --git a/mvnw b/mvnw index fc7efd17d..63fcc8f0f 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "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 +# https://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 diff --git a/mvnw.cmd b/mvnw.cmd index 0d49a2de0..66e928bd1 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,145 +1,145 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index bd21cc90a..14f58acf3 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 diff --git a/readme.md b/readme.md index 37d09817f..86ac7955d 100644 --- a/readme.md +++ b/readme.md @@ -118,7 +118,7 @@ For pull requests, editor preferences are available in the [editor config](.edit # License -The Spring PetClinic sample application is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0). +The Spring PetClinic sample application is released under version 2.0 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0). [spring-petclinic]: https://github.com/spring-projects/spring-petclinic [spring-framework-petclinic]: https://github.com/spring-petclinic/spring-framework-petclinic diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index 83b118095..cf0c5e301 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java index 86cc21092..8350eb744 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java index d66c97ae7..cc596a194 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index 5d23523bd..883376fbc 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/model/package-info.java b/src/main/java/org/springframework/samples/petclinic/model/package-info.java index 78294d130..13c1673d5 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/package-info.java +++ b/src/main/java/org/springframework/samples/petclinic/model/package-info.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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. + */ + /** * The classes in this package represent utilities used by the domain. */ diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java index 89aad2c2c..5b1b7fb36 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index 5d11bff4c..fca15d8e5 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java index 61941e3b2..a5803f36a 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java index c225b8d8a..7ded757bd 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java index e0c1feeed..0107aa8a9 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java index 15d6d8e4f..0d483b7ad 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java index ac827b310..19c27bee3 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java index ccca33913..4423482a3 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java index 1a3d92e9e..3e8438b33 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index 19e42c78e..d4d674dc7 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index f5f659482..9d4a53c64 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.system; import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; diff --git a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java index 2f5e7a348..05be70429 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java index 00430a790..7e96848b6 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.system; diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java b/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java index 5691c2434..ea8ec6ded 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java index 43aecc41e..33b449129 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index c54b3b92d..f15f40b2c 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java index c598e5f3d..1f70182fd 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java index f5b24c3fc..ab29f7a54 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index ab6e3319c..03c9deedf 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java index 0a37796b7..42b58618b 100644 --- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/src/main/less/petclinic.less b/src/main/less/petclinic.less index 32d15a5f2..7c88ec091 100644 --- a/src/main/less/petclinic.less +++ b/src/main/less/petclinic.less @@ -3,7 +3,7 @@ * * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://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, diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java index 3f48c0d4a..669dbddaa 100644 --- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index 7da0d3dea..151c0ce70 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.model; import java.util.Locale; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 7fccb3b04..c1ba09364 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.owner; import static org.hamcrest.Matchers.hasProperty; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index f95d7c87c..2ffae3025 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.owner; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index 4e8e36c14..47812a812 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.owner; import java.text.ParseException; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index 08d61360e..3edd20959 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.owner; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index 9f12151d9..8a7a2f0a5 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java index 44dc6b1c2..8890cc59a 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java +++ b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2012-2019 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 + * https://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, diff --git a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java index 3f108bfe9..cc1e235cb 100644 --- a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.system; import org.junit.Ignore; diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index 21f2edaa4..83ef50144 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2012-2019 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 + * + * https://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.vet; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java index de3a7b9bb..542250751 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2016-2017 the original author or authors. + * Copyright 2012-2019 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 + * https://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, From 5d7372682550f750c48026adebc8ae8d2bcb75e2 Mon Sep 17 00:00:00 2001 From: yanzh Date: Thu, 28 Mar 2019 10:56:33 +0800 Subject: [PATCH 069/131] Upgrade maven wrapper Closes gh-405 --- .mvn/wrapper/MavenWrapperDownloader.java | 117 +++++++++++++++ .mvn/wrapper/maven-wrapper.jar | Bin 49519 -> 50709 bytes .mvn/wrapper/maven-wrapper.properties | 3 +- mvnw | 180 ++++++++++++++++------- mvnw.cmd | 51 ++++++- 5 files changed, 291 insertions(+), 60 deletions(-) create mode 100644 .mvn/wrapper/MavenWrapperDownloader.java diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 000000000..1ef8d6981 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present 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. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.4"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + " .jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index c6feb8bb6f76f2553e266ff8bf8867105154237e..1914b842cfcbb00a843b5c458ad1db942c7aa522 100644 GIT binary patch literal 50709 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 Kc2Rxz>;C~chsnGE literal 49519 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%0A$pwhjXzyA0ZzErH{1@M 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 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 6c8c0e080..23fdba01f 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,2 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.4/maven-wrapper-0.5.4.jar diff --git a/mvnw b/mvnw index 63fcc8f0f..35ff643b3 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# 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 @@ -54,38 +54,16 @@ case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; esac if [ -z "$JAVA_HOME" ] ; then @@ -130,13 +108,12 @@ if $cygwin ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi -# For Migwn, ensure paths are in UNIX format before anything is touched +# For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then @@ -184,27 +161,28 @@ fi CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi - wdir=$(cd "$wdir/.."; pwd) + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround done echo "${basedir}" } @@ -216,10 +194,109 @@ concat_lines() { fi } -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.4/maven-wrapper-0.5.4.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.4/maven-wrapper-0.5.4.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" -# Provide a "standardized" way to retrieve the CLI args that will +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" export MAVEN_CMD_LINE_ARGS @@ -230,5 +307,4 @@ exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS - + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 66e928bd1..dae46d49c 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM http://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @@ -35,7 +35,9 @@ @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' @echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME @@ -80,8 +82,6 @@ goto error :init -set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* - @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". @REM Fallback to current working directory if not found. @@ -117,11 +117,48 @@ for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do s :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.4/maven-wrapper-0.5.4.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.4/maven-wrapper-0.5.4.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end From 6e24f5dc64e6fd3051f2835cfdd8160100904fc7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 11 May 2019 16:06:25 +0200 Subject: [PATCH 070/131] Upgrade to Spring Boot 2.1.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 14f58acf3..50a82ec1e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.3.RELEASE + 2.1.4.RELEASE petclinic From 3f838c2df27013cccadd4b05a11a491038167eb3 Mon Sep 17 00:00:00 2001 From: Johannes Wengert Date: Fri, 31 May 2019 23:08:22 +0200 Subject: [PATCH 071/131] Cleanup tests by using more idiomatic assertj assertions See gh-418 --- .../samples/petclinic/model/ValidatorTests.java | 2 +- .../petclinic/owner/PetTypeFormatterTests.java | 12 ++++++------ .../petclinic/service/ClinicServiceTests.java | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index 151c0ce70..e37a96562 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -53,7 +53,7 @@ public class ValidatorTests { Set> constraintViolations = validator .validate(person); - assertThat(constraintViolations.size()).isEqualTo(1); + assertThat(constraintViolations).hasSize(1); ConstraintViolation violation = constraintViolations.iterator().next(); assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName"); assertThat(violation.getMessage()).isEqualTo("must not be empty"); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index 47812a812..cf5f6cfb2 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -26,10 +26,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; /** * Test class for {@link PetTypeFormatter} @@ -54,19 +54,19 @@ public class PetTypeFormatterTests { PetType petType = new PetType(); petType.setName("Hamster"); String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); - assertEquals("Hamster", petTypeName); + assertThat(petTypeName).isEqualTo("Hamster"); } @Test public void shouldParse() throws ParseException { - Mockito.when(this.pets.findPetTypes()).thenReturn(makePetTypes()); + when(this.pets.findPetTypes()).thenReturn(makePetTypes()); PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); - assertEquals("Bird", petType.getName()); + assertThat(petType.getName()).isEqualTo("Bird"); } @Test(expected = ParseException.class) public void shouldThrowParseException() throws ParseException { - Mockito.when(this.pets.findPetTypes()).thenReturn(makePetTypes()); + when(this.pets.findPetTypes()).thenReturn(makePetTypes()); petTypeFormatter.parse("Fish", Locale.ENGLISH); } diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index 8a7a2f0a5..c103caac0 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -79,17 +79,17 @@ public class ClinicServiceTests { @Test public void shouldFindOwnersByLastName() { Collection owners = this.owners.findByLastName("Davis"); - assertThat(owners.size()).isEqualTo(2); + assertThat(owners).hasSize(2); owners = this.owners.findByLastName("Daviss"); - assertThat(owners.isEmpty()).isTrue(); + assertThat(owners).isEmpty(); } @Test public void shouldFindSingleOwnerWithPet() { Owner owner = this.owners.findById(1); assertThat(owner.getLastName()).startsWith("Franklin"); - assertThat(owner.getPets().size()).isEqualTo(1); + assertThat(owner.getPets()).hasSize(1); assertThat(owner.getPets().get(0).getType()).isNotNull(); assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); } @@ -213,7 +213,7 @@ public class ClinicServiceTests { @Test public void shouldFindVisitsByPetId() throws Exception { Collection visits = this.visits.findByPetId(7); - assertThat(visits.size()).isEqualTo(2); + assertThat(visits).hasSize(2); Visit[] visitArr = visits.toArray(new Visit[visits.size()]); assertThat(visitArr[0].getDate()).isNotNull(); assertThat(visitArr[0].getPetId()).isEqualTo(7); From 8919c7317b26854dd742be5ebd345badaed0bcb2 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 1 Jun 2019 18:09:33 +0200 Subject: [PATCH 072/131] Polish "Cleanup tests by using more idiomatic assertj assertions" See gh-418 --- .../samples/petclinic/owner/PetTypeFormatterTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index cf5f6cfb2..9ba431480 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -29,7 +29,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; /** * Test class for {@link PetTypeFormatter} @@ -59,14 +59,14 @@ public class PetTypeFormatterTests { @Test public void shouldParse() throws ParseException { - when(this.pets.findPetTypes()).thenReturn(makePetTypes()); + given(this.pets.findPetTypes()).willReturn(makePetTypes()); PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); assertThat(petType.getName()).isEqualTo("Bird"); } @Test(expected = ParseException.class) public void shouldThrowParseException() throws ParseException { - when(this.pets.findPetTypes()).thenReturn(makePetTypes()); + given(this.pets.findPetTypes()).willReturn(makePetTypes()); petTypeFormatter.parse("Fish", Locale.ENGLISH); } From 39897cc149588ca413c4cc9f4cb4b6d599ee73c5 Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Mon, 27 May 2019 14:17:52 -0400 Subject: [PATCH 073/131] Push-to-PWS integration See gh-417 --- push-to-pws/button.yml | 1 + readme.md | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 push-to-pws/button.yml diff --git a/push-to-pws/button.yml b/push-to-pws/button.yml new file mode 100644 index 000000000..e85329d59 --- /dev/null +++ b/push-to-pws/button.yml @@ -0,0 +1 @@ +repo: https://github.com/spring-projects/spring-petclinic.git diff --git a/readme.md b/readme.md index 86ac7955d..cc5c9db26 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,8 @@ # Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=master)](https://travis-ci.org/spring-projects/spring-petclinic/) +Deploy `spring-petclinic` app to Pivotal Web Services: + + Push + ## Understanding the Spring Petclinic application with a few diagrams See the presentation here From dc337f580c763c29ea3857cb9c79e9e23fce80d5 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 1 Jun 2019 18:14:23 +0200 Subject: [PATCH 074/131] Polish "Push-to-PWS integration" See gh-417 --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index cc5c9db26..ce2715152 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ # Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=master)](https://travis-ci.org/spring-projects/spring-petclinic/) -Deploy `spring-petclinic` app to Pivotal Web Services: +Deploy this sample application to Pivotal Web Services: - Push + Push ## Understanding the Spring Petclinic application with a few diagrams From 11d0ed4358eebcc8d5d108748705843d8238af5a Mon Sep 17 00:00:00 2001 From: Choonghee Lee Date: Sat, 18 May 2019 10:24:08 +0900 Subject: [PATCH 075/131] update table id attribute in ownersList.html "vets" to "owners" --- src/main/resources/templates/owners/ownersList.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/owners/ownersList.html b/src/main/resources/templates/owners/ownersList.html index acf7e02d0..cf489b59b 100644 --- a/src/main/resources/templates/owners/ownersList.html +++ b/src/main/resources/templates/owners/ownersList.html @@ -6,7 +6,7 @@

Owners

- +
From 7481e8841a452a101b14363ac36ff8df5c7c1956 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 19 Jun 2019 15:11:54 +0200 Subject: [PATCH 076/131] Upgrade to Spring Boot 2.1.6.RELEASE --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 50a82ec1e..7b0c2ec5d 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.4.RELEASE + 2.1.6.RELEASE petclinic From 912d2adca447e8ffbcc60cad63b76a3c01cf9ea7 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 20 Jun 2019 14:14:53 +0100 Subject: [PATCH 077/131] Add VS Code to list of IDEs --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ce2715152..7dd16246c 100644 --- a/readme.md +++ b/readme.md @@ -50,11 +50,12 @@ docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306: The following items should be installed in your system: * Java 8 or newer. * git command line tool (https://help.github.com/articles/set-up-git) -* Your prefered IDE +* Your preferred IDE * Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in `Help -> About` dialog. If m2e is not there, just follow the install process here: https://www.eclipse.org/m2e/ * [Spring Tools Suite](https://spring.io/tools) (STS) * IntelliJ IDEA + * [VS Code](https://code.visualstudio.com) ### Steps: From 02adb1d49f50066003ebfc9527e4fa36065872fa Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 21 Jun 2019 12:27:16 +0100 Subject: [PATCH 078/131] Attempt to fix travis build by hardcoding Ubuntu dist --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c0f28cfa4..1e91cb501 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,2 +1,3 @@ +dist: trusty language: java jdk: oraclejdk8 From e157f200f820e39b8f42991fabf039daaea106ca Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 21 Jun 2019 14:45:39 +0100 Subject: [PATCH 079/131] Clarify the docs on mysql --- readme.md | 2 ++ .../db/mysql/petclinic_db_setup_mysql.txt | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 7dd16246c..a8506b0ee 100644 --- a/readme.md +++ b/readme.md @@ -44,6 +44,8 @@ You could start MySql locally with whatever installer works for your OS, or with docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 ``` +Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). + ## Working with Petclinic in your IDE ### Prerequisites diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index d489a1744..6adb900af 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -11,7 +11,19 @@ 1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), which can be found here: https://dev.mysql.com/downloads/. Or run the "docker-compose.yml" from the root of the project (if you have docker installed - locally). + locally): + + $ docker-compose up + ... + mysql_1_eedb4818d817 | MySQL init process done. Ready for start up. + ... 2) Create the PetClinic database and user by executing the "db/mysql/{schema,data}.sql" - scripts (or set "spring.datasource.initialize=true" the first time you run the app). + scripts (or set "spring.datasource.initialize=always" the first time you run the app). + +3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command + line, but any way that sets that property in a Spring Boot app should work). + +N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value +as it is configured by default. This condition is taken care of by the docker-compose +configuration provided, or by the `schema.sql` if you can run that as root. \ No newline at end of file From b6a619c0c4ae4d85a28a2804628c27ec3716f4ee Mon Sep 17 00:00:00 2001 From: Alex Boyko Date: Thu, 22 Aug 2019 12:39:14 -0400 Subject: [PATCH 080/131] Update Push-to-PWS button image --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index a8506b0ee..c544788ba 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ # Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=master)](https://travis-ci.org/spring-projects/spring-petclinic/) Deploy this sample application to Pivotal Web Services: - Push + Push ## Understanding the Spring Petclinic application with a few diagrams From d6bdc13bdbb08fd1f6c769dfdef11786a0971f90 Mon Sep 17 00:00:00 2001 From: Alex Boyko Date: Tue, 27 Aug 2019 09:28:19 -0400 Subject: [PATCH 081/131] Move Push-to-PWSX button on the next line --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index c544788ba..34c8e8b84 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,8 @@ # Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=master)](https://travis-ci.org/spring-projects/spring-petclinic/) Deploy this sample application to Pivotal Web Services: + - Push + Push ## Understanding the Spring Petclinic application with a few diagrams From 7ef045dac8effb41d5f24c1e1011869b59a3d0a2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 6 Sep 2019 09:13:41 +0100 Subject: [PATCH 082/131] Make Pet.visits @Transient In that way the Pet and Visit entities are more modular, and we don't have to rely on a bit of a hack which is that Hibernate happily maps Pet to its ID in the entity generation (but fails if you do it at compile time). --- .../petclinic/owner/OwnerController.java | 11 +++- .../samples/petclinic/owner/Pet.java | 11 ++-- .../petclinic/owner/VisitController.java | 14 ++-- .../petclinic/owner/OwnerControllerTests.java | 66 +++++++++++++++---- 4 files changed, 77 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index fca15d8e5..afc2c937e 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -15,6 +15,7 @@ */ package org.springframework.samples.petclinic.owner; +import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -40,10 +41,12 @@ class OwnerController { private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; private final OwnerRepository owners; + private VisitRepository visits; - public OwnerController(OwnerRepository clinicService) { + public OwnerController(OwnerRepository clinicService, VisitRepository visits) { this.owners = clinicService; + this.visits = visits; } @InitBinder @@ -126,7 +129,11 @@ class OwnerController { @GetMapping("/owners/{ownerId}") public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { ModelAndView mav = new ModelAndView("owners/ownerDetails"); - mav.addObject(this.owners.findById(ownerId)); + Owner owner = this.owners.findById(ownerId); + for (Pet pet : owner.getPets()) { + pet.setVisitsInternal(visits.findByPetId(pet.getId())); + } + mav.addObject(owner); return mav; } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java index 7ded757bd..0bd04b772 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -17,20 +17,19 @@ package org.springframework.samples.petclinic.owner; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; 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.Transient; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; @@ -61,7 +60,7 @@ public class Pet extends NamedEntity { @JoinColumn(name = "owner_id") private Owner owner; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "petId", fetch = FetchType.EAGER) + @Transient private Set visits = new LinkedHashSet<>(); public void setBirthDate(LocalDate birthDate) { @@ -95,8 +94,8 @@ public class Pet extends NamedEntity { return this.visits; } - protected void setVisitsInternal(Set visits) { - this.visits = visits; + protected void setVisitsInternal(Collection visits) { + this.visits = new LinkedHashSet<>(visits); } public List getVisits() { diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index d4d674dc7..c6dfc7fc7 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -15,15 +15,20 @@ */ package org.springframework.samples.petclinic.owner; +import java.util.Map; + +import javax.validation.Valid; + import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.util.Map; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; /** * @author Juergen Hoeller @@ -62,6 +67,7 @@ class VisitController { @ModelAttribute("visit") public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) { Pet pet = this.pets.findById(petId); + pet.setVisitsInternal(this.visits.findByPetId(petId)); model.put("pet", pet); Visit visit = new Visit(); pet.addVisit(visit); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index c1ba09364..5084f4245 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -16,8 +16,29 @@ package org.springframework.samples.petclinic.owner; +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; + +import org.assertj.core.util.Lists; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.visit.VisitRepository; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -25,19 +46,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; -import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.samples.petclinic.owner.Owner; -import org.springframework.samples.petclinic.owner.OwnerController; -import org.springframework.samples.petclinic.owner.OwnerRepository; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - /** * Test class for {@link OwnerController} * @@ -55,6 +63,9 @@ public class OwnerControllerTests { @MockBean private OwnerRepository owners; + @MockBean + private VisitRepository visits; + private Owner george; @Before @@ -66,7 +77,18 @@ public class OwnerControllerTests { george.setAddress("110 W. Liberty St."); george.setCity("Madison"); george.setTelephone("6085551023"); + Pet max = new Pet(); + PetType dog = new PetType(); + dog.setName("dog"); + max.setId(1); + max.setType(dog); + max.setName("Max"); + max.setBirthDate(LocalDate.now()); + george.setPetsInternal(Collections.singleton(max)); given(this.owners.findById(TEST_OWNER_ID)).willReturn(george); + Visit visit = new Visit(); + visit.setDate(LocalDate.now()); + given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit)); } @Test @@ -189,6 +211,24 @@ public class OwnerControllerTests { .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(model().attribute("owner", hasProperty("pets", not(empty())))) + .andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher>() { + + @Override + public boolean matches(Object item) { + @SuppressWarnings("unchecked") + List pets = (List) item; + Pet pet = pets.get(0); + if (pet.getVisits().isEmpty()) { + return false; + } + return true; + } + + @Override + public void describeTo(Description description) { + description.appendText("Max did not have any visits"); + }}))) .andExpect(view().name("owners/ownerDetails")); } From e280d12144b388ea58f90961f9b22500b29c8e3e Mon Sep 17 00:00:00 2001 From: trisberg Date: Mon, 23 Sep 2019 15:53:00 -0400 Subject: [PATCH 083/131] Fix docs on mysql, use initialization-mode --- src/main/resources/db/mysql/petclinic_db_setup_mysql.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index 6adb900af..920906687 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -19,7 +19,7 @@ ... 2) Create the PetClinic database and user by executing the "db/mysql/{schema,data}.sql" - scripts (or set "spring.datasource.initialize=always" the first time you run the app). + scripts (or set "spring.datasource.initialization-mode=always" the first time you run the app). 3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command line, but any way that sets that property in a Spring Boot app should work). From ecae6d71c39544ff575b0298fbb3c631c96a1fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A8sar=20Ordi=C3=B1ana?= Date: Thu, 3 Oct 2019 13:38:42 +0200 Subject: [PATCH 084/131] Upgrade to Maven 3.6.2 and Maven Wrapper 0.5.5 See gh-457 --- .mvn/wrapper/MavenWrapperDownloader.java | 4 ++-- .mvn/wrapper/maven-wrapper.jar | Bin 50709 -> 50710 bytes .mvn/wrapper/maven-wrapper.properties | 4 ++-- mvnw | 4 ++-- mvnw.cmd | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index 1ef8d6981..c32394f14 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -20,12 +20,12 @@ import java.util.Properties; public class MavenWrapperDownloader { - private static final String WRAPPER_VERSION = "0.5.4"; + private static final String WRAPPER_VERSION = "0.5.5"; /** * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. */ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + " .jar"; + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; /** * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 1914b842cfcbb00a843b5c458ad1db942c7aa522..0d5e649888a4843c1520054d9672f80c62ebbb48 100644 GIT binary patch delta 7708 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 Date: Thu, 3 Oct 2019 13:59:27 +0200 Subject: [PATCH 085/131] Upgrade to Spring Boot 2.1.9.RELEASE --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7b0c2ec5d..0e99f0786 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.6.RELEASE + 2.1.9.RELEASE petclinic From ce7c3f93deb53798e3842e583fecea3514e90f1e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 20 Oct 2019 16:40:04 +0200 Subject: [PATCH 086/131] Upgrade to Spring Boot 2.2.0.RELEASE --- pom.xml | 4 ++-- .../samples/petclinic/vet/VetControllerTests.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 0e99f0786..0f50398bf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.1.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.1.9.RELEASE + 2.2.0.RELEASE petclinic diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index 83ef50144..145c61596 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -78,7 +78,7 @@ public class VetControllerTests { public void testShowResourcesVetList() throws Exception { ResultActions actions = mockMvc.perform(get("/vets") .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); - actions.andExpect(content().contentType("application/json;charset=UTF-8")) + actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.vetList[0].id").value(1)); } From ac69dbba23d9956b7806b2f69e65d950755bab5a Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Wed, 10 Oct 2018 18:41:57 +0200 Subject: [PATCH 087/131] Migrate tests to JUnit 5 See gh-360 --- pom.xml | 19 +++++++++++++++++++ .../petclinic/PetclinicIntegrationTests.java | 6 +----- .../petclinic/model/ValidatorTests.java | 3 +-- .../petclinic/owner/OwnerControllerTests.java | 10 +++------- .../petclinic/owner/PetControllerTests.java | 16 +++------------- .../owner/PetTypeFormatterTests.java | 19 +++++++++++-------- .../petclinic/owner/VisitControllerTests.java | 12 +++--------- .../petclinic/service/ClinicServiceTests.java | 6 ++---- .../system/CrashControllerTests.java | 10 +++------- .../petclinic/vet/VetControllerTests.java | 9 +++------ .../samples/petclinic/vet/VetTests.java | 3 +-- 11 files changed, 50 insertions(+), 63 deletions(-) diff --git a/pom.xml b/pom.xml index 0f50398bf..f23a192fa 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,13 @@ org.springframework.boot spring-boot-starter-test test + + + + junit + junit + + @@ -103,6 +110,18 @@ + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-junit-jupiter + test + + org.springframework.boot spring-boot-devtools diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java index 669dbddaa..425172b30 100644 --- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -16,15 +16,11 @@ package org.springframework.samples.petclinic; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.samples.petclinic.vet.VetRepository; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest public class PetclinicIntegrationTests { diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index e37a96562..30397742e 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -22,8 +22,7 @@ import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validator; -import org.junit.Test; - +import org.junit.jupiter.api.Test; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 5084f4245..899da1471 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -23,16 +23,13 @@ import java.util.List; import org.assertj.core.util.Lists; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import static org.hamcrest.Matchers.empty; @@ -51,7 +48,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * * @author Colin But */ -@RunWith(SpringRunner.class) @WebMvcTest(OwnerController.class) public class OwnerControllerTests { @@ -68,7 +64,7 @@ public class OwnerControllerTests { private Owner george; - @Before + @BeforeEach public void setup() { george = new Owner(); george.setId(TEST_OWNER_ID); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index 2ffae3025..4c0d69538 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -24,22 +24,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; -import org.springframework.samples.petclinic.owner.Owner; -import org.springframework.samples.petclinic.owner.OwnerRepository; -import org.springframework.samples.petclinic.owner.Pet; -import org.springframework.samples.petclinic.owner.PetController; -import org.springframework.samples.petclinic.owner.PetRepository; -import org.springframework.samples.petclinic.owner.PetType; -import org.springframework.samples.petclinic.owner.PetTypeFormatter; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; /** @@ -47,7 +38,6 @@ import org.springframework.test.web.servlet.MockMvc; * * @author Colin But */ -@RunWith(SpringRunner.class) @WebMvcTest(value = PetController.class, includeFilters = @ComponentScan.Filter( value = PetTypeFormatter.class, @@ -67,7 +57,7 @@ public class PetControllerTests { @MockBean private OwnerRepository owners; - @Before + @BeforeEach public void setup() { PetType cat = new PetType(); cat.setId(3); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index 9ba431480..af98b5cfd 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -22,11 +22,12 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -36,7 +37,7 @@ import static org.mockito.BDDMockito.given; * * @author Colin But */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class PetTypeFormatterTests { @Mock @@ -44,7 +45,7 @@ public class PetTypeFormatterTests { private PetTypeFormatter petTypeFormatter; - @Before + @BeforeEach public void setup() { this.petTypeFormatter = new PetTypeFormatter(pets); } @@ -64,10 +65,12 @@ public class PetTypeFormatterTests { assertThat(petType.getName()).isEqualTo("Bird"); } - @Test(expected = ParseException.class) + @Test public void shouldThrowParseException() throws ParseException { given(this.pets.findPetTypes()).willReturn(makePetTypes()); - petTypeFormatter.parse("Fish", Locale.ENGLISH); + Assertions.assertThrows(ParseException.class, () -> { + petTypeFormatter.parse("Fish", Locale.ENGLISH); + }); } /** diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index 3edd20959..93f30b9aa 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -23,17 +23,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.samples.petclinic.owner.Pet; -import org.springframework.samples.petclinic.owner.PetRepository; -import org.springframework.samples.petclinic.owner.VisitController; import org.springframework.samples.petclinic.visit.VisitRepository; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; /** @@ -41,7 +36,6 @@ import org.springframework.test.web.servlet.MockMvc; * * @author Colin But */ -@RunWith(SpringRunner.class) @WebMvcTest(VisitController.class) public class VisitControllerTests { @@ -56,7 +50,7 @@ public class VisitControllerTests { @MockBean private PetRepository pets; - @Before + @BeforeEach public void init() { given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); } diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index c103caac0..562025de9 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -21,8 +21,8 @@ import static org.assertj.core.api.Assertions.assertThat; import java.time.LocalDate; import java.util.Collection; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; @@ -36,7 +36,6 @@ import org.springframework.samples.petclinic.vet.VetRepository; import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Service; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; /** @@ -60,7 +59,6 @@ import org.springframework.transaction.annotation.Transactional; * @author Dave Syer */ -@RunWith(SpringRunner.class) @DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) public class ClinicServiceTests { diff --git a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java index cc1e235cb..b38a7840d 100644 --- a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java @@ -16,13 +16,10 @@ package org.springframework.samples.petclinic.system; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -36,9 +33,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * * @author Colin But */ -@RunWith(SpringRunner.class) // Waiting https://github.com/spring-projects/spring-boot/issues/5574 -@Ignore +@Disabled @WebMvcTest(controllers = CrashController.class) public class CrashControllerTests { diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index 145c61596..c3681f88f 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -25,21 +25,18 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; /** * Test class for the {@link VetController} */ -@RunWith(SpringRunner.class) @WebMvcTest(VetController.class) public class VetControllerTests { @@ -49,7 +46,7 @@ public class VetControllerTests { @MockBean private VetRepository vets; - @Before + @BeforeEach public void setup() { Vet james = new Vet(); james.setFirstName("James"); diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java index 542250751..0e32c531f 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java @@ -15,8 +15,7 @@ */ package org.springframework.samples.petclinic.vet; -import org.junit.Test; - +import org.junit.jupiter.api.Test; import org.springframework.util.SerializationUtils; import static org.assertj.core.api.Assertions.assertThat; From 253e6fde5f488384e0f91c7668917269a780c6d7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 20 Oct 2019 16:49:17 +0200 Subject: [PATCH 088/131] Polish "Migrate tests to JUnit 5" See gh-360 --- pom.xml | 5 ++-- .../petclinic/PetclinicIntegrationTests.java | 4 +-- .../petclinic/model/ValidatorTests.java | 4 +-- .../petclinic/owner/OwnerControllerTests.java | 26 +++++++++---------- .../petclinic/owner/PetControllerTests.java | 16 ++++++------ .../owner/PetTypeFormatterTests.java | 10 +++---- .../petclinic/owner/VisitControllerTests.java | 10 +++---- .../petclinic/service/ClinicServiceTests.java | 26 +++++++++---------- .../system/CrashControllerTests.java | 4 +-- .../petclinic/vet/VetControllerTests.java | 8 +++--- .../samples/petclinic/vet/VetTests.java | 5 ++-- 11 files changed, 57 insertions(+), 61 deletions(-) diff --git a/pom.xml b/pom.xml index f23a192fa..9802b8935 100644 --- a/pom.xml +++ b/pom.xml @@ -58,10 +58,9 @@ spring-boot-starter-test test - - junit - junit + org.junit.vintage + junit-vintage-engine diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java index 425172b30..217d552f4 100644 --- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -22,13 +22,13 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.samples.petclinic.vet.VetRepository; @SpringBootTest -public class PetclinicIntegrationTests { +class PetclinicIntegrationTests { @Autowired private VetRepository vets; @Test - public void testFindAll() throws Exception { + void testFindAll() throws Exception { vets.findAll(); vets.findAll(); // served from cache } diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index 30397742e..4be38f714 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -32,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Michael Isvy Simple test to make sure that Bean Validation is working (useful * when upgrading to a new version of Hibernate Validator/ Bean Validation) */ -public class ValidatorTests { +class ValidatorTests { private Validator createValidator() { LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); @@ -41,7 +41,7 @@ public class ValidatorTests { } @Test - public void shouldNotValidateWhenFirstNameEmpty() { + void shouldNotValidateWhenFirstNameEmpty() { LocaleContextHolder.setLocale(Locale.ENGLISH); Person person = new Person(); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 899da1471..1956e2a24 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -49,7 +49,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * @author Colin But */ @WebMvcTest(OwnerController.class) -public class OwnerControllerTests { +class OwnerControllerTests { private static final int TEST_OWNER_ID = 1; @@ -65,7 +65,7 @@ public class OwnerControllerTests { private Owner george; @BeforeEach - public void setup() { + void setup() { george = new Owner(); george.setId(TEST_OWNER_ID); george.setFirstName("George"); @@ -88,7 +88,7 @@ public class OwnerControllerTests { } @Test - public void testInitCreationForm() throws Exception { + void testInitCreationForm() throws Exception { mockMvc.perform(get("/owners/new")) .andExpect(status().isOk()) .andExpect(model().attributeExists("owner")) @@ -96,7 +96,7 @@ public class OwnerControllerTests { } @Test - public void testProcessCreationFormSuccess() throws Exception { + void testProcessCreationFormSuccess() throws Exception { mockMvc.perform(post("/owners/new") .param("firstName", "Joe") .param("lastName", "Bloggs") @@ -108,7 +108,7 @@ public class OwnerControllerTests { } @Test - public void testProcessCreationFormHasErrors() throws Exception { + void testProcessCreationFormHasErrors() throws Exception { mockMvc.perform(post("/owners/new") .param("firstName", "Joe") .param("lastName", "Bloggs") @@ -122,7 +122,7 @@ public class OwnerControllerTests { } @Test - public void testInitFindForm() throws Exception { + void testInitFindForm() throws Exception { mockMvc.perform(get("/owners/find")) .andExpect(status().isOk()) .andExpect(model().attributeExists("owner")) @@ -130,7 +130,7 @@ public class OwnerControllerTests { } @Test - public void testProcessFindFormSuccess() throws Exception { + void testProcessFindFormSuccess() throws Exception { given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner())); mockMvc.perform(get("/owners")) .andExpect(status().isOk()) @@ -138,7 +138,7 @@ public class OwnerControllerTests { } @Test - public void testProcessFindFormByLastName() throws Exception { + void testProcessFindFormByLastName() throws Exception { given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); mockMvc.perform(get("/owners") .param("lastName", "Franklin") @@ -148,7 +148,7 @@ public class OwnerControllerTests { } @Test - public void testProcessFindFormNoOwnersFound() throws Exception { + void testProcessFindFormNoOwnersFound() throws Exception { mockMvc.perform(get("/owners") .param("lastName", "Unknown Surname") ) @@ -159,7 +159,7 @@ public class OwnerControllerTests { } @Test - public void testInitUpdateOwnerForm() throws Exception { + void testInitUpdateOwnerForm() throws Exception { mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) .andExpect(status().isOk()) .andExpect(model().attributeExists("owner")) @@ -172,7 +172,7 @@ public class OwnerControllerTests { } @Test - public void testProcessUpdateOwnerFormSuccess() throws Exception { + void testProcessUpdateOwnerFormSuccess() throws Exception { mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) .param("firstName", "Joe") .param("lastName", "Bloggs") @@ -185,7 +185,7 @@ public class OwnerControllerTests { } @Test - public void testProcessUpdateOwnerFormHasErrors() throws Exception { + void testProcessUpdateOwnerFormHasErrors() throws Exception { mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) .param("firstName", "Joe") .param("lastName", "Bloggs") @@ -199,7 +199,7 @@ public class OwnerControllerTests { } @Test - public void testShowOwner() throws Exception { + void testShowOwner() throws Exception { mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) .andExpect(status().isOk()) .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index 4c0d69538..f7c8fe726 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -42,7 +42,7 @@ import org.springframework.test.web.servlet.MockMvc; includeFilters = @ComponentScan.Filter( value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE)) -public class PetControllerTests { +class PetControllerTests { private static final int TEST_OWNER_ID = 1; private static final int TEST_PET_ID = 1; @@ -58,7 +58,7 @@ public class PetControllerTests { private OwnerRepository owners; @BeforeEach - public void setup() { + void setup() { PetType cat = new PetType(); cat.setId(3); cat.setName("hamster"); @@ -69,7 +69,7 @@ public class PetControllerTests { } @Test - public void testInitCreationForm() throws Exception { + void testInitCreationForm() throws Exception { mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)) .andExpect(status().isOk()) .andExpect(view().name("pets/createOrUpdatePetForm")) @@ -77,7 +77,7 @@ public class PetControllerTests { } @Test - public void testProcessCreationFormSuccess() throws Exception { + void testProcessCreationFormSuccess() throws Exception { mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) .param("name", "Betty") .param("type", "hamster") @@ -88,7 +88,7 @@ public class PetControllerTests { } @Test - public void testProcessCreationFormHasErrors() throws Exception { + void testProcessCreationFormHasErrors() throws Exception { mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) .param("name", "Betty") .param("birthDate", "2015-02-12") @@ -102,7 +102,7 @@ public class PetControllerTests { } @Test - public void testInitUpdateForm() throws Exception { + void testInitUpdateForm() throws Exception { mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) .andExpect(status().isOk()) .andExpect(model().attributeExists("pet")) @@ -110,7 +110,7 @@ public class PetControllerTests { } @Test - public void testProcessUpdateFormSuccess() throws Exception { + void testProcessUpdateFormSuccess() throws Exception { mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) .param("name", "Betty") .param("type", "hamster") @@ -121,7 +121,7 @@ public class PetControllerTests { } @Test - public void testProcessUpdateFormHasErrors() throws Exception { + void testProcessUpdateFormHasErrors() throws Exception { mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) .param("name", "Betty") .param("birthDate", "2015/02/12") diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index af98b5cfd..e27fce21e 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -38,7 +38,7 @@ import static org.mockito.BDDMockito.given; * @author Colin But */ @ExtendWith(MockitoExtension.class) -public class PetTypeFormatterTests { +class PetTypeFormatterTests { @Mock private PetRepository pets; @@ -46,12 +46,12 @@ public class PetTypeFormatterTests { private PetTypeFormatter petTypeFormatter; @BeforeEach - public void setup() { + void setup() { this.petTypeFormatter = new PetTypeFormatter(pets); } @Test - public void testPrint() { + void testPrint() { PetType petType = new PetType(); petType.setName("Hamster"); String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); @@ -59,14 +59,14 @@ public class PetTypeFormatterTests { } @Test - public void shouldParse() throws ParseException { + void shouldParse() throws ParseException { given(this.pets.findPetTypes()).willReturn(makePetTypes()); PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); assertThat(petType.getName()).isEqualTo("Bird"); } @Test - public void shouldThrowParseException() throws ParseException { + void shouldThrowParseException() throws ParseException { given(this.pets.findPetTypes()).willReturn(makePetTypes()); Assertions.assertThrows(ParseException.class, () -> { petTypeFormatter.parse("Fish", Locale.ENGLISH); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index 93f30b9aa..f61d34c9c 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -37,7 +37,7 @@ import org.springframework.test.web.servlet.MockMvc; * @author Colin But */ @WebMvcTest(VisitController.class) -public class VisitControllerTests { +class VisitControllerTests { private static final int TEST_PET_ID = 1; @@ -51,19 +51,19 @@ public class VisitControllerTests { private PetRepository pets; @BeforeEach - public void init() { + void init() { given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); } @Test - public void testInitNewVisitForm() throws Exception { + void testInitNewVisitForm() throws Exception { mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)) .andExpect(status().isOk()) .andExpect(view().name("pets/createOrUpdateVisitForm")); } @Test - public void testProcessNewVisitFormSuccess() throws Exception { + void testProcessNewVisitFormSuccess() throws Exception { mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) .param("name", "George") .param("description", "Visit Description") @@ -73,7 +73,7 @@ public class VisitControllerTests { } @Test - public void testProcessNewVisitFormHasErrors() throws Exception { + void testProcessNewVisitFormHasErrors() throws Exception { mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) .param("name", "George") ) diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index 562025de9..f11f98373 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -22,7 +22,6 @@ import java.time.LocalDate; import java.util.Collection; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; @@ -58,9 +57,8 @@ import org.springframework.transaction.annotation.Transactional; * @author Michael Isvy * @author Dave Syer */ - @DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) -public class ClinicServiceTests { +class ClinicServiceTests { @Autowired protected OwnerRepository owners; @@ -75,7 +73,7 @@ public class ClinicServiceTests { protected VetRepository vets; @Test - public void shouldFindOwnersByLastName() { + void shouldFindOwnersByLastName() { Collection owners = this.owners.findByLastName("Davis"); assertThat(owners).hasSize(2); @@ -84,7 +82,7 @@ public class ClinicServiceTests { } @Test - public void shouldFindSingleOwnerWithPet() { + void shouldFindSingleOwnerWithPet() { Owner owner = this.owners.findById(1); assertThat(owner.getLastName()).startsWith("Franklin"); assertThat(owner.getPets()).hasSize(1); @@ -94,7 +92,7 @@ public class ClinicServiceTests { @Test @Transactional - public void shouldInsertOwner() { + void shouldInsertOwner() { Collection owners = this.owners.findByLastName("Schultz"); int found = owners.size(); @@ -113,7 +111,7 @@ public class ClinicServiceTests { @Test @Transactional - public void shouldUpdateOwner() { + void shouldUpdateOwner() { Owner owner = this.owners.findById(1); String oldLastName = owner.getLastName(); String newLastName = oldLastName + "X"; @@ -127,7 +125,7 @@ public class ClinicServiceTests { } @Test - public void shouldFindPetWithCorrectId() { + void shouldFindPetWithCorrectId() { Pet pet7 = this.pets.findById(7); assertThat(pet7.getName()).startsWith("Samantha"); assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); @@ -135,7 +133,7 @@ public class ClinicServiceTests { } @Test - public void shouldFindAllPetTypes() { + void shouldFindAllPetTypes() { Collection petTypes = this.pets.findPetTypes(); PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); @@ -146,7 +144,7 @@ public class ClinicServiceTests { @Test @Transactional - public void shouldInsertPetIntoDatabaseAndGenerateId() { + void shouldInsertPetIntoDatabaseAndGenerateId() { Owner owner6 = this.owners.findById(6); int found = owner6.getPets().size(); @@ -169,7 +167,7 @@ public class ClinicServiceTests { @Test @Transactional - public void shouldUpdatePetName() throws Exception { + void shouldUpdatePetName() throws Exception { Pet pet7 = this.pets.findById(7); String oldName = pet7.getName(); @@ -182,7 +180,7 @@ public class ClinicServiceTests { } @Test - public void shouldFindVets() { + void shouldFindVets() { Collection vets = this.vets.findAll(); Vet vet = EntityUtils.getById(vets, Vet.class, 3); @@ -194,7 +192,7 @@ public class ClinicServiceTests { @Test @Transactional - public void shouldAddNewVisitForPet() { + void shouldAddNewVisitForPet() { Pet pet7 = this.pets.findById(7); int found = pet7.getVisits().size(); Visit visit = new Visit(); @@ -209,7 +207,7 @@ public class ClinicServiceTests { } @Test - public void shouldFindVisitsByPetId() throws Exception { + void shouldFindVisitsByPetId() throws Exception { Collection visits = this.visits.findByPetId(7); assertThat(visits).hasSize(2); Visit[] visitArr = visits.toArray(new Visit[visits.size()]); diff --git a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java index b38a7840d..f15689ce2 100644 --- a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java @@ -36,13 +36,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. // Waiting https://github.com/spring-projects/spring-boot/issues/5574 @Disabled @WebMvcTest(controllers = CrashController.class) -public class CrashControllerTests { +class CrashControllerTests { @Autowired private MockMvc mockMvc; @Test - public void testTriggerException() throws Exception { + void testTriggerException() throws Exception { mockMvc.perform(get("/oups")).andExpect(view().name("exception")) .andExpect(model().attributeExists("exception")) .andExpect(forwardedUrl("exception")).andExpect(status().isOk()); diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index c3681f88f..5b6d387e7 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -38,7 +38,7 @@ import org.springframework.test.web.servlet.ResultActions; * Test class for the {@link VetController} */ @WebMvcTest(VetController.class) -public class VetControllerTests { +class VetControllerTests { @Autowired private MockMvc mockMvc; @@ -47,7 +47,7 @@ public class VetControllerTests { private VetRepository vets; @BeforeEach - public void setup() { + void setup() { Vet james = new Vet(); james.setFirstName("James"); james.setLastName("Carter"); @@ -64,7 +64,7 @@ public class VetControllerTests { } @Test - public void testShowVetListHtml() throws Exception { + void testShowVetListHtml() throws Exception { mockMvc.perform(get("/vets.html")) .andExpect(status().isOk()) .andExpect(model().attributeExists("vets")) @@ -72,7 +72,7 @@ public class VetControllerTests { } @Test - public void testShowResourcesVetList() throws Exception { + void testShowResourcesVetList() throws Exception { ResultActions actions = mockMvc.perform(get("/vets") .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java index 0e32c531f..82163eb14 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java @@ -22,12 +22,11 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Dave Syer - * */ -public class VetTests { +class VetTests { @Test - public void testSerialization() { + void testSerialization() { Vet vet = new Vet(); vet.setFirstName("Zaphod"); vet.setLastName("Beeblebrox"); From 32301ed5311f76ed0233ed4c08753ff9cfeaf970 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 31 Oct 2019 10:36:32 +0100 Subject: [PATCH 089/131] Fix compatibility with Java 13 This commit upgrades jacoco to 0.8.5 as this version provides Java 13 support. Closes gh-458 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9802b8935..e8b4f2912 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 2.2.4 1.8.0 - 0.8.2 + 0.8.5 From d47820baadc25bc6b409ca3e7c2ebfd44bd48931 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 20 Nov 2019 09:55:36 +0000 Subject: [PATCH 090/131] Update to Spring Boot 2.2.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e8b4f2912..aab683b24 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.0.RELEASE + 2.2.1.RELEASE petclinic From 2c98a681ca89f60e560b141b205d63c6e2400ece Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 20 Nov 2019 09:56:32 +0000 Subject: [PATCH 091/131] Uncomment sql initialization for mysql --- src/main/resources/application-mysql.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index 823b32b69..38d81f99f 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -3,5 +3,5 @@ database=mysql spring.datasource.url=jdbc:mysql://localhost/petclinic spring.datasource.username=root spring.datasource.password=petclinic -# Uncomment this the first time the app runs -# spring.datasource.initialization-mode=always +# SQL is written to be idempotent so this is safe +spring.datasource.initialization-mode=always From 1561eb550655f293257e4486f4fb69bc00cf0229 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 20 Nov 2019 10:21:30 +0000 Subject: [PATCH 092/131] Add proxyBeanMethods = false It's slightly faster, and we don't need proxies in this app. --- .../petclinic/PetClinicApplication.java | 2 +- .../petclinic/system/CacheConfiguration.java | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index cf0c5e301..e09f0bdeb 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * @author Dave Syer * */ -@SpringBootApplication +@SpringBootApplication(proxyBeanMethods = false) public class PetClinicApplication { public static void main(String[] args) { diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index 9d4a53c64..4c083a41b 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -16,18 +16,19 @@ package org.springframework.samples.petclinic.system; +import javax.cache.configuration.MutableConfiguration; + import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.cache.configuration.MutableConfiguration; - /** - * Cache configuration intended for caches providing the JCache API. This configuration creates the used cache for the - * application and enables statistics that become accessible via JMX. + * Cache configuration intended for caches providing the JCache API. This configuration + * creates the used cache for the application and enables statistics that become + * accessible via JMX. */ -@Configuration +@Configuration(proxyBeanMethods = false) @EnableCaching class CacheConfiguration { @@ -39,11 +40,13 @@ class CacheConfiguration { } /** - * Create a simple configuration that enable statistics via the JCache programmatic configuration API. + * Create a simple configuration that enable statistics via the JCache programmatic + * configuration API. *

- * Within the configuration object that is provided by the JCache API standard, there is only a very limited set of - * configuration options. The really relevant configuration options (like the size limit) must be set via a - * configuration mechanism that is provided by the selected JCache implementation. + * Within the configuration object that is provided by the JCache API standard, there + * is only a very limited set of configuration options. The really relevant + * configuration options (like the size limit) must be set via a configuration + * mechanism that is provided by the selected JCache implementation. */ private javax.cache.configuration.Configuration cacheConfiguration() { return new MutableConfiguration<>().setStatisticsEnabled(true); From f9424b548ad476f1cffb7b013ea832d620963925 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Dec 2019 11:21:41 -0500 Subject: [PATCH 093/131] Spring Boot 2.2.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aab683b24..bf5ab1bf6 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.1.RELEASE + 2.2.2.RELEASE petclinic From 5d57e0d5e25fa5ff633719f36f8c4ce67ec1893c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Jan 2020 05:29:11 -0500 Subject: [PATCH 094/131] Re-organise mysql scripts so the app runs without root access It works better that way with test containers and in k8s. --- docker-compose.yml | 5 ++++- src/main/resources/application-mysql.properties | 2 +- .../resources/db/mysql/petclinic_db_setup_mysql.txt | 8 +++++--- src/main/resources/db/mysql/schema.sql | 10 ---------- src/main/resources/db/mysql/user.sql | 7 +++++++ 5 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/db/mysql/user.sql diff --git a/docker-compose.yml b/docker-compose.yml index 0f4a7fc30..5166fe90f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,10 @@ mysql: ports: - "3306:3306" environment: - - MYSQL_ROOT_PASSWORD=petclinic + - MYSQL_ROOT_PASSWORD= + - MYSQL_ALLOW_EMPTY_PASSWORD=true + - MYSQL_USER=petclinic + - MYSQL_PASSWORD=petclinic - MYSQL_DATABASE=petclinic volumes: - "./conf.d:/etc/mysql/conf.d:ro" diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index 38d81f99f..6d54ddad7 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -1,7 +1,7 @@ # database init, supports mysql too database=mysql spring.datasource.url=jdbc:mysql://localhost/petclinic -spring.datasource.username=root +spring.datasource.username=petclinic spring.datasource.password=petclinic # SQL is written to be idempotent so this is safe spring.datasource.initialization-mode=always diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index 920906687..f6ce6523c 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -18,12 +18,14 @@ mysql_1_eedb4818d817 | MySQL init process done. Ready for start up. ... -2) Create the PetClinic database and user by executing the "db/mysql/{schema,data}.sql" - scripts (or set "spring.datasource.initialization-mode=always" the first time you run the app). +2) (Once only) create the PetClinic database and user by executing the "db/mysql/user.sql" + scripts. You can connect to the database running in the docker container using + `mysql -u root -h localhost --protocol tcp`, but you don't need to run the script there + because the petclinic user is already set up if you use the provided `docker-compose.yaml`. 3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command line, but any way that sets that property in a Spring Boot app should work). N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value as it is configured by default. This condition is taken care of by the docker-compose -configuration provided, or by the `schema.sql` if you can run that as root. \ No newline at end of file +configuration provided, or by the `schema.sql` if you can run that as root. diff --git a/src/main/resources/db/mysql/schema.sql b/src/main/resources/db/mysql/schema.sql index 6a9825983..eb5d7d5d0 100644 --- a/src/main/resources/db/mysql/schema.sql +++ b/src/main/resources/db/mysql/schema.sql @@ -1,13 +1,3 @@ -CREATE DATABASE IF NOT EXISTS petclinic; - -ALTER DATABASE petclinic - DEFAULT CHARACTER SET utf8 - DEFAULT COLLATE utf8_general_ci; - -GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; - -USE petclinic; - CREATE TABLE IF NOT EXISTS vets ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(30), diff --git a/src/main/resources/db/mysql/user.sql b/src/main/resources/db/mysql/user.sql new file mode 100644 index 000000000..60abcee72 --- /dev/null +++ b/src/main/resources/db/mysql/user.sql @@ -0,0 +1,7 @@ +CREATE DATABASE IF NOT EXISTS petclinic; + +ALTER DATABASE petclinic + DEFAULT CHARACTER SET utf8 + DEFAULT COLLATE utf8_general_ci; + +GRANT ALL PRIVILEGES ON petclinic.* TO 'petclinic@%' IDENTIFIED BY 'petclinic'; From 82cb521d636b282340378d80a6307a08e3d4a4c4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Jan 2020 05:59:32 -0500 Subject: [PATCH 095/131] Fix MySQL docker command line in readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 34c8e8b84..77de7dc77 100644 --- a/readme.md +++ b/readme.md @@ -42,7 +42,7 @@ Note that whenever the database type is changed, the app needs to be run with a You could start MySql locally with whatever installer works for your OS, or with docker: ``` -docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 +docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 ``` Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). From 4e1f87407d80cdb4a5a293de89d62034fdcbb847 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Jan 2020 11:22:05 +0000 Subject: [PATCH 096/131] Apply spring-format plugin --- pom.xml | 15 + .../petclinic/PetClinicApplication.java | 6 +- .../samples/petclinic/model/BaseEntity.java | 25 +- .../samples/petclinic/model/NamedEntity.java | 29 +- .../samples/petclinic/model/Person.java | 36 +-- .../samples/petclinic/model/package-info.java | 1 - .../samples/petclinic/owner/Owner.java | 172 ++++++----- .../petclinic/owner/OwnerController.java | 175 +++++------ .../petclinic/owner/OwnerRepository.java | 54 ++-- .../samples/petclinic/owner/Pet.java | 95 +++--- .../petclinic/owner/PetController.java | 128 ++++---- .../petclinic/owner/PetRepository.java | 46 +-- .../samples/petclinic/owner/PetType.java | 3 +- .../petclinic/owner/PetTypeFormatter.java | 46 +-- .../samples/petclinic/owner/PetValidator.java | 54 ++-- .../petclinic/owner/VisitController.java | 86 +++--- .../petclinic/system/CacheConfiguration.java | 36 +-- .../petclinic/system/CrashController.java | 10 +- .../petclinic/system/WelcomeController.java | 10 +- .../samples/petclinic/vet/Vet.java | 50 +-- .../samples/petclinic/vet/VetController.java | 42 +-- .../samples/petclinic/vet/VetRepository.java | 23 +- .../samples/petclinic/vet/Vets.java | 20 +- .../samples/petclinic/visit/Visit.java | 64 ++-- .../petclinic/visit/VisitRepository.java | 22 +- .../petclinic/PetclinicIntegrationTests.java | 15 +- .../petclinic/model/ValidatorTests.java | 37 ++- .../petclinic/owner/OwnerControllerTests.java | 284 ++++++++---------- .../petclinic/owner/PetControllerTests.java | 134 ++++----- .../owner/PetTypeFormatterTests.java | 91 +++--- .../petclinic/owner/VisitControllerTests.java | 63 ++-- .../petclinic/service/ClinicServiceTests.java | 279 ++++++++--------- .../petclinic/service/EntityUtils.java | 39 ++- .../system/CrashControllerTests.java | 17 +- .../petclinic/vet/VetControllerTests.java | 66 ++-- .../samples/petclinic/vet/VetTests.java | 23 +- 36 files changed, 1128 insertions(+), 1168 deletions(-) diff --git a/pom.xml b/pom.xml index bf5ab1bf6..7cb6a8faf 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,7 @@ 1.8.0 0.8.5 + 0.0.17 @@ -130,6 +131,20 @@ + + io.spring.javaformat + spring-javaformat-maven-plugin + ${spring-format.version} + + + + validate + + validate + + + + org.springframework.boot spring-boot-maven-plugin diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index e09f0bdeb..191253587 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -28,8 +28,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(proxyBeanMethods = false) public class PetClinicApplication { - public static void main(String[] args) { - SpringApplication.run(PetClinicApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(PetClinicApplication.class, args); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java index 8350eb744..4cb9ffc0c 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java @@ -31,20 +31,21 @@ import javax.persistence.MappedSuperclass; */ @MappedSuperclass public class BaseEntity implements Serializable { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; - public Integer getId() { - return id; - } + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; - public void setId(Integer id) { - this.id = id; - } + public Integer getId() { + return id; + } - public boolean isNew() { - return this.id == null; - } + public void setId(Integer id) { + this.id = id; + } + + public boolean isNew() { + return this.id == null; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java index cc596a194..088e52e81 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java @@ -18,10 +18,9 @@ package org.springframework.samples.petclinic.model; import javax.persistence.Column; import javax.persistence.MappedSuperclass; - /** - * Simple JavaBean domain object adds a name property to BaseEntity. Used as a base class for objects - * needing these properties. + * Simple JavaBean domain object adds a name property to BaseEntity. Used as + * a base class for objects needing these properties. * * @author Ken Krebs * @author Juergen Hoeller @@ -29,20 +28,20 @@ import javax.persistence.MappedSuperclass; @MappedSuperclass public class NamedEntity extends BaseEntity { - @Column(name = "name") - private String name; + @Column(name = "name") + private String name; - public String getName() { - return this.name; - } + public String getName() { + return this.name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - @Override - public String toString() { - return this.getName(); - } + @Override + public String toString() { + return this.getName(); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index 883376fbc..15fabacc3 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -27,28 +27,28 @@ import javax.validation.constraints.NotEmpty; @MappedSuperclass public class Person extends BaseEntity { - @Column(name = "first_name") - @NotEmpty - private String firstName; + @Column(name = "first_name") + @NotEmpty + private String firstName; - @Column(name = "last_name") - @NotEmpty - private String lastName; + @Column(name = "last_name") + @NotEmpty + private String lastName; - public String getFirstName() { - return this.firstName; - } + public String getFirstName() { + return this.firstName; + } - public void setFirstName(String firstName) { - this.firstName = firstName; - } + public void setFirstName(String firstName) { + this.firstName = firstName; + } - public String getLastName() { - return this.lastName; - } + public String getLastName() { + return this.lastName; + } - public void setLastName(String lastName) { - this.lastName = lastName; - } + public void setLastName(String lastName) { + this.lastName = lastName; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/package-info.java b/src/main/java/org/springframework/samples/petclinic/model/package-info.java index 13c1673d5..37d6295e8 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/package-info.java +++ b/src/main/java/org/springframework/samples/petclinic/model/package-info.java @@ -18,4 +18,3 @@ * The classes in this package represent utilities used by the domain. */ package org.springframework.samples.petclinic.model; - diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java index 5b1b7fb36..61083bc8d 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -45,108 +45,106 @@ import org.springframework.samples.petclinic.model.Person; @Entity @Table(name = "owners") public class Owner extends Person { - @Column(name = "address") - @NotEmpty - private String address; - @Column(name = "city") - @NotEmpty - private String city; + @Column(name = "address") + @NotEmpty + private String address; - @Column(name = "telephone") - @NotEmpty - @Digits(fraction = 0, integer = 10) - private String telephone; + @Column(name = "city") + @NotEmpty + private String city; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") - private Set pets; + @Column(name = "telephone") + @NotEmpty + @Digits(fraction = 0, integer = 10) + private String telephone; - public String getAddress() { - return this.address; - } + @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") + private Set pets; - public void setAddress(String address) { - this.address = address; - } + public String getAddress() { + return this.address; + } - public String getCity() { - return this.city; - } + public void setAddress(String address) { + this.address = address; + } - public void setCity(String city) { - this.city = city; - } + public String getCity() { + return this.city; + } - public String getTelephone() { - return this.telephone; - } + public void setCity(String city) { + this.city = city; + } - public void setTelephone(String telephone) { - this.telephone = telephone; - } + public String getTelephone() { + return this.telephone; + } - protected Set getPetsInternal() { - if (this.pets == null) { - this.pets = new HashSet<>(); - } - return this.pets; - } + public void setTelephone(String telephone) { + this.telephone = telephone; + } - protected void setPetsInternal(Set pets) { - this.pets = pets; - } + protected Set getPetsInternal() { + if (this.pets == null) { + this.pets = new HashSet<>(); + } + return this.pets; + } - public List getPets() { - List sortedPets = new ArrayList<>(getPetsInternal()); - PropertyComparator.sort(sortedPets, - new MutableSortDefinition("name", true, true)); - return Collections.unmodifiableList(sortedPets); - } + protected void setPetsInternal(Set pets) { + this.pets = pets; + } - public void addPet(Pet pet) { - if (pet.isNew()) { - getPetsInternal().add(pet); - } - pet.setOwner(this); - } + public List getPets() { + List sortedPets = new ArrayList<>(getPetsInternal()); + PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedPets); + } - /** - * Return the Pet with the given name, or null if none found for this Owner. - * - * @param name to test - * @return true if pet name is already in use - */ - public Pet getPet(String name) { - return getPet(name, false); - } + public void addPet(Pet pet) { + if (pet.isNew()) { + getPetsInternal().add(pet); + } + pet.setOwner(this); + } - /** - * Return the Pet with the given name, or null if none found for this Owner. - * - * @param name to test - * @return true if pet name is already in use - */ - public Pet getPet(String name, boolean ignoreNew) { - name = name.toLowerCase(); - for (Pet pet : getPetsInternal()) { - if (!ignoreNew || !pet.isNew()) { - String compName = pet.getName(); - compName = compName.toLowerCase(); - if (compName.equals(name)) { - return pet; - } - } - } - return null; - } + /** + * Return the Pet with the given name, or null if none found for this Owner. + * @param name to test + * @return true if pet name is already in use + */ + public Pet getPet(String name) { + return getPet(name, false); + } - @Override - public String toString() { - return new ToStringCreator(this) + /** + * Return the Pet with the given name, or null if none found for this Owner. + * @param name to test + * @return true if pet name is already in use + */ + public Pet getPet(String name, boolean ignoreNew) { + name = name.toLowerCase(); + for (Pet pet : getPetsInternal()) { + if (!ignoreNew || !pet.isNew()) { + String compName = pet.getName(); + compName = compName.toLowerCase(); + if (compName.equals(name)) { + return pet; + } + } + } + return null; + } + + @Override + public String toString() { + return new ToStringCreator(this) + + .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName()) + .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city) + .append("telephone", this.telephone).toString(); + } - .append("id", this.getId()).append("new", this.isNew()) - .append("lastName", this.getLastName()) - .append("firstName", this.getFirstName()).append("address", this.address) - .append("city", this.city).append("telephone", this.telephone).toString(); - } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index afc2c937e..79aa4cd9b 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -39,102 +39,107 @@ import java.util.Map; @Controller class OwnerController { - private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; - private final OwnerRepository owners; - private VisitRepository visits; + private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; + private final OwnerRepository owners; - public OwnerController(OwnerRepository clinicService, VisitRepository visits) { - this.owners = clinicService; - this.visits = visits; - } + private VisitRepository visits; - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } + public OwnerController(OwnerRepository clinicService, VisitRepository visits) { + this.owners = clinicService; + this.visits = visits; + } - @GetMapping("/owners/new") - public String initCreationForm(Map model) { - Owner owner = new Owner(); - model.put("owner", owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } - @PostMapping("/owners/new") - public String processCreationForm(@Valid Owner owner, BindingResult result) { - if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } else { - this.owners.save(owner); - return "redirect:/owners/" + owner.getId(); - } - } + @GetMapping("/owners/new") + public String initCreationForm(Map model) { + Owner owner = new Owner(); + model.put("owner", owner); + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } - @GetMapping("/owners/find") - public String initFindForm(Map model) { - model.put("owner", new Owner()); - return "owners/findOwners"; - } + @PostMapping("/owners/new") + public String processCreationForm(@Valid Owner owner, BindingResult result) { + if (result.hasErrors()) { + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } + else { + this.owners.save(owner); + return "redirect:/owners/" + owner.getId(); + } + } - @GetMapping("/owners") - public String processFindForm(Owner owner, BindingResult result, Map model) { + @GetMapping("/owners/find") + public String initFindForm(Map model) { + model.put("owner", new Owner()); + return "owners/findOwners"; + } - // allow parameterless GET request for /owners to return all records - if (owner.getLastName() == null) { - owner.setLastName(""); // empty string signifies broadest possible search - } + @GetMapping("/owners") + public String processFindForm(Owner owner, BindingResult result, Map model) { - // find owners by last name - Collection results = this.owners.findByLastName(owner.getLastName()); - if (results.isEmpty()) { - // no owners found - result.rejectValue("lastName", "notFound", "not found"); - return "owners/findOwners"; - } else if (results.size() == 1) { - // 1 owner found - owner = results.iterator().next(); - return "redirect:/owners/" + owner.getId(); - } else { - // multiple owners found - model.put("selections", results); - return "owners/ownersList"; - } - } + // allow parameterless GET request for /owners to return all records + if (owner.getLastName() == null) { + owner.setLastName(""); // empty string signifies broadest possible search + } - @GetMapping("/owners/{ownerId}/edit") - public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { - Owner owner = this.owners.findById(ownerId); - model.addAttribute(owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } + // find owners by last name + Collection results = this.owners.findByLastName(owner.getLastName()); + if (results.isEmpty()) { + // no owners found + result.rejectValue("lastName", "notFound", "not found"); + return "owners/findOwners"; + } + else if (results.size() == 1) { + // 1 owner found + owner = results.iterator().next(); + return "redirect:/owners/" + owner.getId(); + } + else { + // multiple owners found + model.put("selections", results); + return "owners/ownersList"; + } + } - @PostMapping("/owners/{ownerId}/edit") - public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) { - if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } else { - owner.setId(ownerId); - this.owners.save(owner); - return "redirect:/owners/{ownerId}"; - } - } + @GetMapping("/owners/{ownerId}/edit") + public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { + Owner owner = this.owners.findById(ownerId); + model.addAttribute(owner); + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } - /** - * Custom handler for displaying an owner. - * - * @param ownerId the ID of the owner to display - * @return a ModelMap with the model attributes for the view - */ - @GetMapping("/owners/{ownerId}") - public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { - ModelAndView mav = new ModelAndView("owners/ownerDetails"); - Owner owner = this.owners.findById(ownerId); - for (Pet pet : owner.getPets()) { - pet.setVisitsInternal(visits.findByPetId(pet.getId())); - } - mav.addObject(owner); - return mav; - } + @PostMapping("/owners/{ownerId}/edit") + public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, + @PathVariable("ownerId") int ownerId) { + if (result.hasErrors()) { + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } + else { + owner.setId(ownerId); + this.owners.save(owner); + return "redirect:/owners/{ownerId}"; + } + } + + /** + * Custom handler for displaying an owner. + * @param ownerId the ID of the owner to display + * @return a ModelMap with the model attributes for the view + */ + @GetMapping("/owners/{ownerId}") + public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { + ModelAndView mav = new ModelAndView("owners/ownerDetails"); + Owner owner = this.owners.findById(ownerId); + for (Pet pet : owner.getPets()) { + pet.setVisitsInternal(visits.findByPetId(pet.getId())); + } + mav.addObject(owner); + return mav; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java index a5803f36a..0613e928a 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java @@ -23,9 +23,10 @@ import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; /** - * Repository class for Owner domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Owner domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -34,31 +35,30 @@ import org.springframework.transaction.annotation.Transactional; */ public interface OwnerRepository extends Repository { - /** - * Retrieve {@link Owner}s from the data store by last name, returning all owners - * whose last name starts with the given name. - * @param lastName Value to search for - * @return a Collection of matching {@link Owner}s (or an empty Collection if none - * found) - */ - @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") - @Transactional(readOnly = true) - Collection findByLastName(@Param("lastName") String lastName); + /** + * Retrieve {@link Owner}s from the data store by last name, returning all owners + * whose last name starts with the given name. + * @param lastName Value to search for + * @return a Collection of matching {@link Owner}s (or an empty Collection if none + * found) + */ + @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") + @Transactional(readOnly = true) + Collection findByLastName(@Param("lastName") String lastName); - /** - * Retrieve an {@link Owner} from the data store by id. - * @param id the id to search for - * @return the {@link Owner} if found - */ - @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") - @Transactional(readOnly = true) - Owner findById(@Param("id") Integer id); - - /** - * Save an {@link Owner} to the data store, either inserting or updating it. - * @param owner the {@link Owner} to save - */ - void save(Owner owner); + /** + * Retrieve an {@link Owner} from the data store by id. + * @param id the id to search for + * @return the {@link Owner} if found + */ + @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") + @Transactional(readOnly = true) + Owner findById(@Param("id") Integer id); + /** + * Save an {@link Owner} to the data store, either inserting or updating it. + * @param owner the {@link Owner} to save + */ + void save(Owner owner); } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java index 0bd04b772..2b68005fd 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -48,66 +48,65 @@ import org.springframework.samples.petclinic.visit.Visit; @Table(name = "pets") public class Pet extends NamedEntity { - @Column(name = "birth_date") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate birthDate; + @Column(name = "birth_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate birthDate; - @ManyToOne - @JoinColumn(name = "type_id") - private PetType type; + @ManyToOne + @JoinColumn(name = "type_id") + private PetType type; - @ManyToOne - @JoinColumn(name = "owner_id") - private Owner owner; + @ManyToOne + @JoinColumn(name = "owner_id") + private Owner owner; - @Transient - private Set visits = new LinkedHashSet<>(); + @Transient + private Set visits = new LinkedHashSet<>(); - public void setBirthDate(LocalDate birthDate) { - this.birthDate = birthDate; - } + public void setBirthDate(LocalDate birthDate) { + this.birthDate = birthDate; + } - public LocalDate getBirthDate() { - return this.birthDate; - } + public LocalDate getBirthDate() { + return this.birthDate; + } - public PetType getType() { - return this.type; - } + public PetType getType() { + return this.type; + } - public void setType(PetType type) { - this.type = type; - } + public void setType(PetType type) { + this.type = type; + } - public Owner getOwner() { - return this.owner; - } + public Owner getOwner() { + return this.owner; + } - protected void setOwner(Owner owner) { - this.owner = owner; - } + protected void setOwner(Owner owner) { + this.owner = owner; + } - protected Set getVisitsInternal() { - if (this.visits == null) { - this.visits = new HashSet<>(); - } - return this.visits; - } + protected Set getVisitsInternal() { + if (this.visits == null) { + this.visits = new HashSet<>(); + } + return this.visits; + } - protected void setVisitsInternal(Collection visits) { - this.visits = new LinkedHashSet<>(visits); - } + protected void setVisitsInternal(Collection visits) { + this.visits = new LinkedHashSet<>(visits); + } - public List getVisits() { - List sortedVisits = new ArrayList<>(getVisitsInternal()); - PropertyComparator.sort(sortedVisits, - new MutableSortDefinition("date", false, false)); - return Collections.unmodifiableList(sortedVisits); - } + public List getVisits() { + List sortedVisits = new ArrayList<>(getVisitsInternal()); + PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false)); + return Collections.unmodifiableList(sortedVisits); + } - public void addVisit(Visit visit) { - getVisitsInternal().add(visit); - visit.setPetId(this.getId()); - } + public void addVisit(Visit visit) { + getVisitsInternal().add(visit); + visit.setPetId(this.getId()); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java index 0107aa8a9..a55e599af 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java @@ -34,76 +34,80 @@ import java.util.Collection; @RequestMapping("/owners/{ownerId}") class PetController { - private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - private final PetRepository pets; - private final OwnerRepository owners; + private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - public PetController(PetRepository pets, OwnerRepository owners) { - this.pets = pets; - this.owners = owners; - } + private final PetRepository pets; - @ModelAttribute("types") - public Collection populatePetTypes() { - return this.pets.findPetTypes(); - } + private final OwnerRepository owners; - @ModelAttribute("owner") - public Owner findOwner(@PathVariable("ownerId") int ownerId) { - return this.owners.findById(ownerId); - } + public PetController(PetRepository pets, OwnerRepository owners) { + this.pets = pets; + this.owners = owners; + } - @InitBinder("owner") - public void initOwnerBinder(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } + @ModelAttribute("types") + public Collection populatePetTypes() { + return this.pets.findPetTypes(); + } - @InitBinder("pet") - public void initPetBinder(WebDataBinder dataBinder) { - dataBinder.setValidator(new PetValidator()); - } + @ModelAttribute("owner") + public Owner findOwner(@PathVariable("ownerId") int ownerId) { + return this.owners.findById(ownerId); + } - @GetMapping("/pets/new") - public String initCreationForm(Owner owner, ModelMap model) { - Pet pet = new Pet(); - owner.addPet(pet); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } + @InitBinder("owner") + public void initOwnerBinder(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } - @PostMapping("/pets/new") - public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { - if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){ - result.rejectValue("name", "duplicate", "already exists"); - } - owner.addPet(pet); - if (result.hasErrors()) { - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { - this.pets.save(pet); - return "redirect:/owners/{ownerId}"; - } - } + @InitBinder("pet") + public void initPetBinder(WebDataBinder dataBinder) { + dataBinder.setValidator(new PetValidator()); + } - @GetMapping("/pets/{petId}/edit") - public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { - Pet pet = this.pets.findById(petId); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } + @GetMapping("/pets/new") + public String initCreationForm(Owner owner, ModelMap model) { + Pet pet = new Pet(); + owner.addPet(pet); + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } - @PostMapping("/pets/{petId}/edit") - public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { - if (result.hasErrors()) { - pet.setOwner(owner); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { - owner.addPet(pet); - this.pets.save(pet); - return "redirect:/owners/{ownerId}"; - } - } + @PostMapping("/pets/new") + public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { + if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { + result.rejectValue("name", "duplicate", "already exists"); + } + owner.addPet(pet); + if (result.hasErrors()) { + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } + else { + this.pets.save(pet); + return "redirect:/owners/{ownerId}"; + } + } + + @GetMapping("/pets/{petId}/edit") + public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { + Pet pet = this.pets.findById(petId); + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } + + @PostMapping("/pets/{petId}/edit") + public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { + if (result.hasErrors()) { + pet.setOwner(owner); + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } + else { + owner.addPet(pet); + this.pets.save(pet); + return "redirect:/owners/{ownerId}"; + } + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java index 0d483b7ad..9d25b095b 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java @@ -22,9 +22,10 @@ import org.springframework.data.repository.Repository; import org.springframework.transaction.annotation.Transactional; /** - * Repository class for Pet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Pet domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -33,27 +34,26 @@ import org.springframework.transaction.annotation.Transactional; */ public interface PetRepository extends Repository { - /** - * Retrieve all {@link PetType}s from the data store. - * @return a Collection of {@link PetType}s. - */ - @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") - @Transactional(readOnly = true) - List findPetTypes(); + /** + * Retrieve all {@link PetType}s from the data store. + * @return a Collection of {@link PetType}s. + */ + @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") + @Transactional(readOnly = true) + List findPetTypes(); - /** - * Retrieve a {@link Pet} from the data store by id. - * @param id the id to search for - * @return the {@link Pet} if found - */ - @Transactional(readOnly = true) - Pet findById(Integer id); + /** + * Retrieve a {@link Pet} from the data store by id. + * @param id the id to search for + * @return the {@link Pet} if found + */ + @Transactional(readOnly = true) + Pet findById(Integer id); - /** - * Save a {@link Pet} to the data store, either inserting or updating it. - * @param pet the {@link Pet} to save - */ - void save(Pet pet); + /** + * Save a {@link Pet} to the data store, either inserting or updating it. + * @param pet the {@link Pet} to save + */ + void save(Pet pet); } - diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java index 19c27bee3..6f0aa58d3 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java @@ -21,8 +21,7 @@ import javax.persistence.Table; import org.springframework.samples.petclinic.model.NamedEntity; /** - * @author Juergen Hoeller - * Can be Cat, Dog, Hamster... + * @author Juergen Hoeller Can be Cat, Dog, Hamster... */ @Entity @Table(name = "types") diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java index 4423482a3..4940bcb38 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java @@ -24,9 +24,10 @@ import org.springframework.format.Formatter; import org.springframework.stereotype.Component; /** - * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have - * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The - * Spring ref doc: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format + * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting + * from Spring 3.0, Formatters have come as an improvement in comparison to legacy + * PropertyEditors. See the following links for more details: - The Spring ref doc: + * https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format * * @author Mark Fisher * @author Juergen Hoeller @@ -35,28 +36,27 @@ import org.springframework.stereotype.Component; @Component public class PetTypeFormatter implements Formatter { - private final PetRepository pets; + private final PetRepository pets; + @Autowired + public PetTypeFormatter(PetRepository pets) { + this.pets = pets; + } - @Autowired - public PetTypeFormatter(PetRepository pets) { - this.pets = pets; - } + @Override + public String print(PetType petType, Locale locale) { + return petType.getName(); + } - @Override - public String print(PetType petType, Locale locale) { - return petType.getName(); - } - - @Override - public PetType parse(String text, Locale locale) throws ParseException { - Collection findPetTypes = this.pets.findPetTypes(); - for (PetType type : findPetTypes) { - if (type.getName().equals(text)) { - return type; - } - } - throw new ParseException("type not found: " + text, 0); - } + @Override + public PetType parse(String text, Locale locale) throws ParseException { + Collection findPetTypes = this.pets.findPetTypes(); + for (PetType type : findPetTypes) { + if (type.getName().equals(text)) { + return type; + } + } + throw new ParseException("type not found: " + text, 0); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java index 3e8438b33..e1370b428 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java @@ -22,7 +22,8 @@ import org.springframework.validation.Validator; /** * Validator for Pet forms. *

- * We're not using Bean Validation annotations here because it is easier to define such validation rule in Java. + * We're not using Bean Validation annotations here because it is easier to define such + * validation rule in Java. *

* * @author Ken Krebs @@ -30,35 +31,34 @@ import org.springframework.validation.Validator; */ public class PetValidator implements Validator { - private static final String REQUIRED = "required"; + private static final String REQUIRED = "required"; - @Override - public void validate(Object obj, Errors errors) { - Pet pet = (Pet) obj; - String name = pet.getName(); - // name validation - if (!StringUtils.hasLength(name)) { - errors.rejectValue("name", REQUIRED, REQUIRED); - } + @Override + public void validate(Object obj, Errors errors) { + Pet pet = (Pet) obj; + String name = pet.getName(); + // name validation + if (!StringUtils.hasLength(name)) { + errors.rejectValue("name", REQUIRED, REQUIRED); + } - // type validation - if (pet.isNew() && pet.getType() == null) { - errors.rejectValue("type", REQUIRED, REQUIRED); - } + // type validation + if (pet.isNew() && pet.getType() == null) { + errors.rejectValue("type", REQUIRED, REQUIRED); + } - // birth date validation - if (pet.getBirthDate() == null) { - errors.rejectValue("birthDate", REQUIRED, REQUIRED); - } - } - - /** - * This Validator validates *just* Pet instances - */ - @Override - public boolean supports(Class clazz) { - return Pet.class.isAssignableFrom(clazz); - } + // birth date validation + if (pet.getBirthDate() == null) { + errors.rejectValue("birthDate", REQUIRED, REQUIRED); + } + } + /** + * This Validator validates *just* Pet instances + */ + @Override + public boolean supports(Class clazz) { + return Pet.class.isAssignableFrom(clazz); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index c6dfc7fc7..375980312 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -40,55 +40,53 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller class VisitController { - private final VisitRepository visits; - private final PetRepository pets; + private final VisitRepository visits; + private final PetRepository pets; - public VisitController(VisitRepository visits, PetRepository pets) { - this.visits = visits; - this.pets = pets; - } + public VisitController(VisitRepository visits, PetRepository pets) { + this.visits = visits; + this.pets = pets; + } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } - /** - * Called before each and every @RequestMapping annotated method. - * 2 goals: - * - Make sure we always have fresh data - * - Since we do not use the session scope, make sure that Pet object always has an id - * (Even though id is not part of the form fields) - * - * @param petId - * @return Pet - */ - @ModelAttribute("visit") - public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) { - Pet pet = this.pets.findById(petId); - pet.setVisitsInternal(this.visits.findByPetId(petId)); - model.put("pet", pet); - Visit visit = new Visit(); - pet.addVisit(visit); - return visit; - } + /** + * Called before each and every @RequestMapping annotated method. 2 goals: - Make sure + * we always have fresh data - Since we do not use the session scope, make sure that + * Pet object always has an id (Even though id is not part of the form fields) + * @param petId + * @return Pet + */ + @ModelAttribute("visit") + public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) { + Pet pet = this.pets.findById(petId); + pet.setVisitsInternal(this.visits.findByPetId(petId)); + model.put("pet", pet); + Visit visit = new Visit(); + pet.addVisit(visit); + return visit; + } - // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called - @GetMapping("/owners/*/pets/{petId}/visits/new") - public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { - return "pets/createOrUpdateVisitForm"; - } + // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called + @GetMapping("/owners/*/pets/{petId}/visits/new") + public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { + return "pets/createOrUpdateVisitForm"; + } - // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called - @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") - public String processNewVisitForm(@Valid Visit visit, BindingResult result) { - if (result.hasErrors()) { - return "pets/createOrUpdateVisitForm"; - } else { - this.visits.save(visit); - return "redirect:/owners/{ownerId}"; - } - } + // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called + @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") + public String processNewVisitForm(@Valid Visit visit, BindingResult result) { + if (result.hasErrors()) { + return "pets/createOrUpdateVisitForm"; + } + else { + this.visits.save(visit); + return "redirect:/owners/{ownerId}"; + } + } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index 4c083a41b..0a96582c9 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -32,24 +32,24 @@ import org.springframework.context.annotation.Configuration; @EnableCaching class CacheConfiguration { - @Bean - public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { - return cm -> { - cm.createCache("vets", cacheConfiguration()); - }; - } + @Bean + public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { + return cm -> { + cm.createCache("vets", cacheConfiguration()); + }; + } - /** - * Create a simple configuration that enable statistics via the JCache programmatic - * configuration API. - *

- * Within the configuration object that is provided by the JCache API standard, there - * is only a very limited set of configuration options. The really relevant - * configuration options (like the size limit) must be set via a configuration - * mechanism that is provided by the selected JCache implementation. - */ - private javax.cache.configuration.Configuration cacheConfiguration() { - return new MutableConfiguration<>().setStatisticsEnabled(true); - } + /** + * Create a simple configuration that enable statistics via the JCache programmatic + * configuration API. + *

+ * Within the configuration object that is provided by the JCache API standard, there + * is only a very limited set of configuration options. The really relevant + * configuration options (like the size limit) must be set via a configuration + * mechanism that is provided by the selected JCache implementation. + */ + private javax.cache.configuration.Configuration cacheConfiguration() { + return new MutableConfiguration<>().setStatisticsEnabled(true); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java index 05be70429..2b28600fd 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java @@ -28,10 +28,10 @@ import org.springframework.web.bind.annotation.GetMapping; @Controller class CrashController { - @GetMapping("/oups") - public String triggerException() { - throw new RuntimeException("Expected: controller used to showcase what " - + "happens when an exception is thrown"); - } + @GetMapping("/oups") + public String triggerException() { + throw new RuntimeException( + "Expected: controller used to showcase what " + "happens when an exception is thrown"); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java index 7e96848b6..9224015bc 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java @@ -16,15 +16,15 @@ package org.springframework.samples.petclinic.system; - import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller class WelcomeController { - @GetMapping("/") - public String welcome() { - return "welcome"; - } + @GetMapping("/") + public String welcome() { + return "welcome"; + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java index 33b449129..014becfce 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java @@ -45,35 +45,35 @@ import org.springframework.samples.petclinic.model.Person; @Table(name = "vets") public class Vet extends Person { - @ManyToMany(fetch = FetchType.EAGER) - @JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"), inverseJoinColumns = @JoinColumn(name = "specialty_id")) - private Set specialties; + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"), + inverseJoinColumns = @JoinColumn(name = "specialty_id")) + private Set specialties; - protected Set getSpecialtiesInternal() { - if (this.specialties == null) { - this.specialties = new HashSet<>(); - } - return this.specialties; - } + protected Set getSpecialtiesInternal() { + if (this.specialties == null) { + this.specialties = new HashSet<>(); + } + return this.specialties; + } - protected void setSpecialtiesInternal(Set specialties) { - this.specialties = specialties; - } + protected void setSpecialtiesInternal(Set specialties) { + this.specialties = specialties; + } - @XmlElement - public List getSpecialties() { - List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); - PropertyComparator.sort(sortedSpecs, - new MutableSortDefinition("name", true, true)); - return Collections.unmodifiableList(sortedSpecs); - } + @XmlElement + public List getSpecialties() { + List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); + PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedSpecs); + } - public int getNrOfSpecialties() { - return getSpecialtiesInternal().size(); - } + public int getNrOfSpecialties() { + return getSpecialtiesInternal().size(); + } - public void addSpecialty(Specialty specialty) { - getSpecialtiesInternal().add(specialty); - } + public void addSpecialty(Specialty specialty) { + getSpecialtiesInternal().add(specialty); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index f15f40b2c..fb5e321ba 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -30,29 +30,29 @@ import java.util.Map; @Controller class VetController { - private final VetRepository vets; + private final VetRepository vets; - public VetController(VetRepository clinicService) { - this.vets = clinicService; - } + public VetController(VetRepository clinicService) { + this.vets = clinicService; + } - @GetMapping("/vets.html") - public String showVetList(Map model) { - // Here we are returning an object of type 'Vets' rather than a collection of Vet - // objects so it is simpler for Object-Xml mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.vets.findAll()); - model.put("vets", vets); - return "vets/vetList"; - } + @GetMapping("/vets.html") + public String showVetList(Map model) { + // Here we are returning an object of type 'Vets' rather than a collection of Vet + // objects so it is simpler for Object-Xml mapping + Vets vets = new Vets(); + vets.getVetList().addAll(this.vets.findAll()); + model.put("vets", vets); + return "vets/vetList"; + } - @GetMapping({ "/vets" }) - public @ResponseBody Vets showResourcesVetList() { - // Here we are returning an object of type 'Vets' rather than a collection of Vet - // objects so it is simpler for JSon/Object mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.vets.findAll()); - return vets; - } + @GetMapping({ "/vets" }) + public @ResponseBody Vets showResourcesVetList() { + // Here we are returning an object of type 'Vets' rather than a collection of Vet + // objects so it is simpler for JSon/Object mapping + Vets vets = new Vets(); + vets.getVetList().addAll(this.vets.findAll()); + return vets; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java index 1f70182fd..549b1c229 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java @@ -23,9 +23,10 @@ import org.springframework.data.repository.Repository; import org.springframework.transaction.annotation.Transactional; /** - * Repository class for Vet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Vet domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -34,14 +35,12 @@ import org.springframework.transaction.annotation.Transactional; */ public interface VetRepository extends Repository { - /** - * Retrieve all Vets from the data store. - * - * @return a Collection of Vets - */ - @Transactional(readOnly = true) - @Cacheable("vets") - Collection findAll() throws DataAccessException; - + /** + * Retrieve all Vets from the data store. + * @return a Collection of Vets + */ + @Transactional(readOnly = true) + @Cacheable("vets") + Collection findAll() throws DataAccessException; } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java index ab29f7a54..cea665629 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java @@ -22,22 +22,22 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** - * Simple domain object representing a list of veterinarians. Mostly here to be used for the 'vets' {@link - * org.springframework.web.servlet.view.xml.MarshallingView}. + * Simple domain object representing a list of veterinarians. Mostly here to be used for + * the 'vets' {@link org.springframework.web.servlet.view.xml.MarshallingView}. * * @author Arjen Poutsma */ @XmlRootElement public class Vets { - private List vets; + private List vets; - @XmlElement - public List getVetList() { - if (vets == null) { - vets = new ArrayList<>(); - } - return vets; - } + @XmlElement + public List getVetList() { + if (vets == null) { + vets = new ArrayList<>(); + } + return vets; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index 03c9deedf..df9f25fe0 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -35,46 +35,46 @@ import org.springframework.samples.petclinic.model.BaseEntity; @Table(name = "visits") public class Visit extends BaseEntity { - @Column(name = "visit_date") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate date; + @Column(name = "visit_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate date; - @NotEmpty - @Column(name = "description") - private String description; + @NotEmpty + @Column(name = "description") + private String description; - @Column(name = "pet_id") - private Integer petId; + @Column(name = "pet_id") + private Integer petId; - /** - * Creates a new instance of Visit for the current date - */ - public Visit() { - this.date = LocalDate.now(); - } + /** + * Creates a new instance of Visit for the current date + */ + public Visit() { + this.date = LocalDate.now(); + } - public LocalDate getDate() { - return this.date; - } + public LocalDate getDate() { + return this.date; + } - public void setDate(LocalDate date) { - this.date = date; - } + public void setDate(LocalDate date) { + this.date = date; + } - public String getDescription() { - return this.description; - } + public String getDescription() { + return this.description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - public Integer getPetId() { - return this.petId; - } + public Integer getPetId() { + return this.petId; + } - public void setPetId(Integer petId) { - this.petId = petId; - } + public void setPetId(Integer petId) { + this.petId = petId; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java index 42b58618b..d5a3334c6 100644 --- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java @@ -22,9 +22,10 @@ import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; /** - * Repository class for Visit domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Visit domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -33,14 +34,13 @@ import org.springframework.samples.petclinic.model.BaseEntity; */ public interface VisitRepository extends Repository { - /** - * Save a Visit to the data store, either inserting or updating it. - * - * @param visit the Visit to save - * @see BaseEntity#isNew - */ - void save(Visit visit) throws DataAccessException; + /** + * Save a Visit to the data store, either inserting or updating it. + * @param visit the Visit to save + * @see BaseEntity#isNew + */ + void save(Visit visit) throws DataAccessException; - List findByPetId(Integer petId); + List findByPetId(Integer petId); } diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java index 217d552f4..226db01fe 100644 --- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -24,12 +24,13 @@ import org.springframework.samples.petclinic.vet.VetRepository; @SpringBootTest class PetclinicIntegrationTests { - @Autowired - private VetRepository vets; + @Autowired + private VetRepository vets; + + @Test + void testFindAll() throws Exception { + vets.findAll(); + vets.findAll(); // served from cache + } - @Test - void testFindAll() throws Exception { - vets.findAll(); - vets.findAll(); // served from cache - } } diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index 4be38f714..8d754900d 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -34,28 +34,27 @@ import static org.assertj.core.api.Assertions.assertThat; */ class ValidatorTests { - private Validator createValidator() { - LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); - localValidatorFactoryBean.afterPropertiesSet(); - return localValidatorFactoryBean; - } + private Validator createValidator() { + LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); + localValidatorFactoryBean.afterPropertiesSet(); + return localValidatorFactoryBean; + } - @Test - void shouldNotValidateWhenFirstNameEmpty() { + @Test + void shouldNotValidateWhenFirstNameEmpty() { - LocaleContextHolder.setLocale(Locale.ENGLISH); - Person person = new Person(); - person.setFirstName(""); - person.setLastName("smith"); + LocaleContextHolder.setLocale(Locale.ENGLISH); + Person person = new Person(); + person.setFirstName(""); + person.setLastName("smith"); - Validator validator = createValidator(); - Set> constraintViolations = validator - .validate(person); + Validator validator = createValidator(); + Set> constraintViolations = validator.validate(person); - assertThat(constraintViolations).hasSize(1); - ConstraintViolation violation = constraintViolations.iterator().next(); - assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName"); - assertThat(violation.getMessage()).isEqualTo("must not be empty"); - } + assertThat(constraintViolations).hasSize(1); + ConstraintViolation violation = constraintViolations.iterator().next(); + assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName"); + assertThat(violation.getMessage()).isEqualTo("must not be empty"); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 1956e2a24..1d6249c5d 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -51,181 +51,149 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @WebMvcTest(OwnerController.class) class OwnerControllerTests { - private static final int TEST_OWNER_ID = 1; + private static final int TEST_OWNER_ID = 1; - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private OwnerRepository owners; + @MockBean + private OwnerRepository owners; - @MockBean - private VisitRepository visits; + @MockBean + private VisitRepository visits; - private Owner george; + private Owner george; - @BeforeEach - void setup() { - george = new Owner(); - george.setId(TEST_OWNER_ID); - george.setFirstName("George"); - george.setLastName("Franklin"); - george.setAddress("110 W. Liberty St."); - george.setCity("Madison"); - george.setTelephone("6085551023"); - Pet max = new Pet(); - PetType dog = new PetType(); - dog.setName("dog"); - max.setId(1); - max.setType(dog); - max.setName("Max"); - max.setBirthDate(LocalDate.now()); - george.setPetsInternal(Collections.singleton(max)); - given(this.owners.findById(TEST_OWNER_ID)).willReturn(george); - Visit visit = new Visit(); - visit.setDate(LocalDate.now()); - given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit)); - } + @BeforeEach + void setup() { + george = new Owner(); + george.setId(TEST_OWNER_ID); + george.setFirstName("George"); + george.setLastName("Franklin"); + george.setAddress("110 W. Liberty St."); + george.setCity("Madison"); + george.setTelephone("6085551023"); + Pet max = new Pet(); + PetType dog = new PetType(); + dog.setName("dog"); + max.setId(1); + max.setType(dog); + max.setName("Max"); + max.setBirthDate(LocalDate.now()); + george.setPetsInternal(Collections.singleton(max)); + given(this.owners.findById(TEST_OWNER_ID)).willReturn(george); + Visit visit = new Visit(); + visit.setDate(LocalDate.now()); + given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit)); + } - @Test - void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/new")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/owners/new")).andExpect(status().isOk()).andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01316761638") - ) - .andExpect(status().is3xxRedirection()); - } + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs") + .param("address", "123 Caramel Street").param("city", "London").param("telephone", "01316761638")) + .andExpect(status().is3xxRedirection()); + } - @Test - void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform( + post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London")) + .andExpect(status().isOk()).andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testInitFindForm() throws Exception { - mockMvc.perform(get("/owners/find")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/findOwners")); - } + @Test + void testInitFindForm() throws Exception { + mockMvc.perform(get("/owners/find")).andExpect(status().isOk()).andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/findOwners")); + } - @Test - void testProcessFindFormSuccess() throws Exception { - given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner())); - mockMvc.perform(get("/owners")) - .andExpect(status().isOk()) - .andExpect(view().name("owners/ownersList")); - } + @Test + void testProcessFindFormSuccess() throws Exception { + given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner())); + mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList")); + } - @Test - void testProcessFindFormByLastName() throws Exception { - given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); - mockMvc.perform(get("/owners") - .param("lastName", "Franklin") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); - } + @Test + void testProcessFindFormByLastName() throws Exception { + given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); + mockMvc.perform(get("/owners").param("lastName", "Franklin")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); + } - @Test - void testProcessFindFormNoOwnersFound() throws Exception { - mockMvc.perform(get("/owners") - .param("lastName", "Unknown Surname") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors("owner", "lastName")) - .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) - .andExpect(view().name("owners/findOwners")); - } + @Test + void testProcessFindFormNoOwnersFound() throws Exception { + mockMvc.perform(get("/owners").param("lastName", "Unknown Surname")).andExpect(status().isOk()) + .andExpect(model().attributeHasFieldErrors("owner", "lastName")) + .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) + .andExpect(view().name("owners/findOwners")); + } - @Test - void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testInitUpdateOwnerForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) + .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) + .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testProcessUpdateOwnerFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01616291589") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessUpdateOwnerFormSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") + .param("lastName", "Bloggs").param("address", "123 Caramel Street").param("city", "London") + .param("telephone", "01616291589")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testProcessUpdateOwnerFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") + .param("lastName", "Bloggs").param("city", "London")).andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testShowOwner() throws Exception { - mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(model().attribute("owner", hasProperty("pets", not(empty())))) - .andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher>() { + @Test + void testShowOwner() throws Exception { + mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) + .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) + .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(model().attribute("owner", hasProperty("pets", not(empty())))) + .andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher>() { - @Override - public boolean matches(Object item) { - @SuppressWarnings("unchecked") - List pets = (List) item; - Pet pet = pets.get(0); - if (pet.getVisits().isEmpty()) { - return false; - } - return true; - } + @Override + public boolean matches(Object item) { + @SuppressWarnings("unchecked") + List pets = (List) item; + Pet pet = pets.get(0); + if (pet.getVisits().isEmpty()) { + return false; + } + return true; + } - @Override - public void describeTo(Description description) { - description.appendText("Max did not have any visits"); - }}))) - .andExpect(view().name("owners/ownerDetails")); - } + @Override + public void describeTo(Description description) { + description.appendText("Max did not have any visits"); + } + }))).andExpect(view().name("owners/ownerDetails")); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index f7c8fe726..47c444a78 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -39,97 +39,75 @@ import org.springframework.test.web.servlet.MockMvc; * @author Colin But */ @WebMvcTest(value = PetController.class, - includeFilters = @ComponentScan.Filter( - value = PetTypeFormatter.class, - type = FilterType.ASSIGNABLE_TYPE)) + includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE)) class PetControllerTests { - private static final int TEST_OWNER_ID = 1; - private static final int TEST_PET_ID = 1; + private static final int TEST_OWNER_ID = 1; + private static final int TEST_PET_ID = 1; - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private PetRepository pets; + @MockBean + private PetRepository pets; - @MockBean - private OwnerRepository owners; + @MockBean + private OwnerRepository owners; - @BeforeEach - void setup() { - PetType cat = new PetType(); - cat.setId(3); - cat.setName("hamster"); - given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat)); - given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner()); - given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); + @BeforeEach + void setup() { + PetType cat = new PetType(); + cat.setId(3); + cat.setName("hamster"); + given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat)); + given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner()); + given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); - } + } - @Test - void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")) - .andExpect(model().attributeExists("pet")); - } + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet")); + } - @Test - void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015-02-12") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty") + .param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("birthDate", "2015-02-12") - ) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(model().attributeHasFieldErrors("pet", "type")) - .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate", + "2015-02-12")).andExpect(model().attributeHasNoErrors("owner")) + .andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type")) + .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")); + } - @Test - void testInitUpdateForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("pet")) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } + @Test + void testInitUpdateForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) + .andExpect(status().isOk()).andExpect(model().attributeExists("pet")) + .andExpect(view().name("pets/createOrUpdatePetForm")); + } - @Test - void testProcessUpdateFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015-02-12") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessUpdateFormSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty") + .param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessUpdateFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("birthDate", "2015/02/12") - ) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } + @Test + void testProcessUpdateFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty") + .param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner")) + .andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index e27fce21e..adb96b69d 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -40,57 +40,56 @@ import static org.mockito.BDDMockito.given; @ExtendWith(MockitoExtension.class) class PetTypeFormatterTests { - @Mock - private PetRepository pets; + @Mock + private PetRepository pets; - private PetTypeFormatter petTypeFormatter; + private PetTypeFormatter petTypeFormatter; - @BeforeEach - void setup() { - this.petTypeFormatter = new PetTypeFormatter(pets); - } + @BeforeEach + void setup() { + this.petTypeFormatter = new PetTypeFormatter(pets); + } - @Test - void testPrint() { - PetType petType = new PetType(); - petType.setName("Hamster"); - String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); - assertThat(petTypeName).isEqualTo("Hamster"); - } + @Test + void testPrint() { + PetType petType = new PetType(); + petType.setName("Hamster"); + String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); + assertThat(petTypeName).isEqualTo("Hamster"); + } - @Test - void shouldParse() throws ParseException { - given(this.pets.findPetTypes()).willReturn(makePetTypes()); - PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); - assertThat(petType.getName()).isEqualTo("Bird"); - } + @Test + void shouldParse() throws ParseException { + given(this.pets.findPetTypes()).willReturn(makePetTypes()); + PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); + assertThat(petType.getName()).isEqualTo("Bird"); + } - @Test - void shouldThrowParseException() throws ParseException { - given(this.pets.findPetTypes()).willReturn(makePetTypes()); - Assertions.assertThrows(ParseException.class, () -> { - petTypeFormatter.parse("Fish", Locale.ENGLISH); - }); - } + @Test + void shouldThrowParseException() throws ParseException { + given(this.pets.findPetTypes()).willReturn(makePetTypes()); + Assertions.assertThrows(ParseException.class, () -> { + petTypeFormatter.parse("Fish", Locale.ENGLISH); + }); + } - /** - * Helper method to produce some sample pet types just for test purpose - * - * @return {@link Collection} of {@link PetType} - */ - private List makePetTypes() { - List petTypes = new ArrayList<>(); - petTypes.add(new PetType() { - { - setName("Dog"); - } - }); - petTypes.add(new PetType() { - { - setName("Bird"); - } - }); - return petTypes; - } + /** + * Helper method to produce some sample pet types just for test purpose + * @return {@link Collection} of {@link PetType} + */ + private List makePetTypes() { + List petTypes = new ArrayList<>(); + petTypes.add(new PetType() { + { + setName("Dog"); + } + }); + petTypes.add(new PetType() { + { + setName("Bird"); + } + }); + return petTypes; + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index f61d34c9c..84bee72df 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -39,47 +39,40 @@ import org.springframework.test.web.servlet.MockMvc; @WebMvcTest(VisitController.class) class VisitControllerTests { - private static final int TEST_PET_ID = 1; + private static final int TEST_PET_ID = 1; - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private VisitRepository visits; + @MockBean + private VisitRepository visits; - @MockBean - private PetRepository pets; + @MockBean + private PetRepository pets; - @BeforeEach - void init() { - given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); - } + @BeforeEach + void init() { + given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); + } - @Test - void testInitNewVisitForm() throws Exception { - mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); - } + @Test + void testInitNewVisitForm() throws Exception { + mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdateVisitForm")); + } - @Test - void testProcessNewVisitFormSuccess() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) - .param("name", "George") - .param("description", "Visit Description") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessNewVisitFormSuccess() throws Exception { + mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George") + .param("description", "Visit Description")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessNewVisitFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) - .param("name", "George") - ) - .andExpect(model().attributeHasErrors("visit")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); - } + @Test + void testProcessNewVisitFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")) + .andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdateVisitForm")); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index f11f98373..a7f3d9d24 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -40,15 +40,24 @@ import org.springframework.transaction.annotation.Transactional; /** * Integration test of the Service and the Repository layer. *

- * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided by the Spring - * TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up - * time between test execution.
  • Dependency Injection of test fixture instances, meaning that - * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the {@link - * ClinicServiceTests#clinicService clinicService} instance variable, which uses autowiring by - * type.
  • Transaction management, meaning each test method is executed in its own transaction, - * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there - * is no need for a teardown or cleanup script.
  • An {@link org.springframework.context.ApplicationContext - * ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary.
+ * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided + * by the Spring TestContext Framework: + *

+ *
    + *
  • Spring IoC container caching which spares us unnecessary set up + * time between test execution.
  • + *
  • Dependency Injection of test fixture instances, meaning that we + * don't need to perform application context lookups. See the use of + * {@link Autowired @Autowired} on the {@link + * ClinicServiceTests#clinicService clinicService} instance variable, which uses + * autowiring by type. + *
  • Transaction management, meaning each test method is executed in + * its own transaction, which is automatically rolled back by default. Thus, even if tests + * insert or otherwise change database state, there is no need for a teardown or cleanup + * script. + *
  • An {@link org.springframework.context.ApplicationContext ApplicationContext} is + * also inherited and can be used for explicit bean lookup if necessary.
  • + *
* * @author Ken Krebs * @author Rod Johnson @@ -60,159 +69,159 @@ import org.springframework.transaction.annotation.Transactional; @DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) class ClinicServiceTests { - @Autowired - protected OwnerRepository owners; + @Autowired + protected OwnerRepository owners; - @Autowired - protected PetRepository pets; + @Autowired + protected PetRepository pets; - @Autowired - protected VisitRepository visits; + @Autowired + protected VisitRepository visits; - @Autowired - protected VetRepository vets; + @Autowired + protected VetRepository vets; - @Test - void shouldFindOwnersByLastName() { - Collection owners = this.owners.findByLastName("Davis"); - assertThat(owners).hasSize(2); + @Test + void shouldFindOwnersByLastName() { + Collection owners = this.owners.findByLastName("Davis"); + assertThat(owners).hasSize(2); - owners = this.owners.findByLastName("Daviss"); - assertThat(owners).isEmpty(); - } + owners = this.owners.findByLastName("Daviss"); + assertThat(owners).isEmpty(); + } - @Test - void shouldFindSingleOwnerWithPet() { - Owner owner = this.owners.findById(1); - assertThat(owner.getLastName()).startsWith("Franklin"); - assertThat(owner.getPets()).hasSize(1); - assertThat(owner.getPets().get(0).getType()).isNotNull(); - assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); - } + @Test + void shouldFindSingleOwnerWithPet() { + Owner owner = this.owners.findById(1); + assertThat(owner.getLastName()).startsWith("Franklin"); + assertThat(owner.getPets()).hasSize(1); + assertThat(owner.getPets().get(0).getType()).isNotNull(); + assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); + } - @Test - @Transactional - void shouldInsertOwner() { - Collection owners = this.owners.findByLastName("Schultz"); - int found = owners.size(); + @Test + @Transactional + void shouldInsertOwner() { + Collection owners = this.owners.findByLastName("Schultz"); + int found = owners.size(); - Owner owner = new Owner(); - owner.setFirstName("Sam"); - owner.setLastName("Schultz"); - owner.setAddress("4, Evans Street"); - owner.setCity("Wollongong"); - owner.setTelephone("4444444444"); - this.owners.save(owner); - assertThat(owner.getId().longValue()).isNotEqualTo(0); + Owner owner = new Owner(); + owner.setFirstName("Sam"); + owner.setLastName("Schultz"); + owner.setAddress("4, Evans Street"); + owner.setCity("Wollongong"); + owner.setTelephone("4444444444"); + this.owners.save(owner); + assertThat(owner.getId().longValue()).isNotEqualTo(0); - owners = this.owners.findByLastName("Schultz"); - assertThat(owners.size()).isEqualTo(found + 1); - } + owners = this.owners.findByLastName("Schultz"); + assertThat(owners.size()).isEqualTo(found + 1); + } - @Test - @Transactional - void shouldUpdateOwner() { - Owner owner = this.owners.findById(1); - String oldLastName = owner.getLastName(); - String newLastName = oldLastName + "X"; + @Test + @Transactional + void shouldUpdateOwner() { + Owner owner = this.owners.findById(1); + String oldLastName = owner.getLastName(); + String newLastName = oldLastName + "X"; - owner.setLastName(newLastName); - this.owners.save(owner); + owner.setLastName(newLastName); + this.owners.save(owner); - // retrieving new name from database - owner = this.owners.findById(1); - assertThat(owner.getLastName()).isEqualTo(newLastName); - } + // retrieving new name from database + owner = this.owners.findById(1); + assertThat(owner.getLastName()).isEqualTo(newLastName); + } - @Test - void shouldFindPetWithCorrectId() { - Pet pet7 = this.pets.findById(7); - assertThat(pet7.getName()).startsWith("Samantha"); - assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); + @Test + void shouldFindPetWithCorrectId() { + Pet pet7 = this.pets.findById(7); + assertThat(pet7.getName()).startsWith("Samantha"); + assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); - } + } - @Test - void shouldFindAllPetTypes() { - Collection petTypes = this.pets.findPetTypes(); + @Test + void shouldFindAllPetTypes() { + Collection petTypes = this.pets.findPetTypes(); - PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); - assertThat(petType1.getName()).isEqualTo("cat"); - PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4); - assertThat(petType4.getName()).isEqualTo("snake"); - } + PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); + assertThat(petType1.getName()).isEqualTo("cat"); + PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4); + assertThat(petType4.getName()).isEqualTo("snake"); + } - @Test - @Transactional - void shouldInsertPetIntoDatabaseAndGenerateId() { - Owner owner6 = this.owners.findById(6); - int found = owner6.getPets().size(); + @Test + @Transactional + void shouldInsertPetIntoDatabaseAndGenerateId() { + Owner owner6 = this.owners.findById(6); + int found = owner6.getPets().size(); - Pet pet = new Pet(); - pet.setName("bowser"); - Collection types = this.pets.findPetTypes(); - pet.setType(EntityUtils.getById(types, PetType.class, 2)); - pet.setBirthDate(LocalDate.now()); - owner6.addPet(pet); - assertThat(owner6.getPets().size()).isEqualTo(found + 1); + Pet pet = new Pet(); + pet.setName("bowser"); + Collection types = this.pets.findPetTypes(); + pet.setType(EntityUtils.getById(types, PetType.class, 2)); + pet.setBirthDate(LocalDate.now()); + owner6.addPet(pet); + assertThat(owner6.getPets().size()).isEqualTo(found + 1); - this.pets.save(pet); - this.owners.save(owner6); + this.pets.save(pet); + this.owners.save(owner6); - owner6 = this.owners.findById(6); - assertThat(owner6.getPets().size()).isEqualTo(found + 1); - // checks that id has been generated - assertThat(pet.getId()).isNotNull(); - } + owner6 = this.owners.findById(6); + assertThat(owner6.getPets().size()).isEqualTo(found + 1); + // checks that id has been generated + assertThat(pet.getId()).isNotNull(); + } - @Test - @Transactional - void shouldUpdatePetName() throws Exception { - Pet pet7 = this.pets.findById(7); - String oldName = pet7.getName(); + @Test + @Transactional + void shouldUpdatePetName() throws Exception { + Pet pet7 = this.pets.findById(7); + String oldName = pet7.getName(); - String newName = oldName + "X"; - pet7.setName(newName); - this.pets.save(pet7); + String newName = oldName + "X"; + pet7.setName(newName); + this.pets.save(pet7); - pet7 = this.pets.findById(7); - assertThat(pet7.getName()).isEqualTo(newName); - } + pet7 = this.pets.findById(7); + assertThat(pet7.getName()).isEqualTo(newName); + } - @Test - void shouldFindVets() { - Collection vets = this.vets.findAll(); + @Test + void shouldFindVets() { + Collection vets = this.vets.findAll(); - Vet vet = EntityUtils.getById(vets, Vet.class, 3); - assertThat(vet.getLastName()).isEqualTo("Douglas"); - assertThat(vet.getNrOfSpecialties()).isEqualTo(2); - assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry"); - assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery"); - } + Vet vet = EntityUtils.getById(vets, Vet.class, 3); + assertThat(vet.getLastName()).isEqualTo("Douglas"); + assertThat(vet.getNrOfSpecialties()).isEqualTo(2); + assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry"); + assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery"); + } - @Test - @Transactional - void shouldAddNewVisitForPet() { - Pet pet7 = this.pets.findById(7); - int found = pet7.getVisits().size(); - Visit visit = new Visit(); - pet7.addVisit(visit); - visit.setDescription("test"); - this.visits.save(visit); - this.pets.save(pet7); + @Test + @Transactional + void shouldAddNewVisitForPet() { + Pet pet7 = this.pets.findById(7); + int found = pet7.getVisits().size(); + Visit visit = new Visit(); + pet7.addVisit(visit); + visit.setDescription("test"); + this.visits.save(visit); + this.pets.save(pet7); - pet7 = this.pets.findById(7); - assertThat(pet7.getVisits().size()).isEqualTo(found + 1); - assertThat(visit.getId()).isNotNull(); - } + pet7 = this.pets.findById(7); + assertThat(pet7.getVisits().size()).isEqualTo(found + 1); + assertThat(visit.getId()).isNotNull(); + } - @Test - void shouldFindVisitsByPetId() throws Exception { - Collection visits = this.visits.findByPetId(7); - assertThat(visits).hasSize(2); - Visit[] visitArr = visits.toArray(new Visit[visits.size()]); - assertThat(visitArr[0].getDate()).isNotNull(); - assertThat(visitArr[0].getPetId()).isEqualTo(7); - } + @Test + void shouldFindVisitsByPetId() throws Exception { + Collection visits = this.visits.findByPetId(7); + assertThat(visits).hasSize(2); + Visit[] visitArr = visits.toArray(new Visit[visits.size()]); + assertThat(visitArr[0].getDate()).isNotNull(); + assertThat(visitArr[0].getPetId()).isEqualTo(7); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java index 8890cc59a..ca8bc41fc 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java +++ b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java @@ -22,8 +22,8 @@ import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.samples.petclinic.model.BaseEntity; /** - * Utility methods for handling entities. Separate from the BaseEntity class mainly because of dependency on the - * ORM-associated ObjectRetrievalFailureException. + * Utility methods for handling entities. Separate from the BaseEntity class mainly + * because of dependency on the ORM-associated ObjectRetrievalFailureException. * * @author Juergen Hoeller * @author Sam Brannen @@ -32,23 +32,22 @@ import org.springframework.samples.petclinic.model.BaseEntity; */ public abstract class EntityUtils { - /** - * Look up the entity of the given class with the given id in the given collection. - * - * @param entities the collection to search - * @param entityClass the entity class to look up - * @param entityId the entity id to look up - * @return the found entity - * @throws ObjectRetrievalFailureException if the entity was not found - */ - public static T getById(Collection entities, Class entityClass, int entityId) - throws ObjectRetrievalFailureException { - for (T entity : entities) { - if (entity.getId() == entityId && entityClass.isInstance(entity)) { - return entity; - } - } - throw new ObjectRetrievalFailureException(entityClass, entityId); - } + /** + * Look up the entity of the given class with the given id in the given collection. + * @param entities the collection to search + * @param entityClass the entity class to look up + * @param entityId the entity id to look up + * @return the found entity + * @throws ObjectRetrievalFailureException if the entity was not found + */ + public static T getById(Collection entities, Class entityClass, int entityId) + throws ObjectRetrievalFailureException { + for (T entity : entities) { + if (entity.getId() == entityId && entityClass.isInstance(entity)) { + return entity; + } + } + throw new ObjectRetrievalFailureException(entityClass, entityId); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java index f15689ce2..6bafc7499 100644 --- a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java @@ -38,13 +38,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @WebMvcTest(controllers = CrashController.class) class CrashControllerTests { - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; + + @Test + void testTriggerException() throws Exception { + mockMvc.perform(get("/oups")).andExpect(view().name("exception")) + .andExpect(model().attributeExists("exception")).andExpect(forwardedUrl("exception")) + .andExpect(status().isOk()); + } - @Test - void testTriggerException() throws Exception { - mockMvc.perform(get("/oups")).andExpect(view().name("exception")) - .andExpect(model().attributeExists("exception")) - .andExpect(forwardedUrl("exception")).andExpect(status().isOk()); - } } diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index 5b6d387e7..fd537bee2 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -40,43 +40,41 @@ import org.springframework.test.web.servlet.ResultActions; @WebMvcTest(VetController.class) class VetControllerTests { - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private VetRepository vets; + @MockBean + private VetRepository vets; - @BeforeEach - void setup() { - Vet james = new Vet(); - james.setFirstName("James"); - james.setLastName("Carter"); - james.setId(1); - Vet helen = new Vet(); - helen.setFirstName("Helen"); - helen.setLastName("Leary"); - helen.setId(2); - Specialty radiology = new Specialty(); - radiology.setId(1); - radiology.setName("radiology"); - helen.addSpecialty(radiology); - given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen)); - } + @BeforeEach + void setup() { + Vet james = new Vet(); + james.setFirstName("James"); + james.setLastName("Carter"); + james.setId(1); + Vet helen = new Vet(); + helen.setFirstName("Helen"); + helen.setLastName("Leary"); + helen.setId(2); + Specialty radiology = new Specialty(); + radiology.setId(1); + radiology.setName("radiology"); + helen.addSpecialty(radiology); + given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen)); + } - @Test - void testShowVetListHtml() throws Exception { - mockMvc.perform(get("/vets.html")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("vets")) - .andExpect(view().name("vets/vetList")); - } + @Test + void testShowVetListHtml() throws Exception { + mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets")) + .andExpect(view().name("vets/vetList")); + } - @Test - void testShowResourcesVetList() throws Exception { - ResultActions actions = mockMvc.perform(get("/vets") - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); - actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.vetList[0].id").value(1)); - } + @Test + void testShowResourcesVetList() throws Exception { + ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.vetList[0].id").value(1)); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java index 82163eb14..d8df78b85 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java @@ -25,17 +25,16 @@ import static org.assertj.core.api.Assertions.assertThat; */ class VetTests { - @Test - void testSerialization() { - Vet vet = new Vet(); - vet.setFirstName("Zaphod"); - vet.setLastName("Beeblebrox"); - vet.setId(123); - Vet other = (Vet) SerializationUtils - .deserialize(SerializationUtils.serialize(vet)); - assertThat(other.getFirstName()).isEqualTo(vet.getFirstName()); - assertThat(other.getLastName()).isEqualTo(vet.getLastName()); - assertThat(other.getId()).isEqualTo(vet.getId()); - } + @Test + void testSerialization() { + Vet vet = new Vet(); + vet.setFirstName("Zaphod"); + vet.setLastName("Beeblebrox"); + vet.setId(123); + Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet)); + assertThat(other.getFirstName()).isEqualTo(vet.getFirstName()); + assertThat(other.getLastName()).isEqualTo(vet.getLastName()); + assertThat(other.getId()).isEqualTo(vet.getId()); + } } From 108a81b946fc12c22dcaf10d7b500daf6969a1be Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 25 Jan 2020 20:30:18 +0100 Subject: [PATCH 097/131] Upgrade to Spring Boot 2.2.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7cb6a8faf..ba704794a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.2.RELEASE + 2.2.4.RELEASE petclinic From 93873665453584deb891569c02e3acc7283cf394 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 25 Jan 2020 20:31:07 +0100 Subject: [PATCH 098/131] Upgrade to spring javaformat 0.0.19 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba704794a..de722ff91 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 1.8.0 0.8.5 - 0.0.17 + 0.0.19 From 5742ecd6ce5bd1fd88e04699e8e16c59cf1efd92 Mon Sep 17 00:00:00 2001 From: vbadipat <42500186+vbadipat@users.noreply.github.com> Date: Fri, 31 Jan 2020 06:30:24 -0500 Subject: [PATCH 099/131] Use https for Maven XSD See gh-522 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de722ff91..f79e7c012 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.springframework.samples spring-petclinic From 400e3028f48a6c23f5156f6598dd10cb5e6a2849 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 31 Jan 2020 16:53:53 +0100 Subject: [PATCH 100/131] Polish "Use https for Maven XSD" See gh-522 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f79e7c012..cf9a9493e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.samples spring-petclinic From 1cc942a4ad75ad844202f6f18e352b4a624e8879 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 31 Jan 2020 17:31:19 +0100 Subject: [PATCH 101/131] Add nohttp check --- .mvn/wrapper/MavenWrapperDownloader.java | 2 +- mvnw | 2 +- mvnw.cmd | 2 +- pom.xml | 36 ++++++++++++++++++- .../nohttp-checkstyle-suppressions.xml | 8 +++++ src/checkstyle/nohttp-checkstyle.xml | 7 ++++ 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 src/checkstyle/nohttp-checkstyle-suppressions.xml create mode 100644 src/checkstyle/nohttp-checkstyle.xml diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index c32394f14..c01806e55 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/mvnw b/mvnw index d2f0ea380..05f3faa58 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "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 +# https://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 diff --git a/mvnw.cmd b/mvnw.cmd index b26ab24f0..ddd991886 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0' @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an diff --git a/pom.xml b/pom.xml index cf9a9493e..ebaf8c43c 100644 --- a/pom.xml +++ b/pom.xml @@ -28,8 +28,8 @@ 1.8.0 0.8.5 + 0.0.4.RELEASE 0.0.19 - @@ -145,6 +145,40 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.0 + + + com.puppycrawl.tools + checkstyle + 8.25 + + + io.spring.nohttp + nohttp-checkstyle + ${nohttp-checkstyle.version} + + + + + nohttp-checkstyle-validation + validate + + src/checkstyle/nohttp-checkstyle.xml + src/checkstyle/nohttp-checkstyle-suppressions.xml + UTF-8 + ${basedir} + **/* + **/.git/**/*,**/.idea/**/*,**/target/**/,**/.flattened-pom.xml,**/*.class + + + check + + + + org.springframework.boot spring-boot-maven-plugin diff --git a/src/checkstyle/nohttp-checkstyle-suppressions.xml b/src/checkstyle/nohttp-checkstyle-suppressions.xml new file mode 100644 index 000000000..1b40e8b3f --- /dev/null +++ b/src/checkstyle/nohttp-checkstyle-suppressions.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/checkstyle/nohttp-checkstyle.xml b/src/checkstyle/nohttp-checkstyle.xml new file mode 100644 index 000000000..e6205127b --- /dev/null +++ b/src/checkstyle/nohttp-checkstyle.xml @@ -0,0 +1,7 @@ + + + + + From ac3e64208e3bcf85eaeff2f870083212f526676f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 3 Feb 2020 09:20:37 +0000 Subject: [PATCH 102/131] Update checkstyle plugin for security scan warning --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ebaf8c43c..799b66e98 100644 --- a/pom.xml +++ b/pom.xml @@ -153,7 +153,7 @@ com.puppycrawl.tools checkstyle - 8.25 + 8.29 io.spring.nohttp From 5c35771a20ec29fd49a6cb54512159d3d7c0aa94 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Mar 2020 08:29:36 +0000 Subject: [PATCH 103/131] Wrong name for user.sql script --- src/main/resources/db/mysql/petclinic_db_setup_mysql.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index f6ce6523c..29bb601fe 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -27,5 +27,6 @@ line, but any way that sets that property in a Spring Boot app should work). N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value -as it is configured by default. This condition is taken care of by the docker-compose -configuration provided, or by the `schema.sql` if you can run that as root. +as it is configured by default. This condition is taken care of automatically by the +docker-compose configuration provided, or by the `user.sql` script if you run that as +root. From e0eec8e3a6075634e4e95f7cc44cf9d73b3dc5e6 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:17:34 +0100 Subject: [PATCH 104/131] Add m2e profile for well-known plugins See gh-519 --- pom.xml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pom.xml b/pom.xml index 799b66e98..28c86da1d 100644 --- a/pom.xml +++ b/pom.xml @@ -323,4 +323,60 @@ + + + m2e + + + m2e.version + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + [1,) + + check + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + [1,) + + build-info + + + + + + + + + + + + + + + + From a79cb9a008022de37ad93a03f89157d32b432c9c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:17:58 +0100 Subject: [PATCH 105/131] Upgrade to Spring Boot 2.2.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 28c86da1d..0ed90e06b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.4.RELEASE + 2.2.5.RELEASE petclinic From e62458833c10be5c91e5f8923af56bed93851c04 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:18:28 +0100 Subject: [PATCH 106/131] Upgrade to spring javaformat 0.0.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ed90e06b..978803473 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.19 + 0.0.20 From c0847b7571e58a18333addaa691691edebb7491c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:24:24 +0100 Subject: [PATCH 107/131] Add support for H2 Closes gh-584 --- pom.xml | 6 +-- readme.md | 7 ++- src/main/resources/application.properties | 2 +- src/main/resources/db/h2/data.sql | 53 +++++++++++++++++++ src/main/resources/db/h2/schema.sql | 64 +++++++++++++++++++++++ 5 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 src/main/resources/db/h2/data.sql create mode 100644 src/main/resources/db/h2/schema.sql diff --git a/pom.xml b/pom.xml index 978803473..becd05b79 100644 --- a/pom.xml +++ b/pom.xml @@ -66,10 +66,10 @@ - + - org.hsqldb - hsqldb + com.h2database + h2 runtime diff --git a/readme.md b/readme.md index 77de7dc77..286e525d1 100644 --- a/readme.md +++ b/readme.md @@ -35,8 +35,11 @@ Our issue tracker is available here: https://github.com/spring-projects/spring-p ## Database configuration -In its default configuration, Petclinic uses an in-memory database (HSQLDB) which -gets populated at startup with data. A similar setup is provided for MySql in case a persistent database configuration is needed. +In its default configuration, Petclinic uses an in-memory database (H2) which +gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` +and it is possibl to inspect the content of the database using the `jdbc:h2:mem:testdb` url. + +A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. You could start MySql locally with whatever installer works for your OS, or with docker: diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b93ff4de3..c87dbf7a9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ # database init, supports mysql too -database=hsqldb +database=h2 spring.datasource.schema=classpath*:db/${database}/schema.sql spring.datasource.data=classpath*:db/${database}/data.sql diff --git a/src/main/resources/db/h2/data.sql b/src/main/resources/db/h2/data.sql new file mode 100644 index 000000000..16dda3e84 --- /dev/null +++ b/src/main/resources/db/h2/data.sql @@ -0,0 +1,53 @@ +INSERT INTO vets VALUES (1, 'James', 'Carter'); +INSERT INTO vets VALUES (2, 'Helen', 'Leary'); +INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); +INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); +INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); +INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); + +INSERT INTO specialties VALUES (1, 'radiology'); +INSERT INTO specialties VALUES (2, 'surgery'); +INSERT INTO specialties VALUES (3, 'dentistry'); + +INSERT INTO vet_specialties VALUES (2, 1); +INSERT INTO vet_specialties VALUES (3, 2); +INSERT INTO vet_specialties VALUES (3, 3); +INSERT INTO vet_specialties VALUES (4, 2); +INSERT INTO vet_specialties VALUES (5, 1); + +INSERT INTO types VALUES (1, 'cat'); +INSERT INTO types VALUES (2, 'dog'); +INSERT INTO types VALUES (3, 'lizard'); +INSERT INTO types VALUES (4, 'snake'); +INSERT INTO types VALUES (5, 'bird'); +INSERT INTO types VALUES (6, 'hamster'); + +INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); + +INSERT INTO pets VALUES (1, 'Leo', '2010-09-07', 1, 1); +INSERT INTO pets VALUES (2, 'Basil', '2012-08-06', 6, 2); +INSERT INTO pets VALUES (3, 'Rosy', '2011-04-17', 2, 3); +INSERT INTO pets VALUES (4, 'Jewel', '2010-03-07', 2, 3); +INSERT INTO pets VALUES (5, 'Iggy', '2010-11-30', 3, 4); +INSERT INTO pets VALUES (6, 'George', '2010-01-20', 4, 5); +INSERT INTO pets VALUES (7, 'Samantha', '2012-09-04', 1, 6); +INSERT INTO pets VALUES (8, 'Max', '2012-09-04', 1, 6); +INSERT INTO pets VALUES (9, 'Lucky', '2011-08-06', 5, 7); +INSERT INTO pets VALUES (10, 'Mulligan', '2007-02-24', 2, 8); +INSERT INTO pets VALUES (11, 'Freddy', '2010-03-09', 5, 9); +INSERT INTO pets VALUES (12, 'Lucky', '2010-06-24', 2, 10); +INSERT INTO pets VALUES (13, 'Sly', '2012-06-08', 1, 10); + +INSERT INTO visits VALUES (1, 7, '2013-01-01', 'rabies shot'); +INSERT INTO visits VALUES (2, 8, '2013-01-02', 'rabies shot'); +INSERT INTO visits VALUES (3, 8, '2013-01-03', 'neutered'); +INSERT INTO visits VALUES (4, 7, '2013-01-04', 'spayed'); diff --git a/src/main/resources/db/h2/schema.sql b/src/main/resources/db/h2/schema.sql new file mode 100644 index 000000000..f3c6947b7 --- /dev/null +++ b/src/main/resources/db/h2/schema.sql @@ -0,0 +1,64 @@ +DROP TABLE vet_specialties IF EXISTS; +DROP TABLE vets IF EXISTS; +DROP TABLE specialties IF EXISTS; +DROP TABLE visits IF EXISTS; +DROP TABLE pets IF EXISTS; +DROP TABLE types IF EXISTS; +DROP TABLE owners IF EXISTS; + + +CREATE TABLE vets ( + id INTEGER IDENTITY PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30) +); +CREATE INDEX vets_last_name ON vets (last_name); + +CREATE TABLE specialties ( + id INTEGER IDENTITY PRIMARY KEY, + name VARCHAR(80) +); +CREATE INDEX specialties_name ON specialties (name); + +CREATE TABLE vet_specialties ( + vet_id INTEGER NOT NULL, + specialty_id INTEGER NOT NULL +); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id); + +CREATE TABLE types ( + id INTEGER IDENTITY PRIMARY KEY, + name VARCHAR(80) +); +CREATE INDEX types_name ON types (name); + +CREATE TABLE owners ( + id INTEGER IDENTITY PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR_IGNORECASE(30), + address VARCHAR(255), + city VARCHAR(80), + telephone VARCHAR(20) +); +CREATE INDEX owners_last_name ON owners (last_name); + +CREATE TABLE pets ( + id INTEGER IDENTITY PRIMARY KEY, + name VARCHAR(30), + birth_date DATE, + type_id INTEGER NOT NULL, + owner_id INTEGER NOT NULL +); +ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id); +ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id); +CREATE INDEX pets_name ON pets (name); + +CREATE TABLE visits ( + id INTEGER IDENTITY PRIMARY KEY, + pet_id INTEGER NOT NULL, + visit_date DATE, + description VARCHAR(255) +); +ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id); +CREATE INDEX visits_pet_id ON visits (pet_id); From 8805eaa721a6ce59cbd7870653dc28afda806c0a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:26:24 +0100 Subject: [PATCH 108/131] Disable open-in-view explicitly to remove warning on startup --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c87dbf7a9..4f2c86834 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,7 @@ spring.thymeleaf.mode=HTML # JPA spring.jpa.hibernate.ddl-auto=none +spring.jpa.open-in-view=false # Internationalization spring.messages.basename=messages/messages From 8db8c272c102127664d8896ebe63d9d2af76359e Mon Sep 17 00:00:00 2001 From: James Artz Date: Sun, 29 Mar 2020 16:12:22 -0500 Subject: [PATCH 109/131] Fix typo in readme See gh-586 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 286e525d1..716676ed3 100644 --- a/readme.md +++ b/readme.md @@ -37,7 +37,7 @@ Our issue tracker is available here: https://github.com/spring-projects/spring-p In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` -and it is possibl to inspect the content of the database using the `jdbc:h2:mem:testdb` url. +and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url. A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. From d9f37ece5c865ded91b6582828142ccc33e9d54f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 2 May 2020 07:51:21 +0200 Subject: [PATCH 110/131] Upgrade to Spring Boot 2.3.0.RC1 --- pom.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index becd05b79..2c4ddf801 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.2.5.RELEASE + 2.3.0.RC1 petclinic @@ -50,6 +50,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot spring-boot-starter-thymeleaf From 628862206bd20efcce9ae5f97b89aad59bb2c9ca Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 2 May 2020 08:02:49 +0200 Subject: [PATCH 111/131] Switch actuator to standard path --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4f2c86834..4d4784e36 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,8 +13,7 @@ spring.jpa.open-in-view=false # Internationalization spring.messages.basename=messages/messages -# Actuator / Management -management.endpoints.web.base-path=/manage +# Actuator management.endpoints.web.exposure.include=* # Logging From 6a18eecc9b74f67dbcc8a7b7e11044db2f6907d7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 3 May 2020 08:55:22 +0200 Subject: [PATCH 112/131] Upgrade to spring javaformat 0.0.21 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2c4ddf801..41689d542 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.20 + 0.0.21 From adab01ef624418db4a9677c5c641a039d39b7a18 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 3 May 2020 08:55:49 +0200 Subject: [PATCH 113/131] Upgrade to maven checkstyle plugin 3.1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 41689d542..2baea5a12 100644 --- a/pom.xml +++ b/pom.xml @@ -152,7 +152,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.0 + 3.1.1 com.puppycrawl.tools From c9230c37b9e6aac71d0724eccf3236dde034ce27 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 27 May 2020 13:40:44 +0000 Subject: [PATCH 114/131] Bump to Spring Boot 2.3.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2baea5a12..ef1417bf6 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.0.RC1 + 2.3.0.RELEASE petclinic From 907eea340b7d51faf8f668cd15a1ae3b001fb7ef Mon Sep 17 00:00:00 2001 From: Kristof Neirynck Date: Sat, 16 May 2020 16:32:48 +0200 Subject: [PATCH 115/131] Upgrade to Maven 3.6.3 and Maven Wrapper 0.5.6 --- .mvn/wrapper/MavenWrapperDownloader.java | 2 +- .mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 50710 bytes .mvn/wrapper/maven-wrapper.properties | 5 +++-- mvnw | 8 ++++---- mvnw.cmd | 8 ++++---- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index c01806e55..89964d141 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -20,7 +20,7 @@ import java.util.Properties; public class MavenWrapperDownloader { - private static final String WRAPPER_VERSION = "0.5.5"; + private static final String WRAPPER_VERSION = "0.5.6"; /** * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. */ diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 0d5e649888a4843c1520054d9672f80c62ebbb48..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 100644 GIT binary patch delta 3148 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 delta 3147 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 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 7d59a01f2..2743cab67 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,3 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar + diff --git a/mvnw b/mvnw index 05f3faa58..2c90d17e4 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Maven Start Up Batch script # # Required ENV vars: # ------------------ @@ -212,9 +212,9 @@ else echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; @@ -246,7 +246,7 @@ else else curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f fi - + else if [ "$MVNW_VERBOSE" = true ]; then echo "Falling back to using Java to download" diff --git a/mvnw.cmd b/mvnw.cmd index ddd991886..0d34af450 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,7 +18,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script +@REM Maven Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @@ -26,7 +26,7 @@ @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -120,7 +120,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B @@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... From d94b995db23e9251a865b85bcb2d8ed99f45d8bb Mon Sep 17 00:00:00 2001 From: Kristof Neirynck Date: Thu, 21 May 2020 14:51:47 +0200 Subject: [PATCH 116/131] Change EditorConfig to be consistent with spring-javaformat spring-javaformat uses tabs to indent java files --- .editorconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.editorconfig b/.editorconfig index 8d67bc7a5..44e7e6703 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,5 @@ indent_style = space [*.{java,xml}] indent_size = 4 trim_trailing_whitespace = true +indent_style = tab +tab_width = 4 From 9873188e291a2f81f7d5f27dea09ba5e66fede14 Mon Sep 17 00:00:00 2001 From: Kristof Neirynck Date: Sat, 23 May 2020 12:38:08 +0200 Subject: [PATCH 117/131] Change EditorConfig to reflect some files are indented with 2 spaces --- .editorconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.editorconfig b/.editorconfig index 44e7e6703..2513d2a34 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,3 +12,10 @@ indent_size = 4 trim_trailing_whitespace = true indent_style = tab tab_width = 4 + +[{pom,wro}.xml] +indent_size = 2 +indent_style = space + +[*.{html,sql,less}] +indent_size = 2 From 410abc21f3cb89977e16cb8c1c3947b31dcff7af Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 19 Apr 2020 21:56:57 +0900 Subject: [PATCH 118/131] remove trailing slash --- .../resources/templates/owners/ownerDetails.html | 12 ++++++------ .../templates/pets/createOrUpdateVisitForm.html | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/resources/templates/owners/ownerDetails.html b/src/main/resources/templates/owners/ownerDetails.html index fa2b71ee9..383fa929f 100644 --- a/src/main/resources/templates/owners/ownerDetails.html +++ b/src/main/resources/templates/owners/ownerDetails.html @@ -16,15 +16,15 @@
- + - + - +
Name
Address
City
Telephone
@@ -44,12 +44,12 @@
Name
-
+
Birth Date
+ th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}">
Type
-
+
diff --git a/src/main/resources/templates/pets/createOrUpdateVisitForm.html b/src/main/resources/templates/pets/createOrUpdateVisitForm.html index d7589c3bc..ddcbb9d59 100644 --- a/src/main/resources/templates/pets/createOrUpdateVisitForm.html +++ b/src/main/resources/templates/pets/createOrUpdateVisitForm.html @@ -19,12 +19,12 @@ - + - + th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}"> + + th:text="${pet.owner?.firstName + ' ' + pet.owner?.lastName}"> @@ -52,8 +52,8 @@ Description - - + + From d17355505678e29d397c82f7b6d4405f01abef39 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 13 Jun 2020 14:09:36 +0100 Subject: [PATCH 119/131] Update to Boot 2.3.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ef1417bf6..510c933f3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.3.0.BUILD-SNAPSHOT + 2.3.1.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.3.0.RELEASE + 2.3.1.RELEASE petclinic From 07b9d5aa45a51ce6d2372c46880cad2192da9d07 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 13 Jun 2020 14:56:10 +0100 Subject: [PATCH 120/131] Ensure fragment for menu items is not itself rendered Formerly there was a "ghost" menu item with no text and no icon because Thymeleaf had not been instructed to remove the fragment definition. This change tidies that up and also removes the use of the "path" variable, which Thymeleaf populates from the current request context, and poses a potential security threat as a result (if users type malicious characters in the URL). --- .../resources/templates/fragments/layout.html | 136 ++++++++++-------- 1 file changed, 73 insertions(+), 63 deletions(-) diff --git a/src/main/resources/templates/fragments/layout.html b/src/main/resources/templates/fragments/layout.html index 7cb5f4697..f3b207483 100755 --- a/src/main/resources/templates/fragments/layout.html +++ b/src/main/resources/templates/fragments/layout.html @@ -1,88 +1,98 @@ - + - - - - + + + + - + - PetClinic :: a Spring Framework demonstration + PetClinic :: a Spring Framework demonstration - - + - +
-
- - +
-
-
-
-
-
- Sponsored by Pivotal
-
+ + +
+
+
+
+
+ Sponsored by Pivotal
+
From 73ede82651bf1e733b26e6c630f2aac9c855e900 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 13 Jun 2020 15:16:31 +0100 Subject: [PATCH 121/131] Replace references to main branch --- readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 716676ed3..eb8aa7d7e 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=master)](https://travis-ci.org/spring-projects/spring-petclinic/) +# Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=main)](https://travis-ci.org/spring-projects/spring-petclinic/) Deploy this sample application to Pivotal Web Services: @@ -48,7 +48,7 @@ You could start MySql locally with whatever installer works for your OS, or with docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 ``` -Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). +Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). ## Working with Petclinic in your IDE @@ -96,13 +96,13 @@ Visit [http://localhost:8080](http://localhost:8080) in your browser. |Spring Boot Configuration | Class or Java property files | |--------------------------|---| -|The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) | -|Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources) | -|Caching | [CacheConfiguration](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) | +|The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) | +|Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources) | +|Caching | [CacheConfiguration](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) | ## Interesting Spring Petclinic branches and forks -The Spring Petclinic master branch in the main [spring-projects](https://github.com/spring-projects/spring-petclinic) +The Spring Petclinic "main" branch in the [spring-projects](https://github.com/spring-projects/spring-petclinic) GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are [quite a few forks](https://spring-petclinic.github.io/docs/forks.html) in a special GitHub org [spring-petclinic](https://github.com/spring-petclinic). If you have a special interest in a different technology stack From d367e2b4b41a2de899b0f438bc984a7c1c011b77 Mon Sep 17 00:00:00 2001 From: Alex Hatzenbuhler Date: Mon, 30 Mar 2020 09:11:48 -0500 Subject: [PATCH 122/131] Updating spacing on step list --- readme.md | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/readme.md b/readme.md index eb8aa7d7e..8460e2de6 100644 --- a/readme.md +++ b/readme.md @@ -39,8 +39,7 @@ In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url. -A similar setup is provided for MySql in case a persistent database configuration is needed. -Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. +A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. You could start MySql locally with whatever installer works for your OS, or with docker: @@ -66,30 +65,26 @@ The following items should be installed in your system: ### Steps: 1) On the command line -``` -git clone https://github.com/spring-projects/spring-petclinic.git -``` + ``` + git clone https://github.com/spring-projects/spring-petclinic.git + ``` 2) Inside Eclipse or STS -``` -File -> Import -> Maven -> Existing Maven project -``` + ``` + File -> Import -> Maven -> Existing Maven project + ``` -Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. + Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. 3) Inside IntelliJ IDEA + In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button. -In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button. + CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`. -CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` -or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`. - -A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate -version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing -`Run 'PetClinicApplication'`. + A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`. 4) Navigate to Petclinic -Visit [http://localhost:8080](http://localhost:8080) in your browser. + Visit [http://localhost:8080](http://localhost:8080) in your browser. ## Looking for something in particular? From 0390e85c252a58917954ec682775c6672159b58c Mon Sep 17 00:00:00 2001 From: aleVeD Date: Mon, 1 Jun 2020 16:45:57 -0400 Subject: [PATCH 123/131] adding new message in Spanish --- src/main/resources/messages/messages_es.properties | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/resources/messages/messages_es.properties diff --git a/src/main/resources/messages/messages_es.properties b/src/main/resources/messages/messages_es.properties new file mode 100644 index 000000000..33ee867b5 --- /dev/null +++ b/src/main/resources/messages/messages_es.properties @@ -0,0 +1,8 @@ +welcome=Bienvenido +required=Es requerido +notFound=No ha sido encontrado +duplicate=Ya se encuentra en uso +nonNumeric=Sólo debe contener numeros +duplicateFormSubmission=No se permite el envío de formularios duplicados +typeMismatch.date=Fecha invalida +typeMismatch.birthDate=Fecha invalida From 4953f87917b449a404a7f1f4e2457836b9eafbbc Mon Sep 17 00:00:00 2001 From: Rognetta <38105584+Rognetta@users.noreply.github.com> Date: Thu, 21 Nov 2019 16:39:14 +0100 Subject: [PATCH 124/131] Update application-mysql.properties Add some environment variables with defaults for the MySQL credentials. Closes #506 --- src/main/resources/application-mysql.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index 6d54ddad7..d388c9e6d 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -1,7 +1,7 @@ # database init, supports mysql too database=mysql -spring.datasource.url=jdbc:mysql://localhost/petclinic -spring.datasource.username=petclinic -spring.datasource.password=petclinic +spring.datasource.url=${MYSQL_URL:jdbc:mysql://localhost/petclinic} +spring.datasource.username=${MYSQL_USER:petclinic} +spring.datasource.password=${MYSQL_PASS:petclinic} # SQL is written to be idempotent so this is safe spring.datasource.initialization-mode=always From 5ad6bc3ccde1c61379d751f0751a1731114761af Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 11 Jul 2020 08:56:32 +0200 Subject: [PATCH 125/131] Upgrade to spring javaformat 0.0.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 510c933f3..2c92f7746 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.21 + 0.0.22 From 02cc84223b296e7b401cdba74905b2e18a87e51e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 11 Jul 2020 08:57:33 +0200 Subject: [PATCH 126/131] Polish --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2c92f7746..5ac0cc4c6 100644 --- a/pom.xml +++ b/pom.xml @@ -139,7 +139,6 @@ io.spring.javaformat spring-javaformat-maven-plugin ${spring-format.version} - validate @@ -281,7 +280,6 @@ - Apache License, Version 2.0 From c42f95980a943634106e7584575c053265906978 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Wed, 29 Jul 2020 16:43:31 +0200 Subject: [PATCH 127/131] remove push-to-pws button from guide, since pws free trials end --- push-to-pws/button.yml | 1 - readme.md | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 push-to-pws/button.yml diff --git a/push-to-pws/button.yml b/push-to-pws/button.yml deleted file mode 100644 index e85329d59..000000000 --- a/push-to-pws/button.yml +++ /dev/null @@ -1 +0,0 @@ -repo: https://github.com/spring-projects/spring-petclinic.git diff --git a/readme.md b/readme.md index 8460e2de6..ff6d2be15 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,4 @@ # Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=main)](https://travis-ci.org/spring-projects/spring-petclinic/) -Deploy this sample application to Pivotal Web Services: - - - Push - ## Understanding the Spring Petclinic application with a few diagrams See the presentation here From d19963e1744f56ff330be879d35672733d66f641 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:03:32 +0200 Subject: [PATCH 128/131] Upgrade to Spring Boot 2.3.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5ac0cc4c6..44c406725 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.1.RELEASE + 2.3.3.RELEASE petclinic From 2e5be53533d3a5cd7950ada623ade5e87d059784 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:03:51 +0200 Subject: [PATCH 129/131] Upgrade to spring javaformat 0.0.25 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44c406725..a30a98e01 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.22 + 0.0.25 From be0f161453c0a986450affb901d0cf4445c0a740 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:04:12 +0200 Subject: [PATCH 130/131] Upgrade to Checkstyle 8.32 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a30a98e01..38232a26c 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ com.puppycrawl.tools checkstyle - 8.29 + 8.32 io.spring.nohttp From 27109010a52600eb9bf227d631fac3f81ed6ba15 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:05:30 +0200 Subject: [PATCH 131/131] Restore version to 2.3.0.BUILD-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 38232a26c..e4e74747a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.3.1.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT org.springframework.boot