X-Git-Url: https://gerrit.onap.org/r/gitweb?p=aaf%2Fauthz.git;a=blobdiff_plain;f=cadi%2Faaf%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fcadi%2Faaf%2Fv2_0%2FAbsAAFLocator.java;h=a654e6f6b7817c6883395d77a5412c2c166ac578;hp=ab0f595c020ecc35d680d6bca5d44aa8e80d8dec;hb=07fb3ece74a9aa1fad8e2a9fab73b4de3e36853b;hpb=b126c6c5f625432722405538692184f5c74edaad diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java index ab0f595c..a654e6f6 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java @@ -23,6 +23,7 @@ package org.onap.aaf.cadi.aaf.v2_0; import java.net.URI; import java.net.URISyntaxException; +import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Iterator; @@ -32,10 +33,11 @@ import java.util.NoSuchElementException; import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.Locator; import org.onap.aaf.cadi.LocatorException; import org.onap.aaf.cadi.config.Config; -import org.onap.aaf.cadi.locator.PropertyLocator; +import org.onap.aaf.cadi.config.RegistrationPropHolder; import org.onap.aaf.cadi.routing.GreatCircle; import org.onap.aaf.misc.env.Trans; import org.onap.aaf.misc.env.util.Split; @@ -43,459 +45,437 @@ import org.onap.aaf.misc.env.util.Split; import locate.v1_0.Endpoint; public abstract class AbsAAFLocator implements Locator { - protected static final SecureRandom sr = new SecureRandom(); - private static LocatorCreator locatorCreator; - protected final Access access; - - protected final double latitude; - protected final double longitude; - protected List epList; - protected final String name, version; - private String pathInfo = null; - private String query = null; - private String fragment = null; - private boolean additional = false; - protected String myhostname; - protected int myport; - protected final String aaf_locator_host; - private long earliest; - private final long refreshWait; - - - public AbsAAFLocator(Access access, String name, final long refreshMin) throws LocatorException { - aaf_locator_host = access.getProperty(Config.AAF_LOCATE_URL, null); - - epList = new LinkedList(); - refreshWait = refreshMin; - - this.access = access; - String lat = access.getProperty(Config.CADI_LATITUDE,null); - String lng = access.getProperty(Config.CADI_LONGITUDE,null); - if(lat==null || lng==null) { - throw new LocatorException(Config.CADI_LATITUDE + " and " + Config.CADI_LONGITUDE + " properties are required."); - } else { - latitude = Double.parseDouble(lat); - longitude = Double.parseDouble(lng); - } - if(name.startsWith("http")) { // simple URL - this.name = name; - this.version = Config.AAF_DEFAULT_VERSION; - } else { - String[] split = Split.split(':', name); - - switch(split.length) { - case 1: - this.name = split[0]; - this.version = Config.AAF_DEFAULT_VERSION; - break; - case 0: - this.name = name; - this.version = Config.AAF_DEFAULT_VERSION; - break; - default: - this.version = split[1]; - this.name = split[0]; - - } - } - - } - - /** - * This is the way to setup specialized AAFLocators ahead of time. - * @param preload - */ - public static void setCreator(LocatorCreator lc) { - locatorCreator = lc; - } - - public static Locator create(String key) throws LocatorException { - String name = null; - String version = Config.AAF_DEFAULT_VERSION; - String pathInfo = null; - int prev = key.indexOf("/locate"); - if(prev>0) { - prev = key.indexOf('/',prev+6); - if(prev>0) { - int next = key.indexOf('/',++prev); - if(next>0) { - name = key.substring(prev, next); - pathInfo=key.substring(next); - } else { - name = key.substring(prev); - } - String[] split = Split.split(':', name); - switch(split.length) { - case 3: - case 2: - version = split[1]; - name = split[0]; - break; - } - } - } - - if(key.startsWith("http")) { - if(name!=null) { - if(locatorCreator != null) { - if(name!=null) { - AbsAAFLocator aal = locatorCreator.create(name, version); - if(pathInfo!=null) { - aal.setPathInfo(pathInfo); - } - return aal; - } - } - } else { - return new PropertyLocator(key); - } - } - return null; - } - - public static Locator create(final String name, final String version) throws LocatorException { - return locatorCreator.create(name, version); - } - - public interface LocatorCreator { - public AbsAAFLocator create(String key, String version) throws LocatorException; - public void setSelf(String hostname, int port); - } - - protected static String nameFromLocatorURI(URI locatorURI) { - String[] path = Split.split('/', locatorURI.getPath()); - if(path.length>2 && "locate".equals(path[1])) { - return path[2]; - } else { - return locatorURI.toString(); - } - } - - /** - * Setting "self" excludes this service from the list. Critical for contacting peers. - */ - public void setSelf(final String hostname, final int port) { - myhostname=hostname; - myport=port; - } - - - public static void setCreatorSelf(final String hostname, final int port) { - if(locatorCreator!=null) { - locatorCreator.setSelf(hostname,port); - } - } - - protected final synchronized void replace(List list) { - epList = list; - } - - /** - * Call _refresh as needed during calls, but actual refresh will not occur if there - * are existing entities or if it has been called in the last 10 (settable) seconds. - * Timed Refreshes happen by Scheduled Thread - */ - private final boolean _refresh() { - boolean rv = false; - long now=System.currentTimeMillis(); - if(noEntries()) { - if(earliest iter = epList.iterator(); iter.hasNext(); ) { - EP ep = iter.next(); - if(ep.valid) { - return true; - } - } - isEmpty = true; - } - if(_refresh()) { // is refreshed... check again - isEmpty = epList.isEmpty(); - } - return !isEmpty; - } - - @Override - public void invalidate(Item item) throws LocatorException { - if(item!=null) { - if(item instanceof AAFLItem) { - AAFLItem ali =(AAFLItem)item; - EP ep = ali.ep; - synchronized(epList) { - epList.remove(ep); - } - ep.invalid(); - ali.iter = getIterator(); // for next guy... fresh iterator - } else { - throw new LocatorException(item.getClass().getName() + " does not belong to AAFLocator"); - } - } - } - - @Override - public Item best() throws LocatorException { - if(!hasItems()) { - throw new LocatorException("No Entries found" + (pathInfo==null?"":(" for " + pathInfo))); - } - List lep = new ArrayList(); - EP first = null; - // Note: Deque is sorted on the way by closest distance - Iterator iter = getIterator(); - EP ep; - while(iter.hasNext()) { - ep = iter.next(); - if(ep.valid) { - if(first==null) { - first = ep; - lep.add(first); - } else { - if(Math.abs(ep.distance-first.distance)<.1) { // allow for nearby/precision issues. - lep.add(ep); - } else { - break; - } - } - } - } - switch(lep.size()) { - case 0: - return null; - case 1: - return new AAFLItem(iter,first); - default: - int rand = sr.nextInt(); // Sonar chokes without. - int i = Math.abs(rand)%lep.size(); - if(i<0) { - return null; - } else { - return new AAFLItem(iter,lep.get(i)); - } - - } - } - - private Iterator getIterator() { - Object[] epa = epList.toArray(); - if(epa.length==0) { - _refresh(); - epa = epList.toArray(); - } - return new EPIterator(epa, epList); - } - - public class EPIterator implements Iterator { - private final Object[] epa; - private final List epList; - private int idx; - - public EPIterator(Object[] epa, List epList) { - this.epa = epa; - this.epList = epList; - idx = epa.length>0?0:-1; - } - - @Override - public boolean hasNext() { - if(idx<0) { - return false; - } else { - Object obj; - while(idx=0 && idx iter = getIterator(); - EP ep = AAFLItem.next(iter); - if(ep==null) { - return null; - } - return new AAFLItem(iter,ep); - } - - @Override - public Item next(Item prev) throws LocatorException { - if(prev==null) { - StringBuilder sb = new StringBuilder("Locator Item passed in next(item) is null."); - int lines = 0; - for(StackTraceElement st : Thread.currentThread().getStackTrace()) { - sb.append("\n\t"); - sb.append(st.toString()); - if(++lines > 5) { - sb.append("\n\t..."); - break; - } - } - access.log(Level.ERROR, sb); - } else { - if(prev instanceof AAFLItem) { - AAFLItem ali = (AAFLItem)prev; - EP ep = AAFLItem.next(ali.iter); - if(ep!=null) { - return new AAFLItem(ali.iter,ep); - } - } else { - throw new LocatorException(prev.getClass().getName() + " does not belong to AAFLocator"); - } - } - return null; - } - - protected static class AAFLItem implements Item { - private Iterator iter; - private URI uri; - private EP ep; - - public AAFLItem(Iterator iter, EP ep) { - this.iter = iter; - this.ep = ep; - uri = ep.uri; - } - - private static EP next(Iterator iter) { - EP ep=null; - while(iter.hasNext() && (ep==null || !ep.valid)) { - ep = iter.next(); - } - return ep; - } - - public String toString() { - return ep==null?"Locator Item Invalid":ep.toString(); - } - } - - protected static class EP implements Comparable { - public URI uri; - public final double distance; - private boolean valid; - - public EP(final Endpoint ep, double latitude, double longitude) throws URISyntaxException { - uri = new URI(ep.getProtocol(),null,ep.getHostname(),ep.getPort(),null,null,null); - distance = GreatCircle.calc(latitude, longitude, ep.getLatitude(), ep.getLongitude()); - valid = true; - } - - public void invalid() { - valid = false; - } - - @Override - public int compareTo(EP o) { - if(distanceo.distance) { - return 1; - } else { - return 0; - } - } - - @Override - public String toString() { - return distance + ": " + uri + (valid?" valid":" invalidate"); - } - } - - /* (non-Javadoc) - * @see org.onap.aaf.cadi.Locator#destroy() - */ - @Override - public void destroy() { - // Nothing to do - } - - @Override - public String toString() { - return "AAFLocator for " + name + " on " + getURI(); - } - - public AbsAAFLocator setPathInfo(String pathInfo) { - this.pathInfo = pathInfo; - additional=true; - return this; - } - - public AbsAAFLocator setQuery(String query) { - this.query = query; - additional=true; - return this; - } - - public AbsAAFLocator setFragment(String fragment) { - this.fragment = fragment; - additional=true; - return this; - } - - // Core URI, for reporting purposes - protected abstract URI getURI(); - - protected URI getURI(URI rv) throws LocatorException { - if(additional) { - try { - return new URI(rv.getScheme(),rv.getUserInfo(),rv.getHost(),rv.getPort(),pathInfo,query,fragment); - } catch (URISyntaxException e) { - throw new LocatorException("Error coping URL"); - } - } - return rv; - } + protected static final SecureRandom sr = new SecureRandom(); + private static LocatorCreator locatorCreator; + protected final Access access; + + protected final double latitude; + protected final double longitude; + protected List epList; + protected final String name, version; + private String pathInfo = null; + private String query = null; + private String fragment = null; + private boolean additional = false; + protected String myhostname; + protected int myport; + protected final String aaf_locator_host; + protected URI aaf_locator_uri; + private long earliest; + private final long refreshWait; + + + public AbsAAFLocator(Access access, String name, final long refreshMin) throws LocatorException { + RegistrationPropHolder rph; + try { + rph = new RegistrationPropHolder(access, 0); + } catch (UnknownHostException | CadiException e1) { + throw new LocatorException(e1); + } + URI aaf_locator_uri; + try { + aaf_locator_host = rph.replacements(getClass().getSimpleName(),"https://"+Config.AAF_LOCATE_URL_TAG,null,null); + if(aaf_locator_host.endsWith("/locate")) { + aaf_locator_uri = new URI(aaf_locator_host); + } else { + aaf_locator_uri = new URI(aaf_locator_host+"/locate"); + } + access.printf(Level.INFO, "AbsAAFLocator AAF URI is %s",aaf_locator_uri); + } catch (URISyntaxException e) { + throw new LocatorException(e); + } + + name = rph.replacements(getClass().getSimpleName(),name, null,null); + access.printf(Level.INFO, "AbsAAFLocator name is %s",aaf_locator_uri); + + epList = new LinkedList<>(); + refreshWait = refreshMin; + + this.access = access; + String lat = access.getProperty(Config.CADI_LATITUDE,null); + String lng = access.getProperty(Config.CADI_LONGITUDE,null); + if (lat==null || lng==null) { + throw new LocatorException(Config.CADI_LATITUDE + " and " + Config.CADI_LONGITUDE + " properties are required."); + } else { + latitude = Double.parseDouble(lat); + longitude = Double.parseDouble(lng); + } + + + if (name.startsWith("http")) { // simple URL + this.name = name; + this.version = access.getProperty(Config.AAF_API_VERSION,Config.AAF_DEFAULT_API_VERSION); + } else { + String[] split = Split.split(':', name); + this.name = split[0]; + this.version = (split.length > 1) ? split[1] : access.getProperty(Config.AAF_API_VERSION,Config.AAF_DEFAULT_API_VERSION); + } + } + + /** + * This is the way to setup specialized AAFLocators ahead of time. + * @param preload + */ + public static void setCreator(LocatorCreator lc) { + locatorCreator = lc; + } + + public static Locator create(final String name, final String version) throws LocatorException { + if(locatorCreator==null) { + throw new LocatorException("LocatorCreator is not set"); + } + return locatorCreator.create(name, version); + } + + public interface LocatorCreator { + public AbsAAFLocator create(String key, String version) throws LocatorException; + public void setSelf(String hostname, int port); + } + + protected static String nameFromLocatorURI(URI locatorURI) { + String[] path = Split.split('/', locatorURI.getPath()); + if (path.length>1 && "locate".equals(path[1])) { + return path[2]; + } else if(path.length>1) { + return path[1]; + } else { + return locatorURI.toString(); + } + } + + /** + * Setting "self" excludes this service from the list. Critical for contacting peers. + */ + public void setSelf(final String hostname, final int port) { + myhostname=hostname; + myport=port; + } + + + public static void setCreatorSelf(final String hostname, final int port) { + if (locatorCreator!=null) { + locatorCreator.setSelf(hostname,port); + } + } + + protected final synchronized void replace(List list) { + epList = list; + } + + /** + * Call _refresh as needed during calls, but actual refresh will not occur if there + * are existing entities or if it has been called in the last 10 (settable) seconds. + * Timed Refreshes happen by Scheduled Thread + */ + private final boolean _refresh() { + boolean rv = false; + long now=System.currentTimeMillis(); + if (noEntries()) { + if (earliest iter = epList.iterator(); iter.hasNext(); ) { + EP ep = iter.next(); + if (ep.valid) { + return true; + } + } + isEmpty = true; + } + if (_refresh()) { // is refreshed... check again + isEmpty = epList.isEmpty(); + } + return !isEmpty; + } + + @Override + public void invalidate(Item item) throws LocatorException { + if (item!=null) { + if (item instanceof AAFLItem) { + AAFLItem ali =(AAFLItem)item; + EP ep = ali.ep; + synchronized(epList) { + epList.remove(ep); + } + ep.invalid(); + ali.iter = getIterator(); // for next guy... fresh iterator + } else { + throw new LocatorException(item.getClass().getName() + " does not belong to AAFLocator"); + } + } + } + + @Override + public Item best() throws LocatorException { + if (!hasItems()) { + throw new LocatorException(String.format("No Entries found for '%s/%s:%s'", + (aaf_locator_uri==null?aaf_locator_host:aaf_locator_uri.toString()), + name, + version)); + } + List lep = new ArrayList<>(); + EP first = null; + // Note: Deque is sorted on the way by closest distance + Iterator iter = getIterator(); + EP ep; + while (iter.hasNext()) { + ep = iter.next(); + if (ep.valid) { + if (first==null) { + first = ep; + lep.add(first); + } else { + if (Math.abs(ep.distance-first.distance)<.1) { // allow for nearby/precision issues. + lep.add(ep); + } else { + break; + } + } + } + } + switch(lep.size()) { + case 0: + return null; + case 1: + return new AAFLItem(iter,first); + default: + int rand = sr.nextInt(); // Sonar chokes without. + int i = Math.abs(rand)%lep.size(); + if (i<0) { + return null; + } else { + return new AAFLItem(iter,lep.get(i)); + } + + } + } + + private Iterator getIterator() { + Object[] epa = epList.toArray(); + if (epa.length==0) { + _refresh(); + epa = epList.toArray(); + } + return new EPIterator(epa, epList); + } + + public class EPIterator implements Iterator { + private final Object[] epa; + private final List epList; + private int idx; + + public EPIterator(Object[] epa, List epList) { + this.epa = epa; + this.epList = epList; + idx = epa.length>0?0:-1; + } + + @Override + public boolean hasNext() { + if (idx<0) { + return false; + } else { + Object obj; + while (idx=0 && idx iter = getIterator(); + EP ep = AAFLItem.next(iter); + if (ep==null) { + return null; + } + return new AAFLItem(iter,ep); + } + + @Override + public Item next(Item prev) throws LocatorException { + if (prev==null) { + StringBuilder sb = new StringBuilder("Locator Item passed in next(item) is null."); + int lines = 0; + for (StackTraceElement st : Thread.currentThread().getStackTrace()) { + sb.append("\n\t"); + sb.append(st.toString()); + if (++lines > 5) { + sb.append("\n\t..."); + break; + } + } + access.log(Level.ERROR, sb); + } else { + if (prev instanceof AAFLItem) { + AAFLItem ali = (AAFLItem)prev; + EP ep = AAFLItem.next(ali.iter); + if (ep!=null) { + return new AAFLItem(ali.iter,ep); + } + } else { + throw new LocatorException(prev.getClass().getName() + " does not belong to AAFLocator"); + } + } + return null; + } + + protected static class AAFLItem implements Item { + private Iterator iter; + private URI uri; + private EP ep; + + public AAFLItem(Iterator iter, EP ep) { + this.iter = iter; + this.ep = ep; + uri = ep.uri; + } + + private static EP next(Iterator iter) { + EP ep=null; + while (iter.hasNext() && (ep==null || !ep.valid)) { + ep = iter.next(); + } + return ep; + } + + public String toString() { + return ep==null?"Locator Item Invalid":ep.toString(); + } + } + + protected static class EP implements Comparable { + private URI uri; + private final double distance; + private boolean valid; + + public EP(final Endpoint ep, double latitude, double longitude) throws URISyntaxException { + uri = new URI(ep.getProtocol(),null,ep.getHostname(),ep.getPort(),null,null,null); + distance = GreatCircle.calc(latitude, longitude, ep.getLatitude(), ep.getLongitude()); + valid = true; + } + + public void invalid() { + valid = false; + } + + @Override + public int compareTo(EP o) { + if (distanceo.distance) { + return 1; + } else { + return 0; + } + } + + @Override + public String toString() { + return distance + ": " + uri + (valid?" valid":" invalidate"); + } + } + + /* (non-Javadoc) + * @see org.onap.aaf.cadi.Locator#destroy() + */ + @Override + public void destroy() { + // Nothing to do + } + + @Override + public String toString() { + return "AAFLocator for " + name + " on " + getURI(); + } + + public AbsAAFLocator setPathInfo(String pathInfo) { + this.pathInfo = pathInfo; + additional=true; + return this; + } + + public AbsAAFLocator setQuery(String query) { + this.query = query; + additional=true; + return this; + } + + public AbsAAFLocator setFragment(String fragment) { + this.fragment = fragment; + additional=true; + return this; + } + + // Core URI, for reporting purposes + protected abstract URI getURI(); + + protected URI getURI(URI rv) throws LocatorException { + if (additional) { + try { + return new URI(rv.getScheme(),rv.getUserInfo(),rv.getHost(),rv.getPort(),pathInfo,query,fragment); + } catch (URISyntaxException e) { + throw new LocatorException("Error copying URL", e); + } + } + return rv; + } + + protected void clear() { + epList.clear(); + earliest=0L; + } }