/** * Single VDC constructor. */ public ObjectConfig(Protocol protocol, int port, String... hosts) { this(protocol, port, new Vdc(hosts)); }
@Override public boolean shouldVeto(Host host, Map<String, Object> requestProperties) { Vdc vdc = (Vdc) requestProperties.get(PROP_GEO_PINNED_VDC); return (vdc != null && host instanceof VdcHost && !vdc.equals(((VdcHost) host).getVdc())); } }
/** * Cloning constructor. */ public ObjectConfig(ObjectConfig<T> other) { this.protocol = other.protocol; // deep copy the VDCs to avoid two clients referencing the same host lists (SDK-122) this.vdcs = new ArrayList<Vdc>(); for (Vdc vdc : other.getVdcs()) { this.vdcs.add(new Vdc(vdc.getName(), vdc.getHosts())); } this.port = other.port; this.smartClient = other.smartClient; this.rootContext = other.rootContext; this.namespace = other.namespace; this.identity = other.identity; this.secretKey = other.secretKey; this.serverClockSkew = other.serverClockSkew; this.userAgent = other.userAgent; this.geoPinningEnabled = other.geoPinningEnabled; this.geoReadRetryFailover = other.geoReadRetryFailover; this.chunkedEncodingSize = other.chunkedEncodingSize; this.properties = new HashMap<String, Object>(other.properties); }
@Override public String getAsText() { Vdc vdc = (Vdc) getValue(); if (vdc.getHosts().isEmpty()) return ""; List<String> names = new ArrayList<>(); for (Host host : vdc.getHosts()) { names.add(host.getName()); } if (vdc.getName() == null || vdc.getName().equals(vdc.getHosts().get(0).getName())) { return SyncUtil.join(names, ","); } else { return String.format("%s(%s)", vdc.getName(), SyncUtil.join(names, ",")); } }
for (Iterator<VdcHost> vdcI = vdc.iterator(); vdcI.hasNext(); ) { VdcHost vdcHost = vdcI.next(); boolean hostPresent = false; log.info("host " + vdcHost.getName() + " was not in the updated node list; removing from VDC " + vdc.getName()); vdcI.remove(); log.info("adding host " + node.getName() + " to VDC " + vdc.getName()); vdc.getHosts().add(new VdcHost(vdc, node.getName()));
@Override public String stringFromValue(Object value) { if (value == null) return null; Vdc vdc = (Vdc) value; StringBuilder stringBuilder = new StringBuilder(); String separator = ""; for (Host host : vdc.getHosts()) { stringBuilder.append(separator).append(host.getName()); separator = ","; } return stringBuilder.toString(); } }
public Vdc withName(String name) { setName(name); return this; } }
public Vdc(String name, List<? extends Host> hosts) { this.name = name; this.hosts = createVdcHosts(hosts); }
@Override public int hashCode() { int result = super.hashCode(); result = 31 * result + getVdc().hashCode(); return result; }
@Override public ClientResponse handle(ClientRequest request) throws ClientHandlerException { // if there's no bucket, we don't need to pin the request (there's no write or read) String bucketName = (String) request.getProperties().get(S3Constants.PROPERTY_BUCKET_NAME); String objectKey = (String) request.getProperties().get(S3Constants.PROPERTY_OBJECT_KEY); if (bucketName != null) { List<Vdc> healthyVdcs = new ArrayList<Vdc>(); for (Vdc vdc : objectConfig.getVdcs()) { if (vdc.isHealthy()) healthyVdcs.add(vdc); } if (healthyVdcs.isEmpty()) { log.debug("there are no healthy VDCs; geo-pinning will include all VDCs"); healthyVdcs.addAll(objectConfig.getVdcs()); } int geoPinIndex = getGeoPinIndex(getGeoId(bucketName, objectKey), healthyVdcs.size()); // if this is a read and failover for retries is requested, round-robin the VDCs for each retry if (objectConfig.isGeoReadRetryFailover() && Method.GET.name().equalsIgnoreCase(request.getMethod())) { Integer retries = (Integer) request.getProperties().get(RetryFilter.PROP_RETRY_COUNT); if (retries != null) { int newIndex = (geoPinIndex + retries) % healthyVdcs.size(); log.info("geo-pin read retry #{}: failing over from primary VDC {} to VDC {}", retries, geoPinIndex, newIndex); geoPinIndex = newIndex; } } request.getProperties().put(GeoPinningRule.PROP_GEO_PINNED_VDC, healthyVdcs.get(geoPinIndex)); } return getNext().handle(request); }
public List<Host> getHostList() { if (vdcs == null || vdcs.isEmpty()) return getDataNodes(loadBalancer.getTopHost(null)); List<Host> hostList = new ArrayList<Host>(); for (Vdc vdc : vdcs) { if (vdc.getHosts().isEmpty()) log.warn("VDC " + vdc.getName() + " has no hosts!"); boolean success = false; for (Host host : vdc) { if (!host.isHealthy()) { // the load balancer manages health checks log.warn("not retrieving node list from " + host.getName() + " because it's unhealthy"); continue; } try { updateVdcNodes(vdc, getDataNodes(host)); success = true; break; } catch (Throwable t) { log.warn("unable to retrieve node list from " + host.getName(), t); } } if (!success) log.warn("could not retrieve node list for VDC " + vdc.getName()); hostList.addAll(vdc.getHosts()); } return hostList; }
@Override public Host resolveHost() { return getVdcs().get(0).getHosts().get(0); }
@ConfigUriProperty(type = ConfigUriProperty.Type.Host) public String getHost() { if (getVdcs() == null || getVdcs().isEmpty()) return null; return getVdcs().get(0).getHosts().get(0).getName(); }
@Override public int hashCode() { return getName().hashCode(); }
@Override public Object valueFromString(String param) { if (param == null) return null; return new Vdc(param.split(",")); }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof VdcHost)) return false; if (!super.equals(o)) return false; VdcHost vdcHost = (VdcHost) o; return getVdc().equals(vdcHost.getVdc()); }
public SmartConfig toSmartConfig() { List<Host> allHosts = new ArrayList<Host>(); for (Vdc vdc : vdcs) { allHosts.addAll(vdc.getHosts());
@Override public String toString() { return vdc.getName() + ":" + super.toString(); }