From 76f679817fccaaeecc8d227bab50751a8766af26 Mon Sep 17 00:00:00 2001 From: Jeff Elsloo Date: Mon, 14 Mar 2016 16:04:11 -0600 Subject: [PATCH] Adds support for geolocation within the coverage zone file. This resolves #1157. --- .../traffic_router/core/loc/NetworkNode.java | 26 ++++++++--- .../core/router/TrafficRouter.java | 44 +++++++++++++------ .../core/router/DNSRoutingMissesTest.java | 2 +- .../core/router/DnsRoutePerformanceTest.java | 8 ++-- ...StatelessTrafficRouterPerformanceTest.java | 3 +- .../core/router/TrafficRouterTest.java | 2 +- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java index c2abbb30b..fc943114a 100644 --- a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java +++ b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java @@ -27,6 +27,8 @@ import java.util.TreeMap; import com.comcast.cdn.traffic_control.traffic_router.core.util.CidrAddress; +import com.comcast.cdn.traffic_control.traffic_router.geolocation.Geolocation; + import org.apache.log4j.Logger; import org.apache.wicket.ajax.json.JSONArray; import org.apache.wicket.ajax.json.JSONException; @@ -44,6 +46,7 @@ public class NetworkNode implements Comparable { private CidrAddress cidrAddress; private String loc; private CacheLocation cacheLocation = null; + private Geolocation geolocation = null; protected Map children; public static NetworkNode getInstance() { @@ -73,6 +76,14 @@ public static NetworkNode generateTree(final JSONObject json) { for (String loc : JSONObject.getNames(coverageZones)) { final JSONObject locData = coverageZones.getJSONObject(loc); + final JSONObject coordinates = locData.optJSONObject("coordinates"); + Geolocation geolocation = null; + + if (coordinates != null && coordinates.has("latitude") && coordinates.has("longitude")) { + final double latitude = coordinates.optDouble("latitude"); + final double longitude = coordinates.optDouble("longitude"); + geolocation = new Geolocation(latitude, longitude); + } try { final JSONArray network6 = locData.getJSONArray("network6"); @@ -81,7 +92,7 @@ public static NetworkNode generateTree(final JSONObject json) { final String ip = network6.getString(i); try { - root.add6(new NetworkNode(ip, loc)); + root.add6(new NetworkNode(ip, loc, geolocation)); } catch (NetworkNodeException ex) { LOGGER.error(ex, ex); } @@ -97,7 +108,7 @@ public static NetworkNode generateTree(final JSONObject json) { final String ip = network.getString(i); try { - root.add(new NetworkNode(ip, loc)); + root.add(new NetworkNode(ip, loc, geolocation)); } catch (NetworkNodeException ex) { LOGGER.error(ex, ex); } @@ -120,11 +131,16 @@ public static NetworkNode generateTree(final JSONObject json) { } public NetworkNode(final String str) throws NetworkNodeException { - this(str, null); + this(str, null, null); } public NetworkNode(final String str, final String loc) throws NetworkNodeException { + this(str, loc, null); + } + + public NetworkNode(final String str, final String loc, final Geolocation geolocation) throws NetworkNodeException { this.loc = loc; + this.geolocation = geolocation; cidrAddress = CidrAddress.fromString(str); } @@ -198,8 +214,8 @@ public String getLoc() { return loc; } - public void setLoc(final String loc) { - this.loc = loc; + public Geolocation getGeolocation() { + return geolocation; } public CacheLocation getCacheLocation() { diff --git a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java index fa45854ce..d192ad945 100644 --- a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java +++ b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java @@ -195,7 +195,7 @@ public List getCachesByGeo(final Request request, final DeliveryService d int locationsTested = 0; final int locationLimit = ds.getLocationLimit(); - final List cacheLocations = orderCacheLocations(request, getCacheRegister().getCacheLocations(null), ds, clientLocation); + final List cacheLocations = orderCacheLocations(getCacheRegister().getCacheLocations(null), ds, clientLocation); for (final CacheLocation location : cacheLocations) { final List caches = selectCache(location, ds); @@ -215,7 +215,7 @@ public List getCachesByGeo(final Request request, final DeliveryService d return null; } protected List selectCache(final Request request, final DeliveryService ds, final Track track) throws GeolocationException { - final CacheLocation cacheLocation = getCoverageZoneCache(request.getClientIP()); + final CacheLocation cacheLocation = getCoverageZoneCache(request.getClientIP(), ds); List caches = selectCachesByCZ(ds, cacheLocation, track); if (caches != null) { @@ -275,7 +275,7 @@ public DNSRouteResult route(final DNSRequest request, final Track track) throws return result; } - final CacheLocation cacheLocation = getCoverageZoneCache(request.getClientIP()); + final CacheLocation cacheLocation = getCoverageZoneCache(request.getClientIP(), ds); List caches = selectCachesByCZ(ds, cacheLocation, track); if (caches != null) { @@ -440,29 +440,33 @@ public HTTPRouteResult route(final HTTPRequest request, final Track track) throw return routeResult; } - protected CacheLocation getCoverageZoneCache(final String ip) { + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) + protected CacheLocation getCoverageZoneCache(final String ip, final DeliveryService ds) { NetworkNode nn = null; try { nn = NetworkNode.getInstance().getNetwork(ip); } catch (NetworkNodeException e) { LOGGER.warn(e); } + if (nn == null) { return null; } final String locId = nn.getLoc(); final CacheLocation cl = nn.getCacheLocation(); - if(cl != null) { + + if (cl != null) { return cl; } - if(locId == null) { + + if (locId == null) { return null; } - // find CacheLocation - final Collection caches = getCacheRegister() - .getCacheLocations(); + // find CacheLocation + final Collection caches = getCacheRegister().getCacheLocations(); + for (final CacheLocation cl2 : caches) { if (cl2.getId().equals(locId)) { nn.setCacheLocation(cl2); @@ -470,6 +474,20 @@ protected CacheLocation getCoverageZoneCache(final String ip) { } } + /* + * We had a hit in the CZF but the name does not match a known cache location. + * Check whether the CZF entry has a geolocation and use it if so. + */ + if (nn.getGeolocation() != null) { + final List cacheLocations = orderCacheLocations(caches, ds, nn.getGeolocation()); + + for (CacheLocation cacheLocation : cacheLocations) { + if (cacheLocation.getCaches() != null && !cacheLocation.getCaches().isEmpty()) { + return cacheLocation; + } + } + } + return null; } @@ -591,18 +609,16 @@ protected SortedMap consistentHash(final List caches, * If the client's location could not be determined, then the list is * unsorted. * - * @param request - * the client's request * @param cacheLocations * the collection of CacheLocations to order * @param ds * @return the ordered list of locations */ - public List orderCacheLocations(final Request request, final Collection cacheLocations, final DeliveryService ds, final Geolocation clientLocation) { + public List orderCacheLocations(final Collection cacheLocations, final DeliveryService ds, final Geolocation clientLocation) { final List locations = new ArrayList(); - for(final CacheLocation cl : cacheLocations) { - if(ds.isLocationAvailable(cl)) { + for (final CacheLocation cl : cacheLocations) { + if (ds.isLocationAvailable(cl)) { locations.add(cl); } } diff --git a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DNSRoutingMissesTest.java b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DNSRoutingMissesTest.java index df5e1b99b..c266d47a0 100644 --- a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DNSRoutingMissesTest.java +++ b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DNSRoutingMissesTest.java @@ -144,7 +144,7 @@ public void itSetsDetailsWhenCacheNotFoundByGeolocation() throws Exception { when(deliveryService.isCoverageZoneOnly()).thenReturn(false); doReturn(deliveryService).when(trafficRouter).selectDeliveryService(request, false); - doReturn(cacheLocation).when(trafficRouter).getCoverageZoneCache("192.168.34.56"); + doReturn(cacheLocation).when(trafficRouter).getCoverageZoneCache("192.168.34.56", deliveryService); doReturn(cacheRegister).when(trafficRouter).getCacheRegister(); trafficRouter.route(request, track); diff --git a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DnsRoutePerformanceTest.java b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DnsRoutePerformanceTest.java index 78ca9b2b6..3a7015ae0 100644 --- a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DnsRoutePerformanceTest.java +++ b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/DnsRoutePerformanceTest.java @@ -97,7 +97,7 @@ public void before() throws Exception { trafficRouter = spy(trafficRouter); - doCallRealMethod().when(trafficRouter).getCoverageZoneCache(anyString()); + doCallRealMethod().when(trafficRouter).getCoverageZoneCache(anyString(), any(DeliveryService.class)); doCallRealMethod().when(trafficRouter).selectCache(any(Request.class), any(DeliveryService.class), any(Track.class)); doCallRealMethod().when(trafficRouter, "selectCache", any(CacheLocation.class), any(DeliveryService.class)); @@ -164,10 +164,10 @@ public void itSupportsMinimalDNSRouteRequestTPS() throws Exception { System.out.println("TPS was " + tps + " for routing dns request with hostname " + names); for (ResultType resultType : ResultType.values()) { - if (resultType != ResultType.CZ && resultType != ResultType.GEO) { - assertThat(stats.get(resultType), equalTo(0)); - } else { + if (resultType == ResultType.CZ) { assertThat(stats.get(resultType), greaterThan(0)); + } else { + assertThat(stats.get(resultType), equalTo(0)); } } diff --git a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/StatelessTrafficRouterPerformanceTest.java b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/StatelessTrafficRouterPerformanceTest.java index 51ee2e9b8..e2ae15997 100644 --- a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/StatelessTrafficRouterPerformanceTest.java +++ b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/StatelessTrafficRouterPerformanceTest.java @@ -150,8 +150,7 @@ public URL routeTest(final HTTPRequest request, String[] rstrs) throws TrafficRo final String zoneId = null; // getZoneManager().getZone(request.getRequestedUrl()); Geolocation clientLocation = getGeolocationService().location(request.getClientIP()); - final List cacheLocations = orderCacheLocations(request, - getCacheRegister().getCacheLocations(zoneId), ds, clientLocation); + final List cacheLocations = orderCacheLocations(getCacheRegister().getCacheLocations(zoneId), ds, clientLocation); for (final CacheLocation location : cacheLocations) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Trying location: " + location.getId()); diff --git a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterTest.java b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterTest.java index 1bc4bf492..731e94271 100644 --- a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterTest.java +++ b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterTest.java @@ -114,7 +114,7 @@ public void itSetsResultToGeo() throws Exception { when(trafficRouter.getClientLocation(any(Request.class), any(DeliveryService.class), any(CacheLocation.class), any(Track.class))).thenReturn(clientLocation); when(trafficRouter.getCachesByGeo(any(Request.class), any(DeliveryService.class), any(Geolocation.class), any(Track.class))).thenCallRealMethod(); - when(trafficRouter.orderCacheLocations(any(Request.class), any(Collection.class), any(DeliveryService.class), any(Geolocation.class))).thenCallRealMethod(); + when(trafficRouter.orderCacheLocations(any(Collection.class), any(DeliveryService.class), any(Geolocation.class))).thenCallRealMethod(); when(trafficRouter.getSupportingCaches(any(List.class), any(DeliveryService.class))).thenCallRealMethod(); HTTPRequest httpRequest = new HTTPRequest();