Mass removal of all Tabs (Style Warnings)
[aaf/authz.git] / cadi / client / src / main / java / org / onap / aaf / cadi / locator / DNSLocator.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.locator;
23
24 import java.io.IOException;
25 import java.net.InetAddress;
26 import java.net.URI;
27 import java.net.URISyntaxException;
28
29 import org.onap.aaf.cadi.Access;
30 import org.onap.aaf.cadi.Locator;
31 import org.onap.aaf.cadi.LocatorException;
32 import org.onap.aaf.cadi.Access.Level;
33
34 public class DNSLocator implements Locator<URI> {
35     private static enum Status {UNTRIED, OK, INVALID, SLOW};
36     private static final int CHECK_TIME = 3000;
37     
38     private String host, protocol;
39     private Access access;
40     private Host[] hosts;
41     private int startPort, endPort;
42     private String suffix;
43     
44     public DNSLocator(Access access, String protocol, String host, String range) {
45         this.host = host;
46         this.protocol = protocol;
47         this.access = access;
48         int dash = range.indexOf('-');
49         if(dash<0) {
50             startPort = endPort = Integer.parseInt(range);
51         } else {
52             startPort = Integer.parseInt(range.substring(0,dash));
53             endPort = Integer.parseInt(range.substring(dash + 1));
54         }
55         refresh();
56     }
57
58     public DNSLocator(Access access, String aaf_locate) throws LocatorException {
59         this.access = access;
60         if(aaf_locate==null) {
61             throw new LocatorException("Null passed into DNSLocator constructor");
62         }
63         int start, port;
64         if(aaf_locate.startsWith("https:")) {
65             protocol = "https:";
66             start = 9; // https://
67             port = 443;
68         } else if(aaf_locate.startsWith("http:")) {
69             protocol = "http:";
70             start = 8; // http://
71             port = 80;
72         } else {
73             throw new LocatorException("DNSLocator accepts only https or http protocols.  (requested URL " + aaf_locate + ')');
74         }
75         
76         parsePorts(aaf_locate.substring(start), port);
77     }
78
79     @Override
80     public URI get(Item item) throws LocatorException {
81         return hosts[((DLItem)item).cnt].uri;
82     }
83
84     @Override
85     public boolean hasItems() {
86         for(Host h : hosts) {
87             if(h.status==Status.OK) {
88                 return true;
89             }
90         }
91         return false;
92     }
93
94     @Override
95     public void invalidate(Item item) {
96         DLItem di = (DLItem)item;
97         hosts[di.cnt].status = Status.INVALID;
98     }
99
100     @Override
101     public Item best() throws LocatorException {
102         // not a good "best"
103         for(int i=0;i<hosts.length;++i) {
104             switch(hosts[i].status) {
105                 case OK:
106                     return new DLItem(i);
107                 case INVALID:
108                     break;
109                 case SLOW:
110                     break;
111                 case UNTRIED:
112                     try {
113                         if(hosts[i].ia.isReachable(CHECK_TIME)) {
114                             hosts[i].status = Status.OK;
115                             return new DLItem(i);
116                         }
117                     } catch (IOException e) {
118                         throw new LocatorException(e);
119                     }
120                     break;
121                 default:
122                     break;
123             }
124         }
125         throw new LocatorException("No Available URIs for " + host);
126     }
127
128     @Override
129     public Item first() throws LocatorException {
130         return new DLItem(0);
131     }
132
133     @Override
134     public Item next(Item item) throws LocatorException {
135         DLItem di = (DLItem)item;
136         if(++di.cnt<hosts.length) {
137             return di;
138         } else {
139             return null;
140         }
141     }
142
143     @Override
144     public boolean refresh() {
145         try {
146             InetAddress[] ias = InetAddress.getAllByName(host);
147             Host[] temp = new Host[ias.length * (1 + endPort - startPort)];
148             int cnt = -1;
149             for(int j=startPort; j<=endPort; ++j) {
150                 for(int i=0;i<ias.length;++i) {
151                     temp[++cnt] = new Host(ias[i], j, suffix);
152                 }
153             }
154             hosts = temp;
155             return true;
156         } catch (Exception e) {
157             access.log(Level.ERROR, e);
158         }
159         return false;
160     }
161     
162     private void parsePorts(String aaf_locate, int defaultPort) throws LocatorException {
163         int slash, start;
164         int colon = aaf_locate.indexOf(':');
165         if(colon > 0) {
166             start = colon + 1;
167             int left = aaf_locate.indexOf('[', start);
168             if(left > 0) {
169                 int right = aaf_locate.indexOf(']', left + 1);
170                 if (right < 0) {
171                     throw new LocatorException("Missing closing bracket in DNSLocator constructor.  (requested URL " + aaf_locate + ')');
172                 } else if (right == (left + 1)) {
173                     throw new LocatorException("Missing ports in brackets in DNSLocator constructor.  (requested URL " + aaf_locate + ')');
174                 }
175                 int dash = aaf_locate.indexOf('-', left + 1);
176                 if (dash == (right - 1) || dash == (left + 1)) {
177                     throw new LocatorException("Missing ports in brackets in DNSLocator constructor.  (requested URL " + aaf_locate + ')');
178                 }
179                 if(dash < 0) {
180                     startPort = endPort = Integer.parseInt(aaf_locate.substring(left + 1, right));
181                 } else {
182                     startPort = Integer.parseInt(aaf_locate.substring(left + 1, dash));
183                     endPort = Integer.parseInt(aaf_locate.substring(dash + 1, right));
184                 }
185                 
186             } else {
187                 slash = aaf_locate.indexOf('/', start);
188                 if (slash == start) {
189                     throw new LocatorException("Missing port before '/' in DNSLocator constructor.  (requested URL " + aaf_locate + ')');
190                 }
191                 if(slash < 0) {
192                     startPort = endPort = Integer.parseInt(aaf_locate.substring(start));
193                 } else {
194                     startPort = endPort = Integer.parseInt(aaf_locate.substring(start, slash));
195                 }
196             }
197         } else {
198             startPort = endPort = defaultPort;
199         }        
200     }
201
202     private class Host {
203         private URI uri;
204         private InetAddress ia;
205         private Status status;
206         
207         public Host(InetAddress inetAddress, int port, String suffix) throws URISyntaxException {
208             ia = inetAddress;
209             uri = new URI(protocol,null,inetAddress.getHostAddress(),port,suffix,null,null);
210             status = Status.UNTRIED;
211         }
212     }
213     
214     private class DLItem implements Item {
215         public DLItem(int i) {
216             cnt = i;
217         }
218
219         private int cnt;
220     }
221     
222     public void destroy() {}
223 }