/*
* Copyright (c) 2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.security.geo;
import java.net.URI;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Properties;
import com.emc.storageos.security.helpers.ServiceClientRetryFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.coordinator.client.service.CoordinatorClient;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.VirtualDataCenter;
import com.emc.storageos.db.common.VdcUtil;
public class GeoClientCacheManager {
private static final int CLIENT_CONNECT_TIMEOUT = 30 * 1000;
private static final int CLIENT_READ_TIMEOUT = 30 * 1000;
private int _clientConnTimeout = CLIENT_CONNECT_TIMEOUT;
private int _clientReadTimeout = CLIENT_READ_TIMEOUT;
private static final Logger log = LoggerFactory.getLogger(GeoClientCacheManager.class);
private CoordinatorClient coordinatorClient;
private DbClient dbClient;
// TODO: ultimately we'll need a strategy for cache refresh
private ConcurrentHashMap<String, GeoServiceClient> clientCache = new ConcurrentHashMap<String, GeoServiceClient>();
public void setClientConnTimeout(int clientConnTimeout) {
_clientConnTimeout = clientConnTimeout;
}
public void setClientReadTimeout(int clientReadTimeout) {
_clientReadTimeout = clientReadTimeout;
}
public void setCoordinatorClient(CoordinatorClient coordinatorClient) {
this.coordinatorClient = coordinatorClient;
}
public void setDbClient(DbClient dbClient) {
this.dbClient = dbClient;
}
/**
* Clear the Client Cache (and the underlying dbClient URN cache)
*/
public void clearCache() {
VdcUtil.invalidateVdcUrnCache();
clientCache.clear();
}
public GeoServiceClient getGeoClient(String shortVdcId) {
GeoServiceClient client = null;
if (clientCache.containsKey(shortVdcId)) {
client = clientCache.get(shortVdcId);
log.info("returning existing cached client for vdc {}", shortVdcId);
} else {
client = createClient(lookupVdc(shortVdcId));
clientCache.put(shortVdcId, client);
log.info("returning new cached client for vdc {}", shortVdcId);
}
return client;
}
public GeoServiceClient getGeoClient(Properties vdcInfo) {
GeoServiceClient client = null;
String shortId = vdcInfo.getProperty(GeoServiceJob.VDC_SHORT_ID);
if (clientCache.containsKey(shortId)) {
client = clientCache.get(shortId);
log.info("returning existing cached client for vdc {}", shortId);
} else {
client = createClient(vdcInfo);
clientCache.put(shortId, client);
log.info("returning new cached client for vdc {}", shortId);
}
return client;
}
/**
* Remove this method once the ugly code needing to use a non-standard
* port in the add vdc flow is fixed
*
* @param shortVdcId
* @param nonSharedClient
* @return
*/
@Deprecated
public GeoServiceClient getNonSharedGeoClient(String shortVdcId) {
GeoServiceClient client = createClient(lookupVdc(shortVdcId));
log.info("returning non-shared client for {}", shortVdcId);
return client;
}
private VirtualDataCenter lookupVdc(String shortVdcId) {
// to refresh the cache in case it's called after a new VDC added.
dbClient.invalidateVdcUrnCache();
URI vdcURN = dbClient.getVdcUrn(shortVdcId);
// TODO: convert to the appropriate ViPR exception
if (vdcURN == null) {
throw new IllegalArgumentException("unknown vdc id " + shortVdcId);
}
VirtualDataCenter vdc = dbClient.queryObject(VirtualDataCenter.class, vdcURN);
// TODO: convert to the proper ViPR exception
if (vdc == null) {
throw new IllegalArgumentException("vdc does not exist: " + vdcURN);
}
return vdc;
}
private GeoServiceClient createClient(VirtualDataCenter vdc) {
GeoServiceClient client = new GeoServiceClient();
client.setCoordinatorClient(coordinatorClient);
client.setServer(vdc.getApiEndpoint());
client.setSecretKey(vdc.getSecretKey());
// set both timeout values to 30s due to CTRL-2779
client.setClientConnectTimeout(_clientConnTimeout);
client.setClientReadTimeout(_clientReadTimeout);
client.addFilter(new ServiceClientRetryFilter(client.getClientMaxRetries(), client.getClientRetryInterval()));
client.addFilter(new GeoServiceExceptionFilter());
return client;
}
private GeoServiceClient createClient(Properties vdcInfo) {
GeoServiceClient client = new GeoServiceClient();
client.setCoordinatorClient(coordinatorClient);
client.setServer(vdcInfo.getProperty(GeoServiceJob.VDC_API_ENDPOINT));
client.setSecretKey(vdcInfo.getProperty(GeoServiceJob.VDC_SECRETE_KEY));
// set both timeout values to 30s due to CTRL-2779
client.setClientConnectTimeout(_clientConnTimeout);
client.setClientReadTimeout(_clientReadTimeout);
client.addFilter(new ServiceClientRetryFilter(client.getClientMaxRetries(), client.getClientRetryInterval()));
client.addFilter(new GeoServiceExceptionFilter());
return client;
}
}