1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.locator;
\r
25 import java.io.IOException;
\r
26 import java.net.InetAddress;
\r
27 import java.net.InetSocketAddress;
\r
28 import java.net.Socket;
\r
29 import java.net.URI;
\r
30 import java.net.URISyntaxException;
\r
31 import java.net.UnknownHostException;
\r
32 import java.util.ArrayList;
\r
33 import java.util.List;
\r
34 import java.security.SecureRandom;
\r
35 import java.util.Timer;
\r
36 import java.util.TimerTask;
\r
38 import org.onap.aaf.cadi.Locator;
\r
39 import org.onap.aaf.cadi.LocatorException;
\r
41 import org.onap.aaf.inno.env.util.Split;
\r
43 public class PropertyLocator implements Locator<URI> {
\r
44 private final URI [] orig;
\r
45 private PLItem[] current;
\r
47 private final SecureRandom random;
\r
48 private URI[] resolved;
\r
49 private long lastRefreshed=0L;
\r
50 private long minRefresh;
\r
51 private long backgroundRefresh;
\r
53 public PropertyLocator(String locList) throws LocatorException {
\r
54 this(locList,10000L, 1000*60*20); // defaults, do not refresh more than once in 10 seconds, Refresh Locator every 20 mins.
\r
57 * comma delimited root url list
\r
60 * @throws LocatorException
\r
62 public PropertyLocator(String locList, long minRefreshMillis, long backgroundRefreshMillis) throws LocatorException {
\r
63 minRefresh = minRefreshMillis;
\r
64 backgroundRefresh = backgroundRefreshMillis;
\r
66 throw new LocatorException("No Location List given for PropertyLocator");
\r
68 String[] locarray = Split.split(',',locList);
\r
69 List<URI> uriList = new ArrayList<URI>();
\r
71 random = new SecureRandom();
\r
73 for(int i=0;i<locarray.length;++i) {
\r
75 int range = locarray[i].indexOf(":[");
\r
77 uriList.add(new URI(locarray[i]));
\r
79 int dash = locarray[i].indexOf('-',range+2);
\r
80 int brac = locarray[i].indexOf(']',dash+1);
\r
81 int start = Integer.parseInt(locarray[i].substring(range+2, dash));
\r
82 int end = Integer.parseInt(locarray[i].substring(dash+1, brac));
\r
83 for(int port=start;port<=end;++port) {
\r
84 uriList.add(new URI(locarray[i].substring(0, range+1)+port));
\r
87 } catch (NumberFormatException nf) {
\r
88 throw new LocatorException("Invalid URI format: " + locarray[i]);
\r
89 } catch (URISyntaxException e) {
\r
90 throw new LocatorException(e);
\r
93 orig = new URI[uriList.size()];
\r
94 uriList.toArray(orig);
\r
97 new Timer("PropertyLocator Refresh Timer",true).scheduleAtFixedRate(new TimerTask() {
\r
102 }, backgroundRefresh,backgroundRefresh);
\r
107 public URI get(Item item) throws LocatorException {
\r
108 synchronized(orig) {
\r
112 return resolved[((PLItem)item).idx];
\r
118 public Item first() throws LocatorException {
\r
119 return end>0?current[0]:null;
\r
123 public boolean hasItems() {
\r
128 public Item next(Item item) throws LocatorException {
\r
133 if((spot=(((PLItem)item).order+1))>=end)return null;
\r
134 return current[spot];
\r
139 public synchronized void invalidate(Item item) throws LocatorException {
\r
144 PLItem pli = (PLItem)item;
\r
146 for(i=0;i<end;++i) {
\r
147 if(pli==current[i])break;
\r
149 order = current[i].order;
\r
151 current[i]=current[i+1];
\r
152 current[i].order=order++;
\r
158 public Item best() throws LocatorException {
\r
159 if(current.length==0) {
\r
162 switch(current.length) {
\r
168 return current[Math.abs(random.nextInt())%current.length];
\r
173 public synchronized boolean refresh() {
\r
174 if(System.currentTimeMillis()>lastRefreshed) {
\r
176 List<URI> resolve = new ArrayList<URI>();
\r
178 for(int i = 0; i < orig.length ; ++i) {
\r
180 InetAddress ia[] = InetAddress.getAllByName(orig[i].getHost());
\r
183 for(int j=0;j<ia.length;++j) {
\r
185 Socket socket = new Socket();
\r
187 realname=ia[j].getCanonicalHostName();
\r
188 socket.connect(new InetSocketAddress(realname,o.getPort()),3000);
\r
189 if(socket.isConnected()) {
\r
201 } catch (IOException e) {
\r
203 if(!socket.isClosed()) {
\r
206 } catch (IOException e) {
\r
212 } catch (UnknownHostException | URISyntaxException e) {
\r
213 // Note: Orig Name already known as valid, based on constructor
\r
216 end=resolve.size();
\r
217 PLItem[] newCurrent;
\r
218 if(current==null || current.length!=end) {
\r
219 newCurrent = new PLItem[end];
\r
221 newCurrent = current;
\r
224 for(int i=0; i< end; ++i) {
\r
225 if(newCurrent[i]==null){
\r
226 newCurrent[i]=new PLItem(i);
\r
228 newCurrent[i].idx=newCurrent[i].order=i;
\r
231 synchronized(orig) {
\r
232 resolved = new URI[end];
\r
233 resolve.toArray(resolved);
\r
234 current = newCurrent;
\r
236 lastRefreshed = System.currentTimeMillis()+minRefresh;
\r
237 return !resolve.isEmpty();
\r
243 private class PLItem implements Item {
\r
244 public int idx,order;
\r
246 public PLItem(int i) {
\r
250 public String toString() {
\r
251 return "Item: " + idx + " order: " + order;
\r
255 public String toString() {
\r
256 StringBuilder sb = new StringBuilder();
\r
257 boolean first = true;
\r
258 for(URI uri : orig) {
\r
259 boolean isResolved=false;
\r
266 sb.append(uri.toString());
\r
268 for(URI u2 : resolved) {
\r
269 if(uri.equals(u2)) {
\r
274 sb.append(isResolved?"X]\n":" ]");
\r
277 return sb.toString();
\r
280 public void destroy() {
\r