diff --git a/README.md b/README.md index 4966392..6e2c5b5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Available methods: GET /mapcode/status Returns 200 if the service OK. GET /mapcode/codes/{lat},{lon}[/[mapcodes|local|international]] - [?precision=[0|1|2] & territory={restrictToTerritory} & alphabet={alphabet} & include={offset|territory}] + [?precision=[0|1|2] & territory={restrictToTerritory} & alphabet={alphabet} & include={offset|territory|alphabet}] Convert latitude/longitude to one or more mapcodes. Path parameters: @@ -30,6 +30,7 @@ Available methods: include : Multiple options may be set, separated by comma's: offset = include offset from mapcode center to lat/lon (in meters) territory = always include territory in result, also for territory 'AAA' + alphabet = always include mapcodeInAlphabet, even if the same as mapcode GET /mapcode/coords/{code} [?territory={mapcodeTerritory}] Convert a mapcode into a latitude/longitude pair @@ -81,6 +82,7 @@ in `src/main/resources` which override the following properties: MongoDBTrace.writeEnabled = true MongoDBTrace.servers = your-server:27017 + MongoDBTrace.database = your-database MongoDBTrace.userName = your-username MongoDBTrace.password = your-password @@ -112,7 +114,12 @@ There's also an example HTML page in the `examples/index.html` for HTML/Javascri ## Release Notes -* 1.50.1 +* 1.50.1.3 + + Added "?include=alphabet" option to always include mapcodeInAlphabet or territoryInAlphabet even if the same + as the original (default is now these are only output if different). + +* 1.50.1.0 - 1.50.1.2 Bug fix for state IN-DD (in India). diff --git a/example/monitorclient/MapcodeMonitor.js b/example/monitorclient/MapcodeMonitor.js index ba8741a..2134a0b 100644 --- a/example/monitorclient/MapcodeMonitor.js +++ b/example/monitorclient/MapcodeMonitor.js @@ -77,9 +77,9 @@ $(document).ready(function () { metric(metricName, "lastMonth/" + pathPostfix, "Last Month")]); } - stdgraph("#allMapcodeToLatLonRequestsSum", "Total requests: mapcode > coord", "AllMapcodeToLatLonRequests", "sum"); + stdgraph("#totalMapcodeToLatLonRequestsSum", "Total requests: mapcode > coord", "TotalMapcodeToLatLonRequests", "sum"); stdgraph("#validMapcodeToLatLonRequestsSum", "Valid requests: mapcode > coord", "ValidMapcodeToLatLonRequests", "sum"); - stdgraph("#allLatLonToMapcodeRequestsSum", "Total requests: coord > mapcode", "AllLatLonToMapcodeRequests", "sum"); + stdgraph("#totalLatLonToMapcodeRequestsSum", "Total requests: coord > mapcode", "TotalLatLonToMapcodeRequests", "sum"); stdgraph("#validLatLonToMapcodeRequestsSum", "Valid requests: coord > mapcode", "ValidLatLonToMapcodeRequests", "sum"); stdgraph("#warningsAndErrorsSum", "Warnings and Errors", "WarningsAndErrors", "sum"); diff --git a/example/monitorclient/index.html b/example/monitorclient/index.html index bd03c36..920e1d6 100644 --- a/example/monitorclient/index.html +++ b/example/monitorclient/index.html @@ -55,7 +55,7 @@

System Usage - Totals

-
+
@@ -65,7 +65,7 @@

System Usage - Totals

-
+
@@ -83,10 +83,11 @@

System Usage - Totals

- Important: These monitoring statistics represent a single - Mapcode REST API server instance. If the service using multiple servers - behind a load-balancer, these statistics do not represent all servers, - just one of them. + Important: This page serves as an example of how to monitor this + service only. In its current implementation, the monitoring statistics + represent a single Mapcode REST API server instance. + If the service using multiple servers behind a load-balancer, + these statistics do not represent all servers, just one of them.
diff --git a/pom.xml b/pom.xml index abf5245..e7981cb 100755 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ mapcode-rest-service war - 1.50.1.0 + 1.50.1.3 Mapcode REST API Web Service diff --git a/src/main/java/com/mapcode/services/MapcodeResource.java b/src/main/java/com/mapcode/services/MapcodeResource.java index 83359ca..51f72e2 100644 --- a/src/main/java/com/mapcode/services/MapcodeResource.java +++ b/src/main/java/com/mapcode/services/MapcodeResource.java @@ -39,7 +39,8 @@ enum ParamType { enum ParamInclude { OFFSET, // Includes offset (in meters) from center of mapcode to originally specified lat/lon. - TERRITORY // Force including the territory, even when the territory code is "AAA". + TERRITORY, // Force including the territory, even when the territory code is "AAA". + ALPHABET // Force including the mapcodeInAlphabet attribute, even if it is the same as the mapcode. } /** diff --git a/src/main/java/com/mapcode/services/SystemMetrics.java b/src/main/java/com/mapcode/services/SystemMetrics.java index 563ac58..aa91ca6 100644 --- a/src/main/java/com/mapcode/services/SystemMetrics.java +++ b/src/main/java/com/mapcode/services/SystemMetrics.java @@ -55,7 +55,7 @@ enum Metric { * @return The total number of requests for mapcode to lat/lon. */ @Nonnull - MultiMetricsData getAllMapcodeToLatLonRequests(); + MultiMetricsData getTotalMapcodeToLatLonRequests(); /** * @return The number of valid requests for mapcode to lat/lon. @@ -67,7 +67,7 @@ enum Metric { * @return The total number of requests for lat/lon to mapcode. */ @Nonnull - MultiMetricsData getAllLatLonToMapcodeRequests(); + MultiMetricsData getTotalLatLonToMapcodeRequests(); /** * @return The number of valid requests for lat/lon to mapcode. diff --git a/src/main/java/com/mapcode/services/SystemMetricsCollector.java b/src/main/java/com/mapcode/services/SystemMetricsCollector.java index 6f8c94a..0bc76d0 100644 --- a/src/main/java/com/mapcode/services/SystemMetricsCollector.java +++ b/src/main/java/com/mapcode/services/SystemMetricsCollector.java @@ -13,21 +13,21 @@ public interface SystemMetricsCollector { * Called whenever ANY mapcode to lat/lon request is made. The request may fail because * the parameters may be invalid though. */ - public void allMapcodeToLatLonRequests(); + public void addOneMapcodeToLatLonRequest(); /** * Called whenever a successful mapcode to lat/lon request is made. */ - public void validMapcodeToLatLonRequests(); + public void addOneValidMapcodeToLatLonRequest(); /** * Called whenever ANY lat/lon to mapcode request is made. The request may fail because * the parameters may be invalid though. */ - public void allLatLonToMapcodeRequests(); + public void addOneLatLonToMapcodeRequest(); /** * Called whenever a successful lat/lon to mapcode request is made. */ - public void validLatLonToMapcodeRequests(); + public void addOneValidLatLonToMapcodeRequest(); } diff --git a/src/main/java/com/mapcode/services/dto/MapcodeDTO.java b/src/main/java/com/mapcode/services/dto/MapcodeDTO.java index f8801f4..17c6cc2 100644 --- a/src/main/java/com/mapcode/services/dto/MapcodeDTO.java +++ b/src/main/java/com/mapcode/services/dto/MapcodeDTO.java @@ -34,7 +34,7 @@ public final class MapcodeDTO extends ApiDTO { @Nonnull private String mapcode; - @Nonnull + @Nullable private String mapcodeInAlphabet; @Nullable @@ -50,7 +50,7 @@ public final class MapcodeDTO extends ApiDTO { public void validate() { validator().start(); validator().checkString(true, "mapcode", mapcode, ApiConstants.API_MAPCODE_LEN_MIN, ApiConstants.API_MAPCODE_LEN_MAX); - validator().checkString(true, "mapcodeInAlphabet", mapcodeInAlphabet, ApiConstants.API_MAPCODE_LEN_MIN, ApiConstants.API_MAPCODE_LEN_MAX); + validator().checkString(false, "mapcodeInAlphabet", mapcodeInAlphabet, ApiConstants.API_MAPCODE_LEN_MIN, ApiConstants.API_MAPCODE_LEN_MAX); validator().checkString(false, "territory", territory, ApiConstants.API_TERRITORY_LEN_MIN, ApiConstants.API_TERRITORY_LEN_MAX); validator().checkString(false, "territoryInAlphabet", territoryInAlphabet, ApiConstants.API_TERRITORY_LEN_MIN, ApiConstants.API_TERRITORY_LEN_MAX); validator().checkDouble(false, "offsetMeters", offsetMeters, -Double.MAX_VALUE, Double.MAX_VALUE, false); @@ -59,7 +59,7 @@ public void validate() { public MapcodeDTO( @Nonnull final String mapcode, - @Nonnull final String mapcodeInAlphabet, + @Nullable final String mapcodeInAlphabet, @Nullable final String territory, @Nullable final String territoryInAlphabet, @Nullable final Double offsetMeters) { @@ -89,15 +89,14 @@ public void setMapcode(@Nonnull final String mapcode) { this.mapcode = mapcode; } - @Nonnull + @Nullable public String getMapcodeInAlphabet() { beforeGet(); return mapcodeInAlphabet; } - public void setMapcodeInAlphabet(@Nonnull final String mapcodeInAlphabet) { + public void setMapcodeInAlphabet(@Nullable final String mapcodeInAlphabet) { beforeSet(); - assert mapcodeInAlphabet != null; this.mapcodeInAlphabet = mapcodeInAlphabet; } diff --git a/src/main/java/com/mapcode/services/implementation/MapcodeResourceImpl.java b/src/main/java/com/mapcode/services/implementation/MapcodeResourceImpl.java index a5819eb..7ab6873 100644 --- a/src/main/java/com/mapcode/services/implementation/MapcodeResourceImpl.java +++ b/src/main/java/com/mapcode/services/implementation/MapcodeResourceImpl.java @@ -138,7 +138,7 @@ public void convertLatLonToMapcode( processor.process("convertLatLonToMapcode", LOG, response, () -> { LOG.info("convertLatLonToMapcode: lat={}, lon={}, precision={}, type={}, context={}, alphabet={}, include={}", paramLatDeg, paramLonDeg, paramPrecision, paramType, paramTerritory, paramAlphabet, paramInclude); - metricsCollector.allLatLonToMapcodeRequests(); + metricsCollector.addOneLatLonToMapcodeRequest(); // Check lat range. final double latDeg = paramLatDeg; @@ -186,12 +186,14 @@ public void convertLatLonToMapcode( // Check include. boolean foundIncludeOffset = false; boolean foundIncludeTerritory = false; + boolean foundIncludeAlphabet = false; for (final String arg : paramInclude.toUpperCase().split(",")) { if (!arg.isEmpty()) { try { ParamInclude include = ParamInclude.valueOf(arg); foundIncludeOffset = foundIncludeOffset || (include == ParamInclude.OFFSET); foundIncludeTerritory = foundIncludeTerritory || (include == ParamInclude.TERRITORY); + foundIncludeAlphabet = foundIncludeAlphabet || (include == ParamInclude.ALPHABET); } catch (final IllegalArgumentException ignored) { throw new ApiInvalidFormatException(PARAM_INCLUDE, paramInclude, API_ERROR_VALID_INCLUDES.toLowerCase()); } @@ -201,6 +203,7 @@ public void convertLatLonToMapcode( // Determine whether include=offset and territory=xxx were supplied as URL parameters. final boolean includeOffset = foundIncludeOffset; final boolean includeTerritory = foundIncludeTerritory; + final boolean includeAlphabet = foundIncludeAlphabet; // Send a trace event with the lat/lon and other parameters. TRACER.eventLatLonToMapcode(latDeg, lonDeg, territory, precision, paramType, paramAlphabet, paramInclude); @@ -230,28 +233,34 @@ public void convertLatLonToMapcode( // No type was supplied, so we need to return the local, international and all mapcodes. result = new MapcodesDTO( - getMapcodeDTO(mapcodeLocal, precision, alphabet, includeTerritory, includeOffset, latDeg, lonDeg), - getMapcodeDTO(mapcodeInternational, precision, alphabet, includeTerritory, includeOffset, latDeg, lonDeg), + getMapcodeDTO(mapcodeLocal, precision, alphabet, includeOffset, includeTerritory, includeAlphabet, + latDeg, lonDeg), + getMapcodeDTO(mapcodeInternational, precision, alphabet, includeOffset, includeTerritory, includeAlphabet, + latDeg, lonDeg), mapcodesAll.stream(). - map(mapcode -> getMapcodeDTO(mapcode, precision, alphabet, includeTerritory, includeOffset, latDeg, lonDeg)). + map(mapcode -> getMapcodeDTO(mapcode, precision, alphabet, includeOffset, includeTerritory, + includeAlphabet, latDeg, lonDeg)). collect(Collectors.toList())); } else { // Return only the local, international or all mapcodes. switch (type) { case LOCAL: { - result = getMapcodeDTO(mapcodeLocal, precision, alphabet, includeTerritory, includeOffset, latDeg, lonDeg); + result = getMapcodeDTO(mapcodeLocal, precision, alphabet, includeOffset, includeTerritory, includeAlphabet, + latDeg, lonDeg); break; } case INTERNATIONAL: { - result = getMapcodeDTO(mapcodeInternational, precision, alphabet, includeTerritory, includeOffset, latDeg, lonDeg); + result = getMapcodeDTO(mapcodeInternational, precision, alphabet, includeOffset, includeTerritory, includeAlphabet, + latDeg, lonDeg); break; } case MAPCODES: { result = new MapcodeListDTO(mapcodesAll.stream(). - map(mapcode -> getMapcodeDTO(mapcode, precision, alphabet, includeTerritory, includeOffset, latDeg, lonDeg)). + map(mapcode -> getMapcodeDTO(mapcode, precision, alphabet, includeOffset, includeTerritory, includeAlphabet, + latDeg, lonDeg)). collect(Collectors.toList())); break; } @@ -264,7 +273,7 @@ public void convertLatLonToMapcode( // Validate the DTO before returning it, to make sure it's valid (internal consistency check). result.validate(); - metricsCollector.validLatLonToMapcodeRequests(); + metricsCollector.addOneValidLatLonToMapcodeRequest(); response.setResponse(Response.ok(result).build()); } catch (final UnknownMapcodeException ignored) { @@ -294,7 +303,7 @@ public void convertMapcodeToLatLon( processor.process("convertMapcodeToLatLon", LOG, response, () -> { LOG.info("convertMapcodeToLatLon: code={}, territory={}", paramCode, paramContext); - metricsCollector.allMapcodeToLatLonRequests(); + metricsCollector.addOneMapcodeToLatLonRequest(); // Get the territory from the path (if specified). final Territory territoryContext; @@ -332,7 +341,7 @@ public void convertMapcodeToLatLon( // Validate the result (internal consistency check). result.validate(); - metricsCollector.validMapcodeToLatLonRequests(); + metricsCollector.addOneValidMapcodeToLatLonRequest(); response.setResponse(Response.ok(result).build()); // The response is already set within this method body. @@ -533,15 +542,19 @@ private static Territory getTerritoryAlias(@Nonnull final String paramAlias) { @Nonnull private static MapcodeDTO getMapcodeDTO(@Nonnull final Mapcode mapcode, final int precision, - @Nullable final Alphabet alphabet, final boolean includeTerritory, - final boolean includeOffset, final double latDeg, final double lonDeg) { + @Nullable final Alphabet alphabet, final boolean includeOffset, + final boolean includeTerritory, final boolean includeAlphabet, + final double latDeg, final double lonDeg) { + final String code = mapcode.getCode(precision); + final String codeInAlphabet = mapcode.getCode(precision, alphabet); + final String territory = mapcode.getTerritory().toString(); + final String territoryInAlphabet = mapcode.getTerritory().toString(alphabet); + final boolean includeOrLocal = includeTerritory || (mapcode.getTerritory() != Territory.AAA); return new MapcodeDTO( - mapcode.getCode(precision), - mapcode.getCode(precision, alphabet), - (includeTerritory || (mapcode.getTerritory() != Territory.AAA)) ? - mapcode.getTerritory().toString() : null, - (includeTerritory || (mapcode.getTerritory() != Territory.AAA)) ? - mapcode.getTerritory().toString(alphabet) : null, + code, + includeAlphabet ? codeInAlphabet : (codeInAlphabet.equals(code) ? null : codeInAlphabet), + includeOrLocal ? territory : null, + includeOrLocal ? (includeAlphabet ? territoryInAlphabet : (territoryInAlphabet.equals(territory) ? null : territoryInAlphabet)) : null, includeOffset ? offsetFromLatLonInMeters(latDeg, lonDeg, mapcode, precision) : null); } diff --git a/src/main/java/com/mapcode/services/implementation/RootResourceImpl.java b/src/main/java/com/mapcode/services/implementation/RootResourceImpl.java index ff3be81..2548eb6 100644 --- a/src/main/java/com/mapcode/services/implementation/RootResourceImpl.java +++ b/src/main/java/com/mapcode/services/implementation/RootResourceImpl.java @@ -49,7 +49,7 @@ public class RootResourceImpl implements RootResource { "GET /mapcode/status Returns 200 if the service OK.\n\n" + "GET /mapcode/codes/{lat},{lon}[/[mapcodes|local|international]]\n" + - " [?precision=[0|1|2] & territory={restrictToTerritory} & alphabet={alphabet} & include={offset|territory}]\n\n" + + " [?precision=[0|1|2] & territory={restrictToTerritory} & alphabet={alphabet} & include={offset|territory|alphabet}]\n\n" + " Convert latitude/longitude to one or more mapcodes.\n" + " Path parameters:\n" + @@ -67,7 +67,8 @@ public class RootResourceImpl implements RootResource { " alphabet : Alphabet to return results in, numeric or alpha code.\n" + " include : Multiple options may be set, separated by comma's:\n" + " offset = Include offset from mapcode center to lat/lon (in meters).\n" + - " territory = Always include territory in result, also for territory 'AAA'.\n\n" + + " territory = Always include territory in result, also for territory 'AAA'.\n" + + " alphabet = Always the mapcodeInAlphabet, also if same as mapcode.\n\n" + "GET /mapcode/coords/{code} [?context={territoryContext}]\n" + " Convert a mapcode into a latitude/longitude pair.\n\n" + diff --git a/src/main/java/com/mapcode/services/implementation/SystemMetricsImpl.java b/src/main/java/com/mapcode/services/implementation/SystemMetricsImpl.java index 8056c8f..5499cce 100644 --- a/src/main/java/com/mapcode/services/implementation/SystemMetricsImpl.java +++ b/src/main/java/com/mapcode/services/implementation/SystemMetricsImpl.java @@ -94,7 +94,7 @@ public MultiMetricsData getMetricData(@Nonnull final Metric metric) { @Nonnull @Override - public MultiMetricsData getAllMapcodeToLatLonRequests() { + public MultiMetricsData getTotalMapcodeToLatLonRequests() { return allMapcodeToLatLonRequests; } @@ -106,7 +106,7 @@ public MultiMetricsData getValidMapcodeToLatLonRequests() { @Nonnull @Override - public MultiMetricsData getAllLatLonToMapcodeRequests() { + public MultiMetricsData getTotalLatLonToMapcodeRequests() { return allLatLonToMapcodeRequests; } @@ -123,22 +123,22 @@ public MultiMetricsData getWarningsAndErrors() { } @Override - public void allMapcodeToLatLonRequests() { + public void addOneMapcodeToLatLonRequest() { allMapcodeToLatLonRequests.addValue(1); } @Override - public void validMapcodeToLatLonRequests() { + public void addOneValidMapcodeToLatLonRequest() { validMapcodeToLatLonRequests.addValue(1); } @Override - public void allLatLonToMapcodeRequests() { + public void addOneLatLonToMapcodeRequest() { allLatLonToMapcodeRequests.addValue(1); } @Override - public void validLatLonToMapcodeRequests() { + public void addOneValidLatLonToMapcodeRequest() { validLatLonToMapcodeRequests.addValue(1); } }