Fix DNSLocator when Network Disconnect
[aaf/authz.git] / cadi / client / src / main / java / org / onap / aaf / cadi / locator / DNSLocator.java
index 66ef4b1..f6edfd1 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,28 +23,39 @@ package org.onap.aaf.cadi.locator;
 
 import java.io.IOException;
 import java.net.InetAddress;
+//import java.net.InetAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.UnknownHostException;
 
 import org.onap.aaf.cadi.Access;
-import org.onap.aaf.cadi.Locator;
-import org.onap.aaf.cadi.LocatorException;
 import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.LocatorException;
 
-public class DNSLocator implements Locator<URI> {
+public class DNSLocator implements SizedLocator<URI> {
     private static enum Status {UNTRIED, OK, INVALID, SLOW};
     private static final int CHECK_TIME = 3000;
-    
+
     private String host, protocol;
     private Access access;
     private Host[] hosts;
     private int startPort, endPort;
     private String suffix;
-    
+    // Added for JUnit Purposes.  Force correct responses in odd situations on tests
+    private final DNSLookup dnsLookup;
+
+    private int size = 1; // initial, until refreshed.
+
     public DNSLocator(Access access, String protocol, String host, String range) {
+       this(access, protocol, host, range, DNSLookup.dflt);
+    }
+    
+    public DNSLocator(Access access, String protocol, String host, String range, DNSLookup dnsLookup) {
         this.host = host;
         this.protocol = protocol;
         this.access = access;
+        this.dnsLookup = dnsLookup;
+         
         int dash = range.indexOf('-');
         if (dash<0) {
             startPort = endPort = Integer.parseInt(range);
@@ -56,16 +67,21 @@ public class DNSLocator implements Locator<URI> {
     }
 
     public DNSLocator(Access access, String aaf_locate) throws LocatorException {
+       this(access, aaf_locate, DNSLookup.dflt);
+    }
+    
+    public DNSLocator(Access access, String aaf_locate, DNSLookup dnsLookup) throws LocatorException {
         this.access = access;
+        this.dnsLookup = dnsLookup;
         if (aaf_locate==null) {
             throw new LocatorException("Null passed into DNSLocator constructor");
         }
         int start, defPort;
-        if (aaf_locate.startsWith("https:")) {
+        if (aaf_locate.startsWith("https://")) {
             protocol = "https";
             start = 8; // https://
             defPort = 443;
-        } else if (aaf_locate.startsWith("http:")) {
+        } else if (aaf_locate.startsWith("http://")) {
             protocol = "http";
             start = 7; // http://
             defPort = 80;
@@ -77,20 +93,22 @@ public class DNSLocator implements Locator<URI> {
     }
 
     public static DNSLocator create(Access access, String url) throws LocatorException {
-               return new DNSLocator(access, url);
-       }
+        return new DNSLocator(access, url);
+    }
 
-       @Override
+    @Override
     public URI get(Item item) throws LocatorException {
         return hosts[((DLItem)item).cnt].uri;
     }
 
     @Override
     public boolean hasItems() {
-        for (Host h : hosts) {
+        if(hosts!=null) {
+          for (Host h : hosts) {
             if (h.status==Status.OK) {
                 return true;
             }
+          }
         }
         return false;
     }
@@ -147,7 +165,7 @@ public class DNSLocator implements Locator<URI> {
     @Override
     public boolean refresh() {
         try {
-            InetAddress[] ias = InetAddress.getAllByName(host);
+            InetAddress[] ias = dnsLookup.getAllByName(host);
             Host[] temp = new Host[ias.length * (1 + endPort - startPort)];
             int cnt = -1;
             for (int j=startPort; j<=endPort; ++j) {
@@ -156,18 +174,19 @@ public class DNSLocator implements Locator<URI> {
                 }
             }
             hosts = temp;
+            size = temp.length * (endPort-startPort+1);
             return true;
         } catch (Exception e) {
             access.log(Level.ERROR, e);
         }
         return false;
     }
-    
+
     private String parseHostAndPorts(String aaf_locate, int _start, int defaultPort) throws LocatorException {
         int slash, start;
         int colon = aaf_locate.indexOf(':',_start);
         if (colon > 0) {
-               host = aaf_locate.substring(_start,colon);
+            host = aaf_locate.substring(_start,colon);
             start = colon + 1;
             int left = aaf_locate.indexOf('[', start);
             if (left > 0) {
@@ -189,9 +208,9 @@ public class DNSLocator implements Locator<URI> {
                 }
                 slash = aaf_locate.indexOf('/', start);
                 if(slash>=0) {
-                       suffix = aaf_locate.substring(slash);
+                    suffix = aaf_locate.substring(slash);
                 }
-                
+
             } else {
                 slash = aaf_locate.indexOf('/', start);
                 if (slash == start) {
@@ -205,30 +224,47 @@ public class DNSLocator implements Locator<URI> {
                 }
             }
         } else {
-               slash = aaf_locate.indexOf('/', _start);
-               host = slash<_start?aaf_locate.substring(_start):aaf_locate.substring(_start,slash);
+            slash = aaf_locate.indexOf('/', _start);
+            host = slash<_start?aaf_locate.substring(_start):aaf_locate.substring(_start,slash);
             startPort = endPort = defaultPort;
         }
-        
+
         return host;
     }
-
+    
+    /**
+     * 
+     * Some ISPs return InetEntries for bogus entries, making JUnit Testing difficult.
+     * We add this interface to force validly empty responses.
+     * We don't use Lambda at this point, so we can continue to support JKD 1.7 
+     * a while longer.
+     *
+     */
+    public interface DNSLookup {
+        InetAddress[] getAllByName(String host) throws UnknownHostException;
+        public static final DNSLookup dflt = new DNSLookup() {
+        public InetAddress[] getAllByName(String host) throws UnknownHostException {
+        return InetAddress.getAllByName(host);
+        }
+       };
+    }
+    
     private class Host {
         private URI uri;
         private InetAddress ia;
         private Status status;
-        
+
         public Host(InetAddress inetAddress, int port, String suffix) throws URISyntaxException {
             ia = inetAddress;
             uri = new URI(protocol,null,inetAddress.getCanonicalHostName(),port,suffix,null,null);
             status = Status.UNTRIED;
         }
-        
+
         public String toString() {
-               return uri.toString() + " - " + status.name();
+            return uri.toString() + " - " + status.name();
         }
     }
-    
+
     private class DLItem implements Item {
         public DLItem(int i) {
             cnt = i;
@@ -236,6 +272,10 @@ public class DNSLocator implements Locator<URI> {
 
         private int cnt;
     }
-    
+
     public void destroy() {}
+
+    public int size() {
+        return size;
+    }
 }