Skip to content

Commit

Permalink
Locations Data Synchronization
Browse files Browse the repository at this point in the history
Synchronization of data sent to the server from the client. New
locations are added to the database. Existing ones are updated. Time
stamps are used to keep track of synchronization.
  • Loading branch information
littlefieldnick committed Aug 17, 2018
1 parent 8e14ce8 commit 54ba871
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ public interface LocationHierarchyService {

@Authorized({PrivilegeConstants.CREATE_ENTITY})
void createLocation(Location location) throws ConstraintViolations;

@Authorized({PrivilegeConstants.CREATE_ENTITY})
void updateLocation(Location location) throws ConstraintViolations;

@Authorized({PrivilegeConstants.VIEW_ENTITY})
List<LocationHierarchy> getAllLocationHierarchies();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,19 @@ public void createLocation(Location location) throws ConstraintViolations {
throw new ConstraintViolations("There was a problem saving the location to the database");
}
}

public void updateLocation(Location location) throws ConstraintViolations {

try {
this.entityService.save(location);
} catch (IllegalArgumentException e) {
}
catch (SQLException e) {
throw new ConstraintViolations("There was a problem saving the location to the database");
}


}

private void assignId(Location location) throws ConstraintViolations {
String id = location.getExtId() == null ? "" : location.getExtId();
Expand Down
34 changes: 29 additions & 5 deletions domain/src/main/java/org/openhds/domain/model/Location.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
Expand All @@ -14,6 +15,7 @@

import javax.persistence.CascadeType;

import org.hibernate.annotations.Proxy;
import org.openhds.domain.annotations.Description;
import org.openhds.domain.constraint.CheckFieldNotBlank;
import org.openhds.domain.constraint.ExtensionStringConstraint;
Expand All @@ -30,16 +32,15 @@
@XmlRootElement
public class Location
extends AuditableCollectedEntity
implements Serializable
{
implements Serializable {

public final static long serialVersionUID = 169551578162260199L;
@NotNull
@CheckFieldNotBlank
@NotNull(message="Location extId cannot be null")
@CheckFieldNotBlank(message="Location extId cannot be blank.")
@Searchable
@Description(description = "External Id of the location. This id is used internally.")
private String extId;
@CheckFieldNotBlank
@CheckFieldNotBlank(message="Location name cannot be blank.")
@Searchable
@Description(description = "Name of the location.")
private String locationName;
Expand All @@ -61,6 +62,10 @@ public class Location
@OneToMany(targetEntity = org.openhds.domain.model.Residency.class)
@JoinColumn(name = "location_uuid")
private List<Residency> residencies;
private long serverUpdateTime;
private long serverInsertTime;



public String getExtId() {
return extId;
Expand Down Expand Up @@ -133,5 +138,24 @@ public List<Residency> getResidencies() {
public void setResidencies(List<Residency> list) {
residencies = list;
}

public long getServerUpdateTime() {
return serverUpdateTime;
}

public void setServerUpdateTime(long serverUpdateTime) {
this.serverUpdateTime = serverUpdateTime;
}

public long getServerInsertTime() {
return serverInsertTime;
}

public void setServerInsertTime(long serverInsertTime) {
this.serverInsertTime = serverInsertTime;
}

public String getUuid() {
return uuid;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import org.openhds.domain.model.Location;


@XmlRootElement
public class Locations {

private List<Location> locations;
private long updateTimestamp;

@XmlElement(name = "location")
public List<Location> getLocations() {
Expand All @@ -21,4 +23,14 @@ public void setLocations(List<Location> locations) {
this.locations = locations;
}

}
public long getTimestamp() {
return updateTimestamp;
}

public void setTimestamp(long timestamp) {
this.updateTimestamp = timestamp;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ public LocationHierarchies getEntireLocationHierarchy() {

for (LocationHierarchy lh : allLocationHierarcies) {
LocationHierarchy copy = new LocationHierarchy();
copy.setUuid(lh.getUuid());
copy.setExtId(lh.getExtId());

LocationHierarchyLevel level = new LocationHierarchyLevel();
level.setName(lh.getLevel().getName());
level.setKeyIdentifier(lh.getLevel().getKeyIdentifier());
copy.setLevel(level);
copy.setName(lh.getName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
Expand Down Expand Up @@ -63,15 +65,89 @@ public Locations getAllLocations() {
List<Location> copies = new ArrayList<Location>(locations.size());

for (Location loc : locations) {
Location copy = ShallowCopier.copyLocation(loc);
Location copy = JsonShallowCopier.copyLocation(loc);
copies.add(copy);
}

Locations allLocations = new Locations();
allLocations.setLocations(copies);
allLocations.setTimestamp(new Date().getTime());
return allLocations;
}

@RequestMapping(method = RequestMethod.GET, value = "/pull/{timestamp}", produces = "application/json")
public ResponseEntity<Locations> getUpdatedLocations(@PathVariable long timestamp) {
long time = new Date().getTime();

List<Location> locations = locationHierarchyService.getAllLocations();
List<Location> copies = new ArrayList<Location>(locations.size());

for (Location loc : locations) {
long compTime;
if(loc.getServerUpdateTime() == 0)
compTime = loc.getServerInsertTime();
else
compTime = loc.getServerUpdateTime();

if(timestamp <= compTime && timestamp < time) {
copies.add(JsonShallowCopier.copyLocation(loc));
}
}
Locations all = new Locations();
ArrayList<Location> allLocations = new ArrayList<Location>();
allLocations.addAll(copies);
all.setLocations(allLocations);
all.setTimestamp(time);
return new ResponseEntity<Locations>(all, HttpStatus.ACCEPTED);
}

@RequestMapping(value="/pushUpdates", method = RequestMethod.PUT, consumes= {"application/json"}, produces = { "application/json" })
public ResponseEntity<? extends Serializable> pushUpdate(@RequestBody Locations locations) {
long lastClientUpdate = locations.getTimestamp();
long time = new Date().getTime();

ConstraintViolations cv = new ConstraintViolations();

for(Location location: locations.getLocations()) {
try {
location.setCollectedBy(fieldBuilder.referenceField(location.getCollectedBy(), cv));
location.setLocationLevel(fieldBuilder.referenceField(location.getLocationLevel(), cv));
location.setServerUpdateTime(new Date().getTime());
this.update(location, lastClientUpdate, time);
} catch(ConstraintViolations e){
return new ResponseEntity<WebServiceCallException>(new WebServiceCallException(e), HttpStatus.BAD_REQUEST);
}
}

return new ResponseEntity<>(time, HttpStatus.ACCEPTED);
}

public void update(Location loc, long currentTimestamp, long lastClientUpdate) throws ConstraintViolations {

if(locationHierarchyService.findLocationById(loc.getExtId()) == null) {
this.locationHierarchyService.createLocation(loc);
}

else if(loc.isDeleted()) {
if(loc.getUuid() == null)
throw new ConstraintViolations("The location uuid is null.");

this.locationHierarchyService.updateLocation(loc);
}

else if(locationHierarchyService.findLocationById(loc.getExtId()) != null){
//Set UUID to prevent assignment of a new one.
loc.setUuid(locationHierarchyService.findLocationById(loc.getExtId()).getUuid());
if(lastClientUpdate > currentTimestamp) {
//Convert timestamp to calendar instance
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTimestamp);
loc.setInsertDate(c);
}
this.locationHierarchyService.updateLocation(loc);
}
}

@RequestMapping(value = "/cached", method = RequestMethod.GET, produces = "application/json")
public void getAllCachedLocations(HttpServletResponse response) {
try {
Expand Down Expand Up @@ -100,6 +176,8 @@ public ResponseEntity<? extends Serializable> insert(@RequestBody Location locat
return new ResponseEntity<Location>(JsonShallowCopier.copyLocation(location), HttpStatus.CREATED);
}



@RequestMapping(value = "/zipped", method = RequestMethod.GET)
public void getAllZippedLocations(HttpServletResponse response) {
try {
Expand Down

1 comment on commit 54ba871

@littlefieldnick
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#9

Please sign in to comment.