Skip to content

Commit

Permalink
Added timeout and retries as an option. Improved Errors handlers. Ret…
Browse files Browse the repository at this point in the history
…urn no null address and coordinated when the address could not be geocoded
  • Loading branch information
r4m-juan committed Feb 8, 2021
1 parent ae7cadb commit 34e957d
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 82 deletions.
6 changes: 4 additions & 2 deletions src/main/java/com/route4me/sdk/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,18 @@ private <T> T makeRequest(RequestMethod method, URIBuilder builder, HttpEntity b
try {
return this.gson.fromJson(respString.toString(), clazz);
} catch (JsonSyntaxException ex) {
throw new APIException(String.format("Unexpected Server response: %s", respString.toString()));
throw new APIException(respString.toString());
}
} else if (type != null) {
StringBuilder respString = responseContentParser(br);
try {
return this.gson.fromJson(respString.toString(), type);
} catch (IllegalStateException ex) {
logger.error(ex);
throw new APIException(String.format("Error parsing JSON response from server. Illegal state error: %s", respString.toString()));
} catch (JsonSyntaxException ex) {
logger.error(String.format("Unexpected Server response: %s", respString.toString()));
logger.error(String.format("Error parsing JSON response from server. Unexpected syntax: %s", respString.toString()));
throw new APIException(String.format("Unexpected Server response: %s", respString.toString()));
}
}
if (clazz == String.class) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,53 +24,57 @@ public static void main(String[] args) {
GeocodingManager manager = new GeocodingManager(apiKey);

List<String> addresses = Arrays.asList(
"2271 SCANLAN ST., LONDON, N5W 6G9",
"112 COMMISSIONERS RD., EMBRO, N4V 1V9",
"82 HOPE ST. W., TAVISTOCK, N0B 2R0",
"70 HOPE ST. W., TAVISTOCK, N0B 2R0",
"485 WOODLAWN RD. W., GUELPH, N1H 7P7",
"183 SILVERCREEK PKWY N, GUELPH, N1H 3T2 ",
"183 SILVERCREEK PARKWAY N., GUELPH, N4G 3S9",
"183 SILVERCREEK PARKWAY N., GUELPH, N1H 3T2",
"130 SILVERCREEK PKY. N., GUELPH, N1H 7Y5",
"104 SILVERCREEK PKWY N, GUELPH, N1H 7B4",
"650 SCOTTSDALE DR., GUELPH, N1G 3M2",
"425 STONE RD. W., GUELPH, N1G 2X6",
"585 SCOTTSDALE DR., GUELPH, N1H 6H9",
"435 STONE RD W, GUELPH, N1G 2X6",
"372 STONE RD. WEST, GUELPH, N1G 2X6",
"372 STONE RD. WEST, GUELPH, N1G 2X6",
"175 STONE RD. W., GUELPH, N1G 2X6",
"80 STONE RD. W., GUELPH, N1G 5L4",
"7 CLAIR RD W, GUELPH, N1L 0A6",
"101 CLAIR RD E, GUELPH, N1L 0J7",
"65 GORDON ST., GUELPH, N1G 4Z1",
"65 GORDON ST., GUELPH, N1G 4Z1",
"243 WOODLAWN AVE. W., GUELPH, N1H 1G8",
"243 WOODLAWN AVE. W., GUELPH, N1H 1G8",
"11 WOODLAWN RD. WEST, GUELPH, N1E 2N4",
"49 WOODLAWN RD. W., GUELPH, N1E 1N5",
"40 HIGH ST., ELORA, N1H 1G8",
"7445 WELLINGTON COUNTY RD. #21, ELORA, V0B 1S0",
"875 ST DAVID ST N, FERGUS, N1M 2W3",
"900 TOWER ST S, FERGUS, N1M 3N7",
"870 TOWER ST. S., FERGUS, N0B 1S0",
"870 TOWER ST. S., FERGUS, N1M 2P6",
"710 TOWER ST. S., FERGUS, N1M 2R3",
"201 ANDREW ST. W., FERGUS, N1M 2P6",
"97 PARKSIDE PLACE, FERGUS, N1M 2W8",
"801 ST. DAVID ST. N., FERGUS, N1M 3M5",
"165 GEORGE ST., ARTHUR, N0G 1A0",
"8006 WELLINGTON RD., ARTHUR, N0G 1A0",
"5201 AMENT LINE, LINWOOD, N0B 2A0",
"5 WOODSTOCK ST. N., TAVISTOCK, N0B 2R0",
"23 WOODSTOCK ST. S., TAVISTOCK, N3T 1M2",
"595771 HWY #59, HUNTINGFORD, N4S 7W1",
"2271 SCANLAN ST., LONDON, N5W 6G9");
"2271 SCANLAN ST., LONDON, N5W 6G9",
"112 COMMISSIONERS RD., EMBRO, N4V 1V9",
"82 HOPE ST. W., TAVISTOCK, N0B 2R0",
"70 HOPE ST. W., TAVISTOCK, N0B 2R0",
"485 WOODLAWN RD. W., GUELPH, N1H 7P7",
"183 SILVERCREEK PKWY N, GUELPH, N1H 3T2 ",
"183 SILVERCREEK PARKWAY N., GUELPH, N4G 3S9",
"183 SILVERCREEK PARKWAY N., GUELPH, N1H 3T2",
"130 SILVERCREEK PKY. N., GUELPH, N1H 7Y5",
"104 SILVERCREEK PKWY N, GUELPH, N1H 7B4",
"650 SCOTTSDALE DR., GUELPH, N1G 3M2",
"425 STONE RD. W., GUELPH, N1G 2X6",
"585 SCOTTSDALE DR., GUELPH, N1H 6H9",
"435 STONE RD W, GUELPH, N1G 2X6",
"372 STONE RD. WEST, GUELPH, N1G 2X6",
"372 STONE RD. WEST, GUELPH, N1G 2X6",
"175 STONE RD. W., GUELPH, N1G 2X6",
"80 STONE RD. W., GUELPH, N1G 5L4",
"7 CLAIR RD W, GUELPH, N1L 0A6",
"101 CLAIR RD E, GUELPH, N1L 0J7",
"65 GORDON ST., GUELPH, N1G 4Z1",
"65 GORDON ST., GUELPH, N1G 4Z1",
"243 WOODLAWN AVE. W., GUELPH, N1H 1G8",
"243 WOODLAWN AVE. W., GUELPH, N1H 1G8",
"11 WOODLAWN RD. WEST, GUELPH, N1E 2N4",
"49 WOODLAWN RD. W., GUELPH, N1E 1N5",
"40 HIGH ST., ELORA, N1H 1G8",
"7445 WELLINGTON COUNTY RD. #21, ELORA, V0B 1S0",
"875 ST DAVID ST N, FERGUS, N1M 2W3",
"900 TOWER ST S, FERGUS, N1M 3N7",
"870 TOWER ST. S., FERGUS, N0B 1S0",
"870 TOWER ST. S., FERGUS, N1M 2P6",
"710 TOWER ST. S., FERGUS, N1M 2R3",
"201 ANDREW ST. W., FERGUS, N1M 2P6",
"97 PARKSIDE PLACE, FERGUS, N1M 2W8",
"801 ST. DAVID ST. N., FERGUS, N1M 3M5",
"165 GEORGE ST., ARTHUR, N0G 1A0",
"8006 WELLINGTON RD., ARTHUR, N0G 1A0",
"5201 AMENT LINE, LINWOOD, N0B 2A0",
"5 WOODSTOCK ST. N., TAVISTOCK, N0B 2R0",
"23 WOODSTOCK ST. S., TAVISTOCK, N3T 1M2",
"595771 HWY #59, HUNTINGFORD, N4S 7W1",
"2271 SCANLAN ST., LONDON, N5W 6G9",
"THIS IS AN INVALID ADDRESS");

GeocoderOptions options = new GeocoderOptions();

options.setDetailed(GeocoderDetails.SIMPLE);
options.setDetailed(GeocoderDetails.DETAILED);
options.setMaxThreads(40);
options.setMaxRetries(10);
options.setMaxTimeout(500l);

logger.debug("Running Geocoder with " + options.getMaxThreads() + " Threads.");
long startTime = System.currentTimeMillis();
Expand All @@ -80,16 +84,14 @@ public static void main(String[] args) {
logger.debug("Processed " + addresses.size() + " - Elapsed Time (seconds): " + (System.currentTimeMillis() - startTime) / 1000f);
logger.debug("All Threads Finished ");

options.setMaxThreads(40);
logger.debug("Running Geocoder with " + options.getMaxThreads() + " Threads.");
startTime = System.currentTimeMillis();

geocodedAddresses = manager.bulkGeocoder(addresses, options);
logger.debug("Addresses Geocoded: " + geocodedAddresses.size());

logger.debug("Processed " + addresses.size() + " - Elapsed Time (seconds): " + (System.currentTimeMillis() - startTime) / 1000f);
logger.debug("All Threads Finished ");
int i = 0;
for (Address geocodedAddress : geocodedAddresses) {
i++;
logger.debug("ADDRESS: (" + i + ")\t" + geocodedAddress.getAddress() + "\t" + geocodedAddress.getLatitude() + "\t" + geocodedAddress.getLongitude() + "\tGEOCODINGS:\t" + geocodedAddress.getGeocodings().get(0).getType() + "\t" + geocodedAddress.getGeocodings().get(0).getLatitude() + "\t" + geocodedAddress.getGeocodings().get(0).getLongitude());


}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class GeocoderOptions {
private GeocoderResponseFormat responseFormat = GeocoderResponseFormat.JSON;
private GeocoderDetails detailed = GeocoderDetails.DETAILED;
private int maxThreads = Runtime.getRuntime().availableProcessors() + 1;
private int maxRetries = 0;
private long maxTimeout = 500l;

public GeocoderOptions() {

Expand All @@ -19,6 +21,7 @@ public GeocoderOptions(int maxThreads) {
this.maxThreads = maxThreads;
}


public enum GeocoderDetails {
SIMPLE("false"),
DETAILED("true");
Expand Down Expand Up @@ -122,4 +125,34 @@ public void setMaxThreads(int maxThreads) {
this.maxThreads = maxThreads;
}

/**
* @return the maxRetries
*/
public int getMaxRetries() {
return maxRetries;
}

/**
* @param maxRetries the maxRetries to set
*/
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}

/**
* @param maxTimeout the maxTimeout to set
*/
public void setMaxTimeout(long maxTimeout) {
this.maxTimeout = maxTimeout;
}

/**
* @return the maxTimeout
*/
public long getMaxTimeout() {
return maxTimeout;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class GeocodingManager extends Manager {
public static final String GEOCODING_EP = "/api/geocoder.php";
public static final String GEOCODING_ADDRESS = "/api/address.php";
private static final String JSON_GEOCODE = "/actions/upload/json-geocode.php";
private static final int MAX_RETRIES = 5;
private int maxRetries = 0;

public GeocodingManager(String apiKey) {
super(apiKey);
Expand All @@ -64,6 +64,8 @@ public GeocoderWebSockets websocketsGeocoder(List<Address> addresses) {

public List<Address> bulkGeocoder(List<String> addresses, GeocoderOptions options) {
ExecutorService executor = Executors.newFixedThreadPool(options.getMaxThreads());

maxRetries = options.getMaxRetries();

List<Future<Address>> workers = new ArrayList<>();
List<Address> geocodedAddresses = new ArrayList<>();
Expand All @@ -81,7 +83,7 @@ public List<Address> bulkGeocoder(List<String> addresses, GeocoderOptions option
for (Future<Address> worker : workers) {
Address geocodedAddress;
try {
geocodedAddress = worker.get(500L, TimeUnit.MILLISECONDS);
geocodedAddress = worker.get(options.getMaxTimeout(), TimeUnit.MILLISECONDS);
geocodedAddresses.add(geocodedAddress);
} catch (InterruptedException | ExecutionException ex) {
logger.error("Thread Execution Exception. " + ex);
Expand All @@ -105,7 +107,7 @@ public Geocodings[] geocode(String address) throws APIException {
public <T> T forwardGeocode(URIBuilder builder, Class<T> clazz) {

int retries = 0;
while (retries < MAX_RETRIES) {
while (retries < maxRetries) {
try {
return this.makeJSONRequest(RequestMethod.GET, builder, "", clazz);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@
import java.util.concurrent.Callable;
import org.apache.http.client.utils.URIBuilder;


public class ThreadBasedGeocoding implements Callable {

private static final String GEOCODING_ADDRESS = "/api/address.php";


private final String address;
private final GeocodingManager manager;
private final GeocoderOptions options;
Expand All @@ -28,26 +26,24 @@ public ThreadBasedGeocoding(GeocodingManager manager, String address, GeocoderOp
this.options = options;
}


protected static URIBuilder defaultBuilder(String endpoint) {
URIBuilder builder = new URIBuilder();
builder.setScheme("https");
builder.setHost("api.route4me.com");
builder.setPath(endpoint);
return builder;
}
private URIBuilder getBuilder(){

private URIBuilder getBuilder() {
URIBuilder builder = defaultBuilder(GEOCODING_ADDRESS);
builder.setParameter("address", address);
builder.setParameter("format", options.getResponseFormat().getValue());
builder.setParameter("detailed", options.getDetailed().getValue());
return builder;
}


private <T> T geocoder(Class<T> clazz) {
return manager.forwardGeocode(getBuilder(), clazz);
return manager.forwardGeocode(getBuilder(), clazz);
}

@Override
Expand All @@ -57,28 +53,38 @@ public String toString() {

@Override
public Address call() throws Exception {
Address geocodedAddress = new Address();
geocodedAddress.setAddress(address);

switch(options.getDetailed()) {
Address geocodedAddress = new Address(address, 0.0, 0.0);
Geocodings defaultGeocodings = new Geocodings(0.0, 0.0, "invalid", "0", address);
geocodedAddress.setGeocodings(Arrays.asList(defaultGeocodings));
switch (options.getDetailed()) {
case DETAILED:
Geocodings[] geocodes = geocoder(Geocodings[].class);
if (geocodes != null && options.getDetailed().equals(GeocoderOptions.GeocoderDetails.DETAILED)){
if (geocodes != null && options.getDetailed().equals(GeocoderOptions.GeocoderDetails.DETAILED)) {
geocodes = fixGeocodings(geocodes);
geocodedAddress.setGeocodings(Arrays.asList(geocodes));
geocodedAddress.setLatitude(geocodes[0].getCoordinates().getLatitude());
geocodedAddress.setLongitude(geocodes[0].getCoordinates().getLongitude());
}
break;
}
case SIMPLE:
GeoCoordinates geocoordinate = geocoder(GeoCoordinates.class);
if (geocoordinate != null){
if (geocoordinate != null) {
geocodedAddress.setLatitude(geocoordinate.getLatitude());
geocodedAddress.setLongitude(geocoordinate.getLongitude());
}
break;
}

return geocodedAddress;
}

private Geocodings[] fixGeocodings(Geocodings[] geocodes) {
// This is done to maintain the backward compatibility
for (Geocodings g: geocodes){
g.setLatitude(g.getCoordinates().getLatitude());
g.setLongitude(g.getCoordinates().getLongitude());
}
return geocodes;
}

}
20 changes: 11 additions & 9 deletions src/main/java/com/route4me/sdk/services/routing/Address.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@Data
public class Address {

@SerializedName("route_destination_id")
private Long routeDestinationId;
@SerializedName("alias")
Expand Down Expand Up @@ -60,9 +60,9 @@ public class Address {
@SerializedName("notes")
private List<Note> notes;
@SerializedName("custom_fields")
private Map<String, Object> custom_fields;
private Map<String, Object> custom_fields;
@SerializedName("manifest")
private Map<String, Object> manifest;
private Map<String, Object> manifest;
@SerializedName("order_id")
private Integer orderId;
@SerializedName("group")
Expand Down Expand Up @@ -168,20 +168,23 @@ public class Address {

@SerializedName("tags")
@QueryParameter("tags")
private List<String> tags;


private List<String> tags;

public Address() {
}

public Address(String address) {
this.address = address;
}

public Address(String address, double lat, double lng, long time) {
public Address(String address, double lat, double lng) {
this(address);
this.latitude = lat;
this.longitude = lng;
}

public Address(String address, double lat, double lng, long time) {
this(address, lat, lng);
this.time = time;
}

Expand Down Expand Up @@ -213,7 +216,6 @@ public Address(String address, String alias, double lat, double lng, long time)
this.alias = alias;
}


public void addCustomField(String key, Object value) {
this.custom_fields.put(key, value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,13 @@ public class Geocodings {
@SerializedName("rooftop_coordinates")
@QueryParameter("rooftop_coordinates")
private GeoCoordinates rooftopCoordinates;

public Geocodings(Double latitude, Double longitude, String type, String confidence, String address) {
this.name = address;
this.latitude = latitude;
this.longitude = longitude;
this.type = type;
this.confidence = confidence;
}

}

0 comments on commit 34e957d

Please sign in to comment.