From 7d45c179879363222fcf49b30f75837f66d7f423 Mon Sep 17 00:00:00 2001 From: Varun Gudisena Date: Thu, 31 Aug 2017 10:44:28 -0500 Subject: Revert package name changes Reverted package name changes to avoid any potential issues. Renamed maven group id only. Issue-id: DMAAP-74 Change-Id: I36c2aef063050c265640b79e6dc0e8ab7add8d22 Signed-off-by: Varun Gudisena --- .../java/com/att/nsa/mr/client/HostSelector.java | 191 +++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 src/main/java/com/att/nsa/mr/client/HostSelector.java (limited to 'src/main/java/com/att/nsa/mr/client/HostSelector.java') diff --git a/src/main/java/com/att/nsa/mr/client/HostSelector.java b/src/main/java/com/att/nsa/mr/client/HostSelector.java new file mode 100644 index 0000000..de0e52c --- /dev/null +++ b/src/main/java/com/att/nsa/mr/client/HostSelector.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * ============LICENSE_START======================================================= + * org.onap.dmaap + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * + *******************************************************************************/ +package com.att.nsa.mr.client; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Random; +import java.util.Set; +import java.util.TreeSet; +import java.util.Vector; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HostSelector +{ + private final TreeSet fBaseHosts; + private final DelayQueue fBlacklist; + private String fIdealHost; + private String fCurrentHost; + private static final Logger log = LoggerFactory.getLogger(HostSelector.class); + + public HostSelector(String hostPart) + { + this(makeSet(hostPart), null); + } + + public HostSelector(Collection baseHosts) + { + this(baseHosts, null); + } + + public HostSelector(Collection baseHosts, String signature) + { + if (baseHosts.size() < 1) + { + throw new IllegalArgumentException("At least one host must be provided."); + } + + this.fBaseHosts = new TreeSet(baseHosts); + this.fBlacklist = new DelayQueue(); + this.fIdealHost = null; + + if (signature == null) { + return; + } + int index = Math.abs(signature.hashCode()) % baseHosts.size(); + + Iterator it = this.fBaseHosts.iterator(); + while (index-- > 0) + { + it.next(); + } + this.fIdealHost = ((String)it.next()); + } + + public String selectBaseHost() + { + if (this.fCurrentHost == null) + { + makeSelection(); + } + return this.fCurrentHost; + } + + public void reportReachabilityProblem(long blacklistUnit, TimeUnit blacklistTimeUnit) + { + if (this.fCurrentHost == null) + { + log.warn("Reporting reachability problem, but no host is currently selected."); + } + + if (blacklistUnit > 0L) + { + for (BlacklistEntry be : this.fBlacklist) + { + if (be.getHost().equals(this.fCurrentHost)) + { + be.expireNow(); + } + } + + LinkedList devNull = new LinkedList(); + this.fBlacklist.drainTo(devNull); + + if (this.fCurrentHost != null) + { + this.fBlacklist.add(new BlacklistEntry(this.fCurrentHost, TimeUnit.MILLISECONDS.convert(blacklistUnit, blacklistTimeUnit))); + } + } + this.fCurrentHost = null; + } + + private String makeSelection() + { + TreeSet workingSet = new TreeSet(this.fBaseHosts); + + LinkedList devNull = new LinkedList(); + this.fBlacklist.drainTo(devNull); + for (BlacklistEntry be : this.fBlacklist) + { + workingSet.remove(be.getHost()); + } + + if (workingSet.size() == 0) + { + log.warn("All hosts were blacklisted; reverting to full set of hosts."); + workingSet.addAll(this.fBaseHosts); + this.fCurrentHost = null; + } + + String selection = null; + if ((this.fCurrentHost != null) && (workingSet.contains(this.fCurrentHost))) + { + selection = this.fCurrentHost; + } + else if ((this.fIdealHost != null) && (workingSet.contains(this.fIdealHost))) + { + selection = this.fIdealHost; + } + else + { + Vector v = new Vector(workingSet); + int index = Math.abs(new Random().nextInt()) % workingSet.size(); + selection = (String)v.elementAt(index); + } + + this.fCurrentHost = selection; + return this.fCurrentHost; + } + + private static Set makeSet(String s) + { + TreeSet set = new TreeSet(); + set.add(s); + return set; } + + private static class BlacklistEntry implements Delayed { + private final String fHost; + private long fExpireAtMs; + + public BlacklistEntry(String host, long delayMs) { + this.fHost = host; + this.fExpireAtMs = (System.currentTimeMillis() + delayMs); + } + + public void expireNow() + { + this.fExpireAtMs = 0L; + } + + public String getHost() + { + return this.fHost; + } + + public int compareTo(Delayed o) + { + Long thisDelay = Long.valueOf(getDelay(TimeUnit.MILLISECONDS)); + return thisDelay.compareTo(Long.valueOf(o.getDelay(TimeUnit.MILLISECONDS))); + } + + public long getDelay(TimeUnit unit) + { + long remainingMs = this.fExpireAtMs - System.currentTimeMillis(); + return unit.convert(remainingMs, TimeUnit.MILLISECONDS); + } + } +} -- cgit 1.2.3-korg