AT&T 2.0.19 Code drop, stage 2
[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                 int colon = aaf_locate.indexOf(':',start);
77                 int slash;
78                 if(colon>0) {
79                         start = colon+1;
80                         int left = aaf_locate.indexOf('[',start);
81                         if(left>0) {
82                                 int right = aaf_locate.indexOf(']',left+1);
83                                 if(right>0) {
84                                         int dash = aaf_locate.indexOf('-',left+1);
85                                         if(dash<0) {
86                                                 startPort = endPort = Integer.parseInt(aaf_locate.substring(left+1,right));
87                                         } else {
88                                                 startPort = Integer.parseInt(aaf_locate.substring(left+1,dash));
89                                                 endPort = Integer.parseInt(aaf_locate.substring(dash + 1,right));
90                                         }
91                                 }
92                                 
93                         } else {
94                                 slash = aaf_locate.indexOf('/',colon+1);
95                                 if(slash<0) {
96                                         startPort = endPort = Integer.parseInt(aaf_locate.substring(start));
97                                 } else {
98                                         startPort = endPort = Integer.parseInt(aaf_locate.substring(start,slash));
99                                 }
100                         }
101                 } else {
102                         startPort = endPort = port;
103                 }               
104         }
105
106         @Override
107         public URI get(Item item) throws LocatorException {
108                 return hosts[((DLItem)item).cnt].uri;
109         }
110
111         @Override
112         public boolean hasItems() {
113                 for(Host h : hosts) {
114                         if(h.status==Status.OK) {
115                                 return true;
116                         }
117                 }
118                 return false;
119         }
120
121         @Override
122         public void invalidate(Item item) {
123                 DLItem di = (DLItem)item;
124                 hosts[di.cnt].status = Status.INVALID;
125         }
126
127         @Override
128         public Item best() throws LocatorException {
129                 // not a good "best"
130                 for(int i=0;i<hosts.length;++i) {
131                         switch(hosts[i].status) {
132                                 case OK:
133                                         return new DLItem(i);
134                                 case INVALID:
135                                         break;
136                                 case SLOW:
137                                         break;
138                                 case UNTRIED:
139                                         try {
140                                                 if(hosts[i].ia.isReachable(CHECK_TIME)) {
141                                                         hosts[i].status = Status.OK;
142                                                         return new DLItem(i);
143                                                 }
144                                         } catch (IOException e) {
145                                                 throw new LocatorException(e);
146                                         }
147                                         break;
148                                 default:
149                                         break;
150                         }
151                 }
152                 throw new LocatorException("No Available URIs for " + host);
153         }
154
155         @Override
156         public Item first() throws LocatorException {
157                 return new DLItem(0);
158         }
159
160         @Override
161         public Item next(Item item) throws LocatorException {
162                 DLItem di = (DLItem)item;
163                 if(++di.cnt<hosts.length) {
164                         return di;
165                 } else {
166                         return null;
167                 }
168         }
169
170         @Override
171         public boolean refresh() {
172                 try {
173                         InetAddress[] ias = InetAddress.getAllByName(host);
174                         Host[] temp = new Host[ias.length * (1 + endPort - startPort)];
175                         int cnt = -1;
176                         for(int j=startPort; j<=endPort; ++j) {
177                                 for(int i=0;i<ias.length;++i) {
178                                         temp[++cnt] = new Host(ias[i], j, suffix);
179                                 }
180                         }
181                         hosts = temp;
182                         return true;
183                 } catch (Exception e) {
184                         access.log(Level.ERROR, e);
185                 }
186                 return false;
187         }
188
189         private class Host {
190                 private URI uri;
191                 private InetAddress ia;
192                 private Status status;
193                 
194                 public Host(InetAddress inetAddress, int port, String suffix) throws URISyntaxException {
195                         ia = inetAddress;
196                         uri = new URI(protocol,null,inetAddress.getHostAddress(),port,suffix,null,null);
197                         status = Status.UNTRIED;
198                 }
199         }
200         
201         private class DLItem implements Item {
202                 public DLItem(int i) {
203                         cnt = i;
204                 }
205
206                 private int cnt;
207         }
208         
209         public void destroy() {}
210 }