mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-19 14:05:50 +00:00
Shadow Read + Refactoring
This commit is contained in:
parent
ed62231e88
commit
ac846db4c3
4 changed files with 200 additions and 17 deletions
|
@ -15,26 +15,48 @@ import org.springframework.samples.petclinic.owner.StaticOwner;
|
||||||
*/
|
*/
|
||||||
public class NewOwnerStore {
|
public class NewOwnerStore {
|
||||||
|
|
||||||
public Map<Integer, StaticOwner> ownerStore;
|
private HashMap<Integer, StaticOwner> ownerStore;
|
||||||
private final OwnerRepository owners;
|
private final OwnerRepository owners;
|
||||||
|
private static NewOwnerStore storeSingleton;
|
||||||
|
|
||||||
public NewOwnerStore(OwnerRepository owners) {
|
private NewOwnerStore(OwnerRepository owners) {
|
||||||
this.owners = owners;
|
this.owners = owners;
|
||||||
this.ownerStore = new HashMap<>();
|
this.ownerStore = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NewOwnerStore getInstance(OwnerRepository owners)
|
||||||
|
{
|
||||||
|
if (storeSingleton == null)
|
||||||
|
storeSingleton = new NewOwnerStore(owners);
|
||||||
|
|
||||||
|
return storeSingleton;
|
||||||
|
}
|
||||||
|
|
||||||
public void populateStore() {
|
public void populateStore() {
|
||||||
Collection<Owner> ownerRepositoryData = this.owners.findAll();
|
Collection<Owner> ownerRepositoryData = this.owners.findAll();
|
||||||
for(Owner owner : ownerRepositoryData) {
|
for(Owner owner : ownerRepositoryData) {
|
||||||
ownerStore.put(owner.getId(), convertToStaticOwner(owner));
|
ownerStore.put(owner.getId(), StaticOwner.convertToStaticOwner(owner));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public StaticOwner convertToStaticOwner(Owner ownerEntity) {
|
public HashMap<Integer, StaticOwner> getStore()
|
||||||
return new StaticOwner(ownerEntity.getAddress(), ownerEntity.getCity(), ownerEntity.getTelephone());
|
{
|
||||||
|
return ownerStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, StaticOwner> getNewOwnerStore() {
|
public void findAndReplace(Owner owner) {
|
||||||
return this.ownerStore;
|
boolean exists = false;
|
||||||
|
|
||||||
|
for (StaticOwner o : getStore().values()) {
|
||||||
|
if (o.getId() == owner.getId()) {
|
||||||
|
exists = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace
|
||||||
|
getStore().put(owner.getId(), StaticOwner.convertToStaticOwner(owner));
|
||||||
|
|
||||||
|
// Report whether inexistent or inconsistent based on exists
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.samples.petclinic.newDataStore.NewOwnerStore;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
|
@ -27,8 +28,11 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
@ -38,7 +42,6 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
class OwnerController {
|
class OwnerController {
|
||||||
|
|
||||||
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
|
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
|
||||||
private final OwnerRepository owners;
|
private final OwnerRepository owners;
|
||||||
|
|
||||||
|
@ -86,6 +89,14 @@ class OwnerController {
|
||||||
|
|
||||||
// find owners by last name
|
// find owners by last name
|
||||||
Collection<Owner> results = this.owners.findByLastName(owner.getLastName());
|
Collection<Owner> results = this.owners.findByLastName(owner.getLastName());
|
||||||
|
|
||||||
|
for (Owner o : results)
|
||||||
|
System.out.println(o.toString());
|
||||||
|
|
||||||
|
// Shadow Read
|
||||||
|
compareResults(results, owner.getLastName());
|
||||||
|
|
||||||
|
|
||||||
if (results.isEmpty()) {
|
if (results.isEmpty()) {
|
||||||
// no owners found
|
// no owners found
|
||||||
result.rejectValue("lastName", "notFound", "not found");
|
result.rejectValue("lastName", "notFound", "not found");
|
||||||
|
@ -101,6 +112,32 @@ class OwnerController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void compareResults(Collection<Owner> results, String lastName) {
|
||||||
|
|
||||||
|
String pattern = lastName + "*";
|
||||||
|
|
||||||
|
NewOwnerStore newStore = NewOwnerStore.getInstance(owners);
|
||||||
|
newStore.populateStore();
|
||||||
|
|
||||||
|
HashMap<Integer, StaticOwner> storeMap = newStore.getStore();
|
||||||
|
|
||||||
|
ArrayList<StaticOwner> newOwners = new ArrayList<>();
|
||||||
|
|
||||||
|
for (StaticOwner owner : storeMap.values()) {
|
||||||
|
if (!Pattern.compile(pattern).matcher(owner.getLastName()).find())
|
||||||
|
newOwners.add(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Owner owner : results) {
|
||||||
|
if (newOwners.contains(owner))
|
||||||
|
System.out.println("Found. Good");
|
||||||
|
else {
|
||||||
|
System.out.println("Not Found. Bad");
|
||||||
|
newStore.findAndReplace(owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/owners/{ownerId}/edit")
|
@GetMapping("/owners/{ownerId}/edit")
|
||||||
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
|
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
|
||||||
Owner owner = this.owners.findById(ownerId);
|
Owner owner = this.owners.findById(ownerId);
|
||||||
|
@ -131,5 +168,4 @@ class OwnerController {
|
||||||
mav.addObject(this.owners.findById(ownerId));
|
mav.addObject(this.owners.findById(ownerId));
|
||||||
return mav;
|
return mav;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gibran
|
* @author Gibran
|
||||||
*/
|
*/
|
||||||
|
@ -11,13 +13,75 @@ public class StaticOwner {
|
||||||
private String address;
|
private String address;
|
||||||
private String city;
|
private String city;
|
||||||
private String telephone;
|
private String telephone;
|
||||||
|
private Integer id;
|
||||||
|
private String lastName;
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
public StaticOwner(String address, String city, String telephone){
|
public StaticOwner(Integer id, String lastName, String firstName, String address, String city, String telephone)
|
||||||
|
{
|
||||||
|
this.setId(id);
|
||||||
|
this.setLastName(lastName);
|
||||||
|
this.setFirstName(firstName);
|
||||||
|
this.setAddress(address);
|
||||||
|
this.setCity(city);
|
||||||
|
this.setTelephone(telephone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCity(String city) {
|
||||||
this.city = city;
|
this.city = city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTelephone(String telephone) {
|
||||||
this.telephone = telephone;
|
this.telephone = telephone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null) return false;
|
||||||
|
Owner owner = (Owner) o;
|
||||||
|
|
||||||
|
return Objects.equals(address, owner.getAddress()) &&
|
||||||
|
Objects.equals(city, owner.getCity()) &&
|
||||||
|
Objects.equals(telephone, owner.getTelephone()) &&
|
||||||
|
Objects.equals(firstName, owner.getFirstName()) &&
|
||||||
|
Objects.equals(lastName, owner.getLastName()) &&
|
||||||
|
Objects.equals(id, owner.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(address, city, telephone);
|
||||||
|
}
|
||||||
|
|
||||||
public String getAddress () {
|
public String getAddress () {
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
@ -30,4 +94,10 @@ public class StaticOwner {
|
||||||
return telephone;
|
return telephone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static StaticOwner convertToStaticOwner(Owner owner) {
|
||||||
|
return new StaticOwner(owner.getId(), owner.getLastName(), owner.getFirstName(),
|
||||||
|
owner.getAddress(), owner.getCity(), owner.getTelephone());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,20 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.samples.petclinic.newDataStore;
|
package org.springframework.samples.petclinic.newDataStore;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.*;
|
||||||
import java.util.Map;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.samples.petclinic.owner.Owner;
|
||||||
import org.springframework.samples.petclinic.owner.OwnerRepository;
|
import org.springframework.samples.petclinic.owner.OwnerRepository;
|
||||||
import org.springframework.samples.petclinic.owner.StaticOwner;
|
import org.springframework.samples.petclinic.owner.StaticOwner;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gibran
|
* @author Gibran
|
||||||
*/
|
*/
|
||||||
|
@ -21,15 +25,15 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||||
public class NewOwnerStoreTest {
|
public class NewOwnerStoreTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
OwnerRepository owner;
|
OwnerRepository owners;
|
||||||
|
|
||||||
NewOwnerStore testOwnerStore;
|
NewOwnerStore testOwnerStore;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPopulation() {
|
public void testPopulation() {
|
||||||
testOwnerStore = new NewOwnerStore(owner);
|
testOwnerStore = NewOwnerStore.getInstance(owners);
|
||||||
testOwnerStore.populateStore();
|
testOwnerStore.populateStore();
|
||||||
Map<Integer, StaticOwner> ownerStore = testOwnerStore.getNewOwnerStore();
|
Map<Integer, StaticOwner> ownerStore = testOwnerStore.getStore();
|
||||||
|
|
||||||
for (Integer id: ownerStore.keySet()){
|
for (Integer id: ownerStore.keySet()){
|
||||||
|
|
||||||
|
@ -37,8 +41,59 @@ public class NewOwnerStoreTest {
|
||||||
String value = ownerStore.get(id).getAddress();
|
String value = ownerStore.get(id).getAddress();
|
||||||
System.out.println(key + " " + value);
|
System.out.println(key + " " + value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShadowRead() {
|
||||||
|
testOwnerStore = NewOwnerStore.getInstance(owners);
|
||||||
|
testOwnerStore.populateStore();
|
||||||
|
|
||||||
|
Collection<Owner> results = this.owners.findByLastName("");
|
||||||
|
|
||||||
|
int inconsistencies = compareResults(results, "");
|
||||||
|
|
||||||
|
assertEquals(inconsistencies, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int compareResults(Collection<Owner> results, String lastName) {
|
||||||
|
|
||||||
|
String pattern = "/^" + lastName + "/";
|
||||||
|
|
||||||
|
HashMap<Integer, StaticOwner> storeMap = testOwnerStore.getStore();
|
||||||
|
|
||||||
|
ArrayList<StaticOwner> staticOwners = new ArrayList<>();
|
||||||
|
|
||||||
|
for (StaticOwner owner : storeMap.values()) {
|
||||||
|
if (!Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(owner.getLastName()).find())
|
||||||
|
staticOwners.add(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Size: " + staticOwners.size());
|
||||||
|
int inconsistencies = 0;
|
||||||
|
|
||||||
|
for (Owner owner : results)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for (StaticOwner staticOwner : staticOwners)
|
||||||
|
{
|
||||||
|
if (staticOwner.equals(owner)) {
|
||||||
|
System.out.println("Found. Good");
|
||||||
|
found = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
inconsistencies++;
|
||||||
|
System.out.println("Not Found. Bad");
|
||||||
|
testOwnerStore.findAndReplace(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return inconsistencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue