com.att.aft.dme2.manager.registry.DME2EndpointRegistryFS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dme2-api Show documentation
Show all versions of dme2-api Show documentation
Direct Messaging Engine dme2-api
The newest version!
package com.att.aft.dme2.manager.registry;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.collections.CollectionUtils;
import com.att.aft.dme2.api.DME2Exception;
import com.att.aft.dme2.config.DME2Configuration;
import com.att.aft.dme2.iterator.domain.DME2RouteOffer;
import com.att.aft.dme2.logging.LogMessage;
import com.att.aft.dme2.logging.Logger;
import com.att.aft.dme2.logging.LoggerFactory;
import com.att.aft.dme2.manager.registry.util.DME2DistanceUtil;
import com.att.aft.dme2.manager.registry.util.DME2FileUtil;
import com.att.aft.dme2.manager.registry.util.DME2Protocol;
import com.att.aft.dme2.manager.registry.util.Version;
import com.att.aft.dme2.request.DmeUniformResource;
import com.att.aft.dme2.types.RouteInfo;
import com.att.aft.dme2.util.DME2Constants;
import com.att.aft.dme2.util.DME2URIUtils;
import com.att.aft.dme2.util.DME2ValidationUtil;
import com.att.aft.dme2.util.ErrorContext;
import com.att.scld.grm.types.v1.ClientJVMInstance;
/**
* DME2 Endpoint Registry for File Systems
*/
public class DME2EndpointRegistryFS extends DME2AbstractEndpointRegistry implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(DME2EndpointRegistryFS.class);
protected static final long DEFAULT_CACHE_STALENESS = 60 * 1000 * 5;
protected static final String CONFIG_KEY_FILE = "AFT_DME2_EP_REGISTRY_FS_DIR";
protected static final String HTTP_PREFIX = "http://";
protected static final String FORWARD_SLASH = "/";
protected static final String HOST_PORT_SEPARATOR = ":";
protected DME2EndpointCacheFS endpointCache;
public DME2EndpointCacheFS getEndpointCache() {
return endpointCache;
}
protected DME2RouteInfoCacheFS routeInfoCache;
public DME2RouteInfoCacheFS getRouteInfoCache() {
return routeInfoCache;
}
private Unmarshaller unmarshaller;
private boolean isMarshalling = false;
private static final String SCHEMA_NAMESPACE = "com.att.aft.dme2.types";
/**
* The last update time ms map.
*/
private final Map lastUpdateTimeMsMap = Collections.synchronizedMap(new HashMap());
private File dir;
private final List localPublishedList = new CopyOnWriteArrayList();
/**
* Basic constructor
*
* @param config
* DME2Configuration
* @param managerName
* Manager Name
* @throws DME2Exception
*/
public DME2EndpointRegistryFS(DME2Configuration config, String managerName) throws DME2Exception {
super(config, managerName);
endpointCache = new DME2EndpointCacheFS(config, this, managerName, false);
routeInfoCache = new DME2RouteInfoCacheFS(config, this, managerName);
staleEndpointCache = new DME2StaleCache(config, DME2Endpoint.class, DME2EndpointRegistryType.FileSystem, this,
managerName);
staleRouteOfferCache = new DME2StaleCache(config, DME2RouteOffer.class, DME2EndpointRegistryType.FileSystem,
this, managerName);
if (unmarshaller == null) {
unmarshaller = createUnmarshaller();
}
}
private Unmarshaller createUnmarshaller() throws DME2Exception {
JAXBContext jaxBContext;
try {
jaxBContext = JAXBContext.newInstance(SCHEMA_NAMESPACE);
} catch (JAXBException e) {
throw new DME2Exception("AFT-DME2-1550",
new ErrorContext().add("extendedMessage", e.getMessage()).add("manager", managerName), e);
}
try {
return jaxBContext.createUnmarshaller();
} catch (JAXBException e) {
throw new DME2Exception("AFT-DME2-1551",
new ErrorContext().add("extendedMessage", e.getMessage()).add("manager", managerName), e);
}
}
/**
* {@inheritDoc}
*
* @param properties
* Properties to use in initialization
* @throws DME2Exception
*/
@Override
public void init(Properties properties) throws DME2Exception {
super.init(properties);
String fileName = getConfig().getProperty(CONFIG_KEY_FILE);
if (fileName == null) {
fileName = "dme2-fs-registry";
}
dir = new File(fileName);
if (!dir.exists()) {
dir.mkdirs();
}
Runtime.getRuntime().addShutdownHook(new Thread(this));
}
/**
* {@inheritDoc}
*
* @param serviceName
* Service name
* @param serviceVersion
* Service version
* @param envContext
* Environment context
* @param routeOffer
* Route offer
* @return List of DME2 Endpoints
* @throws DME2Exception
*/
@Override
public List findEndpoints(String serviceName, String serviceVersion, String envContext,
String routeOffer) throws DME2Exception {
// Build service string
String service = DME2URIUtils.buildServiceURIString(serviceName, serviceVersion, envContext, routeOffer);
DME2FileHandler fileHandler = new DME2FileHandler(dir, service, DEFAULT_CACHE_STALENESS, getClientLatitude(),
getClientLongitude());
Long sourceLastUpdateTimeMs = lastUpdateTimeMsMap.get(service);
List endpoints = null;
if (sourceLastUpdateTimeMs == null || sourceLastUpdateTimeMs >= fileHandler.getLastModified()) {
endpoints = endpointCache.getEndpoints(service);
}
if (endpoints == null || endpoints.isEmpty()) {
endpoints = fetchEndpointsFromSource(fileHandler);
endpointCache.putEndpoints(service, endpoints);
lastUpdateTimeMsMap.put(service, fileHandler.getLastModified());
}
return endpoints;
}
/**
* {@inheritDoc}
*
* @param serviceName
* Service name
* @param serviceVersion
* Service version
* @param envContext
* Environment context
* @return DME2 Route Info
* @throws DME2Exception
*/
@Override
public DME2RouteInfo getRouteInfo(String serviceName, String serviceVersion, String envContext)
throws DME2Exception {
String path = DME2URIUtils.buildServiceURIString(serviceName, serviceVersion, envContext);
File file = new File(dir, path + "/routeInfo.xml");
DME2RouteInfo routeInfo = routeInfoCache.get(path);
if (routeInfo == null || routeInfo.lastUpdated() < file.lastModified()) {
routeInfo = fetchRouteInfoFromSource(path);
routeInfoCache.put(path, routeInfo);
}
return routeInfo;
}
private List fetchEndpointsFromSource(DME2FileHandler fileHandler) throws DME2Exception {
return fileHandler.readEndpoints();
}
protected List fetchEndpointsFromSource(String service) throws DME2Exception {
return fetchEndpointsFromSource(
new DME2FileHandler(dir, service, DEFAULT_CACHE_STALENESS, getClientLatitude(), getClientLongitude()));
}
protected DME2RouteInfo fetchRouteInfoFromSource(String path) throws DME2Exception {
JAXBElement element = null;
// SCLD-4879 - Hierarchical version lookup
List matchingFiles = DME2FileUtil.hierarchicalFileLookup(dir, path + "/routeInfo.xml");
Map routeInfoMap = new HashMap();
for (File file : matchingFiles) {
element = readRouteInfo(file);
routeInfoMap.put(new Version(element.getValue().getServiceVersion()),
new DME2RouteInfo(element.getValue(), getConfig()));
}
ArrayList sortedVersionList = new ArrayList(routeInfoMap.keySet());
Collections.sort(sortedVersionList);
if (sortedVersionList.isEmpty()) {
throw new DME2Exception(DME2Constants.EXP_REG_ROUTE_INFO_FILE_NOT_FOUND,
new ErrorContext().add("path", path).add("path", path));
} else {
return routeInfoMap.get(sortedVersionList.get(0));
}
}
// Marshalling is NOT thread safe!! If no one is using the already-created unmarshaller, go ahead and use it, but
// make sure everyone knows that it is in use. If it is already in use, create a new one.
protected synchronized JAXBElement readRouteInfo(File file) throws DME2Exception {
boolean isMarshallingWasSet = false;
try {
Unmarshaller currentUnmarshaller;
if ( !isMarshalling ) {
isMarshalling = true;
isMarshallingWasSet = true;
currentUnmarshaller = unmarshaller;
} else {
currentUnmarshaller = createUnmarshaller();
}
StreamSource ss = new StreamSource( file );
return (JAXBElement) currentUnmarshaller.unmarshal( ss );
} catch (JAXBException e) {
throw new DME2Exception("AFT-DME2-1552", new ErrorContext().add("extendedMessage", e.getMessage()), e);
} finally {
if ( isMarshallingWasSet ) isMarshalling = false;
}
}
/**
* {@inheritDoc}
*
* @param service
* Service name
* @param path
* Service path
* @param host
* Service host
* @param port
* Service port
* @param latitude
* Service location latitude
* @param longitude
* Service location longitude
* @param protocol
* Service access protocol
* @throws DME2Exception
*/
@Override
public void publish(String service, String path, String host, int port, double latitude, double longitude,
String protocol) throws DME2Exception {
publish(service, path, host, port, latitude, longitude, protocol, null);
}
/**
* {@inheritDoc}
*
* @param service
* Service name
* @param path
* Service path
* @param host
* Service host
* @param port
* Service port
* @param latitude
* Service location latitude
* @param longitude
* Service location longitude
* @param protocol
* Service access protocol
* @param updateLease
* Whether to renew the service lease
* @throws DME2Exception
*/
@Override
public void publish(String service, String path, String host, int port, double latitude, double longitude,
String protocol, boolean updateLease) throws DME2Exception {
publish(service, path, host, port, latitude, longitude, protocol, null);
}
/**
* {@inheritDoc}
*
* @param service
* Service name
* @param path
* Service path
* @param host
* Service host
* @param port
* Service port
* @param protocol
* Service access protocol
* @param props
* Service Properties
* @throws DME2Exception
*/
@Override
public void publish(String service, String path, String host, int port, String protocol, Properties props)
throws DME2Exception {
publish(service, path, host, port, getConfig().getDouble("AFT_LATITUDE"),
getConfig().getDouble("AFT_LONGITUDE"), protocol, props);
}
/**
* {@inheritDoc}
*
* @param service
* Service name
* @param path
* Service path
* @param host
* Service host
* @param port
* Service port
* @param protocol
* Service access protocol
* @throws DME2Exception
*/
@Override
public void publish(String service, String path, String host, int port, String protocol) throws DME2Exception {
publish(service, path, host, port, getConfig().getDouble("AFT_LATITUDE"),
getConfig().getDouble("AFT_LONGITUDE"), protocol, null);
}
@Override
public void publish(String serviceURI, String contextPath, String hostAddress, int port, double latitude,
double longitude, String protocol, Properties props, boolean updateLease) throws DME2Exception {
publish(serviceURI, contextPath, hostAddress, port, latitude, longitude, protocol, props);
}
/**
* {@inheritDoc}
*
* @param service
* Service name
* @param path
* Service path
* @param host
* Service host
* @param port
* Service port
* @param protocol
* Service access protocol
* @param updateLease
* Whether to renew the service lease
* @throws DME2Exception
*/
@Override
public void publish(String service, String path, String host, int port, String protocol, boolean updateLease)
throws DME2Exception {
publish(service, path, host, port, getConfig().getLong("AFT_LATITUDE"), getConfig().getLong("AFT_LONGITUDE"),
protocol, null);
}
private void publish(String servicePath, String contextPath, String host, int port, double latitude,
double longitude, String protocol, Properties inProps) throws DME2Exception {
String urlStr = null;
double distance = DME2DistanceUtil.calculateDistanceBetween(getClientLatitude(), getClientLongitude(), latitude,
longitude);
DmeUniformResource uniformResource = buildUniformResource(protocol, servicePath, host, port);
int queryIndexStart;
if ((queryIndexStart = servicePath.indexOf('?')) != -1) {
servicePath = servicePath.substring(0, queryIndexStart);
}
String serviceContext = "service=" + uniformResource.getService() + "/version=" + uniformResource.getVersion()
+ "/envContext=" + uniformResource.getEnvContext() + "/routeOffer=" + uniformResource.getRouteOffer();
DME2FileHandler fileHandler = new DME2FileHandler(dir, serviceContext, DEFAULT_CACHE_STALENESS,
getClientLatitude(), getClientLongitude());
logger.debug(null, "publish", LogMessage.PUBLISH_FILE, serviceContext + ".txt");
Properties props = fileHandler.readProperties();
String propsKey = host + "," + port;
props.setProperty(propsKey,
"latitude=" + latitude + ";longitude=" + longitude + ";lease=" + System.currentTimeMillis()
+ ";protocol=" + protocol + ";contextPath=" + (contextPath == null ? servicePath : contextPath)
+ ";routeOffer=" + uniformResource.getRouteOffer());
DME2Endpoint ep = null;
if (DME2Protocol.DME2JDBC.equals(protocol)) {
try {
DME2ValidationUtil.validateJDBCEndpointRequiredFields(inProps, servicePath);
} catch (DME2Exception e) {
throw new DME2Exception(e.getErrorCode(), e.getErrorMessage());
}
// ep = new DME2JDBCEndpoint(this.getManager());
ep = new DME2JDBCEndpoint(distance);
if (inProps != null) {
StringBuffer buff = new StringBuffer();
if (inProps.containsKey(DME2Constants.KEY_DME2_JDBC_DATABASE_NAME)) {
((DME2JDBCEndpoint) ep)
.setDatabaseName((String) props.get(DME2Constants.KEY_DME2_JDBC_DATABASE_NAME));
buff.append("DME2JDBCDatabaseName=" + inProps.get(DME2Constants.KEY_DME2_JDBC_DATABASE_NAME) + ";");
}
if (inProps.containsKey(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_USER)) {
((DME2JDBCEndpoint) ep)
.setHealthCheckUser((String) props.get(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_USER));
buff.append("DME2JDBCHealthCheckUser=" + inProps.get(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_USER)
+ ";");
}
if (inProps.containsKey(DME2Constants.KEY_DME2_JDBC_DATABASE_NAME)) {
((DME2JDBCEndpoint) ep).setHealthCheckPassword(
(String) props.get(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_PASSWORD));
buff.append("DME2JDBCHealthCheckPassword="
+ inProps.get(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_PASSWORD) + ";");
}
if (inProps.containsKey(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_DRIVER)) {
((DME2JDBCEndpoint) ep)
.setHealthCheckDriver((String) inProps.get(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_DRIVER));
buff.append("DME2JDBCHealthCheckDriver="
+ inProps.get(DME2Constants.KEY_DME2_JDBC_HEALTHCHECK_DRIVER) + ";");
}
for (String propName : inProps.stringPropertyNames()) {
buff.append(propName + "=" + inProps.get(propName));
}
String endpointProps = props.getProperty(propsKey);
props.setProperty(propsKey, endpointProps + ";" + buff.toString());
}
} else {
ep = new DME2Endpoint(serviceContext, distance);
}
ep.setHost(host);
ep.setPort(port);
ep.setLatitude(latitude);
ep.setLongitude(longitude);
ep.setLease(System.currentTimeMillis());
ep.setProtocol(protocol);
if (contextPath == null) {
ep.setContextPath(servicePath);
} else {
ep.setContextPath(contextPath);
}
localPublishedList.add(ep);
fileHandler.storeProperties(props, true);
}
/**
* {@inheritDoc}
*
* @param serviceName
* Service name
* @param host
* Service host
* @param port
* Service port
* @throws DME2Exception
*/
@Override
public void unpublish(String serviceName, String host, int port) throws DME2Exception {
DME2FileHandler fileHandler = new DME2FileHandler(dir, serviceName, DEFAULT_CACHE_STALENESS,
getClientLatitude(), getClientLongitude());
logger.debug(null, "unpublish", LogMessage.UNPUBLISHING_FILE, serviceName + ".txt");
Properties props = fileHandler.readProperties();
props.remove(host + "," + port);
for (Iterator it = localPublishedList.iterator(); it.hasNext();) {
DME2Endpoint ep = it.next();
if (ep.getHost() != null && ep.getHost().equalsIgnoreCase(host) && ep.getPort() == port) {
localPublishedList.remove(ep);
}
}
fileHandler.storeProperties(props, false);
}
/**
* {@inheritDoc}
*
* @param endpoint
* the endpoint to lease
* @throws DME2Exception
*/
@Override
public void lease(DME2Endpoint endpoint) throws DME2Exception {
publish(endpoint.getPath(), endpoint.getContextPath(), endpoint.getHost(), endpoint.getPort(),
endpoint.getLatitude(), endpoint.getLongitude(), endpoint.getProtocol(),
endpoint.getEndpointProperties());
synchronized (localPublishedList) {
localPublishedList.remove(endpoint);
}
}
private void refreshPublishedDME2Endpoints() {
for (DME2Endpoint ep : localPublishedList) {
try {
lease(ep);
} catch (DME2Exception e) {
logger.debug(null, null, "refreshPublishedDME2Endpoints", LogMessage.DEBUG_MESSAGE, "DME2Exception", e);
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void refresh() {
refreshPublishedDME2Endpoints();
endpointCache.clear();
}
/**
* {@inheritDoc}
*/
@Override
public void shutdown() {
for (DME2Endpoint ep : this.localPublishedList) {
try {
this.unpublish(ep);
} catch (Exception e) {
logger.warn(null, "run", LogMessage.ERROR_UNPUBLISHING, ep);
}
}
}
private void unpublish(DME2Endpoint ep) throws DME2Exception {
unpublish(ep.getPath(), ep.getHost(), ep.getPort());
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
shutdown();
}
@Override
public DME2Endpoint[] find(String serviceKey, String version, String env,
String routeOffer) throws DME2Exception {
List endpoints = findEndpoints(serviceKey, version, env, routeOffer);
DME2Endpoint[] endpointArray = null;
if(CollectionUtils.isNotEmpty(endpoints)) {
endpointArray = endpoints.toArray(new DME2Endpoint[endpoints.size()]);
}
return endpointArray;
}
@Override
public void registerJVM(String envContext, ClientJVMInstance instanceInfo) throws DME2Exception {
// Do Nothing
}
@Override
public void updateJVM(String envContext, ClientJVMInstance instanceInfo) throws DME2Exception {
// Do Nothing
}
@Override
public void deregisterJVM(String envContext, ClientJVMInstance instanceInfo) throws DME2Exception {
// Do Nothing
}
@Override
public List findRegisteredJVM(String envContext, Boolean activeOnly, String hostAddress, String mechID, String processID) throws DME2Exception {
// Do Nothing
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy