Issue #2534 Added reciprocated registry replication subscriptions
Change-Id: I6844d65ccab6c4246f37ce212fa17af09851da27 Former-commit-id:31b53f4ad9
[formerlyf4144fca06
[formerly212bbeb379
] [formerly31b53f4ad9
[formerly 2c52a6ee6f7d491d484c423359b8440975ad6d1e]]] Former-commit-id:f4144fca06
[formerly212bbeb379
] Former-commit-id:f4144fca06
Former-commit-id:67f6ee0999
This commit is contained in:
parent
04c1f9aa95
commit
64e533994c
29 changed files with 1549 additions and 1738 deletions
|
@ -32,8 +32,7 @@ export NCF_ADDRESS=http://${NCF_HOST}:${EBXML_REGISTRY_WEBSERVER_PORT}
|
||||||
export DATADELIVERY_HOST=localhost
|
export DATADELIVERY_HOST=localhost
|
||||||
# Currently the registry is hosted on datadelivery, but this could be changed in the future
|
# Currently the registry is hosted on datadelivery, but this could be changed in the future
|
||||||
export EBXML_REGISTRY_HOST=${DATADELIVERY_HOST}
|
export EBXML_REGISTRY_HOST=${DATADELIVERY_HOST}
|
||||||
export EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED=false
|
export EBXML_REGISTRY_FEDERATION_ENABLED=true
|
||||||
export EBXML_REGISTRY_FEDERATION_ENABLED=false
|
|
||||||
|
|
||||||
# moved here from environment.xml
|
# moved here from environment.xml
|
||||||
# these values are returned to clients that contact the localization service
|
# these values are returned to clients that contact the localization service
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.registry.web;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.registry.services.RegistryServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* Interface for Registry federation status
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 11/20/2013 2534 bphillip Initial Creation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
**/
|
||||||
|
@Path(IRegistryFederationService.REGISTRY_FEDERATION_STATUS_PATH)
|
||||||
|
public interface IRegistryFederationService {
|
||||||
|
|
||||||
|
/** The path to these set of services */
|
||||||
|
public static final String REGISTRY_FEDERATION_STATUS_PATH = "/status/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets if this registry is participating in the federation
|
||||||
|
*
|
||||||
|
* @return The value of the EBXML_REGISTRY_FEDERATION_ENABLED environment
|
||||||
|
* variable
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("isFederated")
|
||||||
|
public String isFederated();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets if this registry is processing registry replication subscriptions
|
||||||
|
*
|
||||||
|
* @return The value of the EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED environment
|
||||||
|
* variable
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("isProcessingSubscriptions")
|
||||||
|
public String isProcessingSubscriptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets information about this registry
|
||||||
|
*
|
||||||
|
* @return Information pertaining to the local registry
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("getMyRegistryInfo")
|
||||||
|
public String getMyRegistryInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the NCF registry to get a list of registries in the federation
|
||||||
|
*
|
||||||
|
* @return The list of registries in the federation
|
||||||
|
* @throws MsgRegistryException
|
||||||
|
* If an error occurs while querying the NCF registry
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("getFederationMembers")
|
||||||
|
public String getFederationMembers() throws MsgRegistryException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of registry that the local registry is subscribed to
|
||||||
|
*
|
||||||
|
* @return The list of registries that the local registry is subscribed to
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("getRegistriesSubscribedTo")
|
||||||
|
public String getRegistriesSubscribedTo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of registries that are subscribing to the local registry
|
||||||
|
*
|
||||||
|
* @return The list of registries that are subscribing to the local registry
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("getRegistrySubscribing")
|
||||||
|
public String getRegistrySubscribing();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of object types that are currently being replicated
|
||||||
|
*
|
||||||
|
* @return The object list
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("getObjectTypesReplicated")
|
||||||
|
public String getObjectTypesReplicated();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kicks of a full registry sync with the specified registry
|
||||||
|
*
|
||||||
|
* @param registryId
|
||||||
|
* The registry ID to sync with
|
||||||
|
* @return status message
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("syncWithRegistry/{registryId}")
|
||||||
|
public String syncWithRegistry(@PathParam("registryId") String registryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribes to replication notifications from the specified registry
|
||||||
|
*
|
||||||
|
* @param registryId
|
||||||
|
* The ID of the registry to subscribe to
|
||||||
|
* @return Status message
|
||||||
|
* @throws JAXBException
|
||||||
|
* @throws RegistryServiceException
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("subscribeToRegistry/{registryId}")
|
||||||
|
public String subscribeToRegistry(@PathParam("registryId") String registryId)
|
||||||
|
throws RegistryServiceException, JAXBException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsubscribes from the specified registry
|
||||||
|
*
|
||||||
|
* @param registryId
|
||||||
|
* The ID of the registry to unsubscribe from
|
||||||
|
* @return The status message
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("unsubscribeFromRegistry/{registryId}")
|
||||||
|
public String unsubscribeFromRegistry(
|
||||||
|
@PathParam("registryId") String registryId);
|
||||||
|
|
||||||
|
}
|
|
@ -22,8 +22,6 @@ package com.raytheon.uf.common.registry.services;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBElement;
|
import javax.xml.bind.JAXBElement;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
|
@ -31,12 +29,15 @@ import javax.xml.bind.JAXBException;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||||
|
|
||||||
import org.apache.cxf.jaxrs.client.Client;
|
import org.apache.cxf.jaxrs.client.Client;
|
||||||
|
import org.apache.cxf.jaxrs.client.ClientConfiguration;
|
||||||
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
|
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
|
||||||
|
import org.apache.cxf.jaxrs.client.WebClient;
|
||||||
|
import org.apache.cxf.transport.http.HTTPConduit;
|
||||||
|
import org.apache.cxf.transports.http.configuration.ConnectionType;
|
||||||
|
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
|
import com.raytheon.uf.common.comm.ProxyConfiguration;
|
||||||
import com.raytheon.uf.common.registry.RegistryJaxbManager;
|
import com.raytheon.uf.common.registry.RegistryJaxbManager;
|
||||||
import com.raytheon.uf.common.registry.RegistryNamespaceMapper;
|
import com.raytheon.uf.common.registry.RegistryNamespaceMapper;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
|
@ -58,6 +59,7 @@ import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService
|
||||||
* 8/1/2013 1693 bphillip Modified getregistry objects method to correctly handle response
|
* 8/1/2013 1693 bphillip Modified getregistry objects method to correctly handle response
|
||||||
* 9/5/2013 1538 bphillip Changed cache expiration timeout and added http header
|
* 9/5/2013 1538 bphillip Changed cache expiration timeout and added http header
|
||||||
* 10/30/2013 1538 bphillip Moved data delivery services out of registry plugin
|
* 10/30/2013 1538 bphillip Moved data delivery services out of registry plugin
|
||||||
|
* 11/20/2013 2534 bphillip Added HTTPClient policy for rest connections. Eliminated service caching.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -65,30 +67,30 @@ import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService
|
||||||
*/
|
*/
|
||||||
public class RegistryRESTServices {
|
public class RegistryRESTServices {
|
||||||
|
|
||||||
|
/** The url path to this set of services */
|
||||||
private static final String REGISTRY_REST_SERVICE_PATH = "/rest";
|
private static final String REGISTRY_REST_SERVICE_PATH = "/rest";
|
||||||
|
|
||||||
/** Map of known registry object request services */
|
/** JAXB Manager */
|
||||||
private LoadingCache<String, IRegistryObjectsRestService> registryObjectServiceMap = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, IRegistryObjectsRestService>() {
|
|
||||||
public IRegistryObjectsRestService load(String url) {
|
|
||||||
return getPort(url + REGISTRY_REST_SERVICE_PATH,
|
|
||||||
IRegistryObjectsRestService.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Map of known repository item request services */
|
|
||||||
private LoadingCache<String, IRepositoryItemsRestService> repositoryItemServiceMap = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, IRepositoryItemsRestService>() {
|
|
||||||
public IRepositoryItemsRestService load(String url) {
|
|
||||||
return getPort(url + REGISTRY_REST_SERVICE_PATH,
|
|
||||||
IRepositoryItemsRestService.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
private RegistryJaxbManager jaxbManager;
|
private RegistryJaxbManager jaxbManager;
|
||||||
|
|
||||||
|
/** Policy used for rest connections */
|
||||||
|
private static final HTTPClientPolicy restPolicy;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ProxyConfiguration proxyConfig = RegistrySOAPServices
|
||||||
|
.getProxyConfiguration();
|
||||||
|
restPolicy = new HTTPClientPolicy();
|
||||||
|
restPolicy.setConnection(ConnectionType.CLOSE);
|
||||||
|
restPolicy.setConnectionTimeout(2000);
|
||||||
|
restPolicy.setReceiveTimeout(30000);
|
||||||
|
restPolicy.setMaxRetransmits(1);
|
||||||
|
if (proxyConfig != null) {
|
||||||
|
restPolicy.setProxyServer(proxyConfig.getHost());
|
||||||
|
restPolicy.setProxyServerPort(proxyConfig.getPort());
|
||||||
|
restPolicy.setNonProxyHosts(proxyConfig.getNonProxyHosts());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public RegistryRESTServices() throws JAXBException {
|
public RegistryRESTServices() throws JAXBException {
|
||||||
jaxbManager = new RegistryJaxbManager(new RegistryNamespaceMapper());
|
jaxbManager = new RegistryJaxbManager(new RegistryNamespaceMapper());
|
||||||
}
|
}
|
||||||
|
@ -101,12 +103,8 @@ public class RegistryRESTServices {
|
||||||
* @return The service implementation
|
* @return The service implementation
|
||||||
*/
|
*/
|
||||||
public IRegistryObjectsRestService getRegistryObjectService(String baseURL) {
|
public IRegistryObjectsRestService getRegistryObjectService(String baseURL) {
|
||||||
try {
|
return getPort(baseURL + REGISTRY_REST_SERVICE_PATH,
|
||||||
return registryObjectServiceMap.get(baseURL);
|
IRegistryObjectsRestService.class);
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting Registry Object Rest Service", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,12 +141,8 @@ public class RegistryRESTServices {
|
||||||
* @return The service implementation
|
* @return The service implementation
|
||||||
*/
|
*/
|
||||||
public IRepositoryItemsRestService getRepositoryItemService(String baseURL) {
|
public IRepositoryItemsRestService getRepositoryItemService(String baseURL) {
|
||||||
try {
|
return getPort(baseURL + REGISTRY_REST_SERVICE_PATH,
|
||||||
return repositoryItemServiceMap.get(baseURL);
|
IRepositoryItemsRestService.class);
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting Repository Item Rest Service", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -192,8 +186,13 @@ public class RegistryRESTServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T extends Object> T getPort(String url, Class<T> serviceClass) {
|
protected <T extends Object> T getPort(String url, Class<T> serviceClass) {
|
||||||
|
|
||||||
T service = JAXRSClientFactory.create(url, serviceClass);
|
T service = JAXRSClientFactory.create(url, serviceClass);
|
||||||
Client client = (Client) Proxy.getInvocationHandler((Proxy) service);
|
Client client = (Client) Proxy.getInvocationHandler((Proxy) service);
|
||||||
|
ClientConfiguration config = WebClient.getConfig(service);
|
||||||
|
HTTPConduit conduit = config.getHttpConduit();
|
||||||
|
conduit.setClient(restPolicy);
|
||||||
|
|
||||||
// Create HTTP header containing the calling registry
|
// Create HTTP header containing the calling registry
|
||||||
client.header(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME,
|
client.header(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME,
|
||||||
RegistryUtil.LOCAL_REGISTRY_ADDRESS);
|
RegistryUtil.LOCAL_REGISTRY_ADDRESS);
|
||||||
|
|
|
@ -27,8 +27,6 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
|
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
|
||||||
|
@ -51,9 +49,6 @@ import org.apache.cxf.transport.http.HTTPConduit;
|
||||||
import org.apache.cxf.transports.http.configuration.ConnectionType;
|
import org.apache.cxf.transports.http.configuration.ConnectionType;
|
||||||
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
|
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.raytheon.uf.common.comm.ProxyConfiguration;
|
import com.raytheon.uf.common.comm.ProxyConfiguration;
|
||||||
import com.raytheon.uf.common.comm.ProxyUtil;
|
import com.raytheon.uf.common.comm.ProxyUtil;
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||||
|
@ -76,7 +71,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
* 8/28/2013 1538 bphillip Removed caches, add http client preferences
|
* 8/28/2013 1538 bphillip Removed caches, add http client preferences
|
||||||
* 9/5/2013 1538 bphillip Add HTTP header information
|
* 9/5/2013 1538 bphillip Add HTTP header information
|
||||||
* 10/30/2013 1538 bphillip Made methods in this class non-static
|
* 10/30/2013 1538 bphillip Made methods in this class non-static
|
||||||
*
|
* 11/20/2013 2534 bphillip Eliminated service caching
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -88,6 +83,12 @@ public class RegistrySOAPServices {
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(RegistrySOAPServices.class);
|
.getHandler(RegistrySOAPServices.class);
|
||||||
|
|
||||||
|
/** Default timeout for receiving HTTP data */
|
||||||
|
private static final long DEFAULT_RECEIVE_TIMEOUT = 60000;
|
||||||
|
|
||||||
|
/** Default value for establishing an HTTP connection */
|
||||||
|
private static final long DEFAULT_CONNECT_TIMEOUT = 10000;
|
||||||
|
|
||||||
/** Path separator */
|
/** Path separator */
|
||||||
private static final String PATH_SEPARATOR = "/";
|
private static final String PATH_SEPARATOR = "/";
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ public class RegistrySOAPServices {
|
||||||
|
|
||||||
private static final ProxyConfiguration proxyConfig;
|
private static final ProxyConfiguration proxyConfig;
|
||||||
|
|
||||||
private static final HTTPClientPolicy httpClientPolicy;
|
protected static final HTTPClientPolicy httpClientPolicy;
|
||||||
static {
|
static {
|
||||||
proxyConfig = getProxyConfiguration();
|
proxyConfig = getProxyConfiguration();
|
||||||
httpClientPolicy = new HTTPClientPolicy();
|
httpClientPolicy = new HTTPClientPolicy();
|
||||||
|
@ -123,7 +124,7 @@ public class RegistrySOAPServices {
|
||||||
statusHandler
|
statusHandler
|
||||||
.error("ebxml-http-receive-timeout not specified. Using default value of 1 minute",
|
.error("ebxml-http-receive-timeout not specified. Using default value of 1 minute",
|
||||||
e);
|
e);
|
||||||
httpClientPolicy.setReceiveTimeout(60000);
|
httpClientPolicy.setReceiveTimeout(DEFAULT_RECEIVE_TIMEOUT);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
httpClientPolicy.setConnectionTimeout(Long.parseLong(System
|
httpClientPolicy.setConnectionTimeout(Long.parseLong(System
|
||||||
|
@ -132,9 +133,9 @@ public class RegistrySOAPServices {
|
||||||
statusHandler
|
statusHandler
|
||||||
.error("ebxml-http-connection-timeout not specified. Using default value of 10 seconds",
|
.error("ebxml-http-connection-timeout not specified. Using default value of 10 seconds",
|
||||||
e);
|
e);
|
||||||
httpClientPolicy.setReceiveTimeout(10000);
|
httpClientPolicy.setConnectionTimeout(DEFAULT_CONNECT_TIMEOUT);
|
||||||
}
|
}
|
||||||
httpClientPolicy.setConnection(ConnectionType.KEEP_ALIVE);
|
httpClientPolicy.setConnection(ConnectionType.CLOSE);
|
||||||
httpClientPolicy.setMaxRetransmits(5);
|
httpClientPolicy.setMaxRetransmits(5);
|
||||||
if (proxyConfig != null) {
|
if (proxyConfig != null) {
|
||||||
httpClientPolicy.setProxyServer(proxyConfig.getHost());
|
httpClientPolicy.setProxyServer(proxyConfig.getHost());
|
||||||
|
@ -143,51 +144,6 @@ public class RegistrySOAPServices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cache of known notification services */
|
|
||||||
private LoadingCache<String, NotificationListener> notificationManagerServices = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, NotificationListener>() {
|
|
||||||
public NotificationListener load(String key) {
|
|
||||||
return getPort(key, NotificationListener.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Cache of known lifecycle manager services */
|
|
||||||
private LoadingCache<String, LifecycleManager> lifecycleManagerServices = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, LifecycleManager>() {
|
|
||||||
public LifecycleManager load(String key) {
|
|
||||||
return getPort(key, LifecycleManager.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Cache of known cataloger services */
|
|
||||||
private LoadingCache<String, Cataloger> catalogerServices = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, Cataloger>() {
|
|
||||||
public Cataloger load(String key) {
|
|
||||||
return getPort(key, Cataloger.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Cache of known query services */
|
|
||||||
private LoadingCache<String, QueryManager> queryServices = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, QueryManager>() {
|
|
||||||
public QueryManager load(String key) {
|
|
||||||
return getPort(key, QueryManager.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Cache of known validator services */
|
|
||||||
private LoadingCache<String, Validator> validatorServices = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, Validator>() {
|
|
||||||
public Validator load(String key) {
|
|
||||||
return getPort(key, Validator.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the notification listener service URL for the given host
|
* Gets the notification listener service URL for the given host
|
||||||
*
|
*
|
||||||
|
@ -209,11 +165,9 @@ public class RegistrySOAPServices {
|
||||||
* @param host
|
* @param host
|
||||||
* The host to get the notification listener service for
|
* The host to get the notification listener service for
|
||||||
* @return The notification listener service for the given host
|
* @return The notification listener service for the given host
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public NotificationListener getNotificationListenerServiceForHost(
|
public NotificationListener getNotificationListenerServiceForHost(
|
||||||
final String host) throws RegistryServiceException {
|
final String host) {
|
||||||
return getNotificationListenerServiceForUrl(host + PATH_SEPARATOR
|
return getNotificationListenerServiceForUrl(host + PATH_SEPARATOR
|
||||||
+ NOTIFICATION_SERVICE_NAME);
|
+ NOTIFICATION_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
@ -224,17 +178,10 @@ public class RegistrySOAPServices {
|
||||||
* @param url
|
* @param url
|
||||||
* The url
|
* The url
|
||||||
* @return The notification listener service at the given URL
|
* @return The notification listener service at the given URL
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public NotificationListener getNotificationListenerServiceForUrl(
|
public NotificationListener getNotificationListenerServiceForUrl(
|
||||||
final String url) throws RegistryServiceException {
|
final String url) throws RegistryServiceException {
|
||||||
try {
|
return getPort(url, NotificationListener.class);
|
||||||
return notificationManagerServices.get(url);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting notification service!", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,11 +190,8 @@ public class RegistrySOAPServices {
|
||||||
* @param host
|
* @param host
|
||||||
* The host to get the lifecycle manager service for
|
* The host to get the lifecycle manager service for
|
||||||
* @return The lifecycle manager service for the given host
|
* @return The lifecycle manager service for the given host
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public LifecycleManager getLifecycleManagerServiceForHost(final String host)
|
public LifecycleManager getLifecycleManagerServiceForHost(final String host) {
|
||||||
throws RegistryServiceException {
|
|
||||||
return getLifecycleManagerServiceForUrl(host + PATH_SEPARATOR
|
return getLifecycleManagerServiceForUrl(host + PATH_SEPARATOR
|
||||||
+ LIFECYCLE_MANAGER_SERVICE_NAME);
|
+ LIFECYCLE_MANAGER_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
@ -258,17 +202,9 @@ public class RegistrySOAPServices {
|
||||||
* @param url
|
* @param url
|
||||||
* The service URL
|
* The service URL
|
||||||
* @return The lifecycle manager service at the given URL string
|
* @return The lifecycle manager service at the given URL string
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public LifecycleManager getLifecycleManagerServiceForUrl(final String url)
|
public LifecycleManager getLifecycleManagerServiceForUrl(final String url) {
|
||||||
throws RegistryServiceException {
|
return getPort(url, LifecycleManager.class);
|
||||||
try {
|
|
||||||
return lifecycleManagerServices.get(url);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting lifecycleManager service", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -277,11 +213,8 @@ public class RegistrySOAPServices {
|
||||||
* @param host
|
* @param host
|
||||||
* The host to get the cataloger service for
|
* The host to get the cataloger service for
|
||||||
* @return The cataloger service at the given host
|
* @return The cataloger service at the given host
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public Cataloger getCatalogerServiceForHost(final String host)
|
public Cataloger getCatalogerServiceForHost(final String host) {
|
||||||
throws RegistryServiceException {
|
|
||||||
return getCatalogerServiceForUrl(host + PATH_SEPARATOR
|
return getCatalogerServiceForUrl(host + PATH_SEPARATOR
|
||||||
+ CATALOGER_SERVICE_NAME);
|
+ CATALOGER_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
@ -292,17 +225,9 @@ public class RegistrySOAPServices {
|
||||||
* @param url
|
* @param url
|
||||||
* the url string
|
* the url string
|
||||||
* @return The cataloger service
|
* @return The cataloger service
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public Cataloger getCatalogerServiceForUrl(final String url)
|
public Cataloger getCatalogerServiceForUrl(final String url) {
|
||||||
throws RegistryServiceException {
|
return getPort(url, Cataloger.class);
|
||||||
try {
|
|
||||||
return catalogerServices.get(url);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting cataloger service!", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -311,11 +236,8 @@ public class RegistrySOAPServices {
|
||||||
* @param host
|
* @param host
|
||||||
* The host name
|
* The host name
|
||||||
* @return The query manager service
|
* @return The query manager service
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public QueryManager getQueryServiceForHost(final String host)
|
public QueryManager getQueryServiceForHost(final String host) {
|
||||||
throws RegistryServiceException {
|
|
||||||
return getQueryServiceForUrl(host + PATH_SEPARATOR + QUERY_SERVICE_NAME);
|
return getQueryServiceForUrl(host + PATH_SEPARATOR + QUERY_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,17 +247,9 @@ public class RegistrySOAPServices {
|
||||||
* @param serviceUrl
|
* @param serviceUrl
|
||||||
* The url string
|
* The url string
|
||||||
* @return The query manager service at the given url string
|
* @return The query manager service at the given url string
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public QueryManager getQueryServiceForUrl(final String url)
|
public QueryManager getQueryServiceForUrl(final String url) {
|
||||||
throws RegistryServiceException {
|
return getPort(url, QueryManager.class);
|
||||||
try {
|
|
||||||
return queryServices.get(url);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error gett queryManager service!", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -347,8 +261,7 @@ public class RegistrySOAPServices {
|
||||||
* @throws RegistryServiceException
|
* @throws RegistryServiceException
|
||||||
* If errors occur creating the URL object
|
* If errors occur creating the URL object
|
||||||
*/
|
*/
|
||||||
public Validator getValidatorServiceForHost(final String host)
|
public Validator getValidatorServiceForHost(final String host) {
|
||||||
throws RegistryServiceException {
|
|
||||||
return getValidatorServiceForUrl(host + PATH_SEPARATOR
|
return getValidatorServiceForUrl(host + PATH_SEPARATOR
|
||||||
+ VALIDATOR_SERVICE_NAME);
|
+ VALIDATOR_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
@ -359,17 +272,10 @@ public class RegistrySOAPServices {
|
||||||
* @param serviceUrl
|
* @param serviceUrl
|
||||||
* The url string
|
* The url string
|
||||||
* @return The validator service for the given url string
|
* @return The validator service for the given url string
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If errors occur creating the URL object
|
|
||||||
*/
|
*/
|
||||||
public Validator getValidatorServiceForUrl(final String url)
|
public Validator getValidatorServiceForUrl(final String url)
|
||||||
throws RegistryServiceException {
|
throws RegistryServiceException {
|
||||||
try {
|
return getPort(url, Validator.class);
|
||||||
return validatorServices.get(url);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting validator service!", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -447,7 +353,7 @@ public class RegistrySOAPServices {
|
||||||
*
|
*
|
||||||
* @return The proxy configuration
|
* @return The proxy configuration
|
||||||
*/
|
*/
|
||||||
private static ProxyConfiguration getProxyConfiguration() {
|
protected static ProxyConfiguration getProxyConfiguration() {
|
||||||
ProxyConfiguration proxyConfig = null;
|
ProxyConfiguration proxyConfig = null;
|
||||||
File proxyFile = PathManagerFactory.getPathManager().getStaticFile(
|
File proxyFile = PathManagerFactory.getPathManager().getStaticFile(
|
||||||
"datadelivery" + File.separator + "proxy.properties");
|
"datadelivery" + File.separator + "proxy.properties");
|
||||||
|
|
|
@ -21,4 +21,5 @@ Require-Bundle: com.raytheon.uf.common.registry.schemas.ebxml;bundle-version="1.
|
||||||
org.apache.commons.cxf;bundle-version="1.0.0",
|
org.apache.commons.cxf;bundle-version="1.0.0",
|
||||||
org.reflections;bundle-version="0.9.9",
|
org.reflections;bundle-version="0.9.9",
|
||||||
com.raytheon.uf.common.datadelivery.registry;bundle-version="1.0.0",
|
com.raytheon.uf.common.datadelivery.registry;bundle-version="1.0.0",
|
||||||
org.apache.commons.lang;bundle-version="2.3.0"
|
org.apache.commons.lang;bundle-version="2.3.0",
|
||||||
|
com.raytheon.uf.common.registry.event;bundle-version="1.0.0"
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
|
||||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
|
||||||
|
|
||||||
<bean name="federationManager"
|
|
||||||
class="com.raytheon.uf.edex.datadelivery.registry.federation.NcfRegistryFederationManager">
|
|
||||||
<constructor-arg ref="ebxmlFederationEnabled"/>
|
|
||||||
<constructor-arg ref="lcmServiceImpl" />
|
|
||||||
<constructor-arg value="ebxml/federation/ncfFederationConfig.xml" />
|
|
||||||
<constructor-arg ref="RegistryReplicationManager"/>
|
|
||||||
<property name="registryObjectDao" ref="registryObjectDao"/>
|
|
||||||
<property name="registryDao" ref="registryDao"/>
|
|
||||||
<property name="registrySoapServices" ref="registryWebServiceClient"/>
|
|
||||||
</bean>
|
|
||||||
</beans>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
|
||||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
|
||||||
|
|
||||||
<bean name="federationManager"
|
|
||||||
class="com.raytheon.uf.edex.datadelivery.registry.federation.WfoRegistryFederationManager">
|
|
||||||
<constructor-arg ref="ebxmlFederationEnabled"/>
|
|
||||||
<constructor-arg ref="lcmServiceImpl" />
|
|
||||||
<constructor-arg value="ebxml/federation/federationConfig.xml"/>
|
|
||||||
<constructor-arg ref="RegistryReplicationManager"/>
|
|
||||||
<property name="registryObjectDao" ref="registryObjectDao"/>
|
|
||||||
<property name="registryDao" ref="registryDao"/>
|
|
||||||
<property name="txTemplate" ref="metadataTxTemplate"/>
|
|
||||||
<property name="dataDeliveryRestClient" ref="dataDeliveryRestClient"/>
|
|
||||||
<property name="registrySoapServices" ref="registryWebServiceClient"/>
|
|
||||||
</bean>
|
|
||||||
</beans>
|
|
|
@ -2,10 +2,26 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||||
|
|
||||||
|
<bean id="FederatedRegistryMonitor" class="com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor">
|
||||||
|
<constructor-arg ref="metadataTxTemplate"/>
|
||||||
|
<constructor-arg ref="registryObjectDao"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="RegistryFederationManager" class="com.raytheon.uf.edex.datadelivery.registry.federation.RegistryFederationManager">
|
||||||
|
<constructor-arg ref="lcmServiceImpl"/>
|
||||||
|
<constructor-arg ref="FederatedRegistryMonitor"/>
|
||||||
|
<constructor-arg ref="metadataTxTemplate"/>
|
||||||
|
<property name="registryObjectDao" ref="registryObjectDao"/>
|
||||||
|
<property name="registryDao" ref="registryDao"/>
|
||||||
|
<property name="registrySoapServices" ref="registryWebServiceClient"/>
|
||||||
|
<property name="dataDeliveryRestClient" ref="dataDeliveryRestClient"/>
|
||||||
|
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||||
<property name="staticMethod"
|
<property name="staticMethod"
|
||||||
value="com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager.addObjectTypesToSubscribeTo" />
|
value="com.raytheon.uf.edex.datadelivery.registry.federation.RegistryFederationManager.addObjectTypesToSubscribeTo" />
|
||||||
<property name="arguments">
|
<property name="arguments">
|
||||||
<list>
|
<list>
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Federation</value>
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Federation</value>
|
||||||
|
@ -13,7 +29,21 @@
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Association</value>
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Association</value>
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Person</value>
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Person</value>
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Organization</value>
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Organization</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.DataSet</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.DataSetMetaData</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.DataSetName</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.GroupDefinition</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.InitialPendingSharedSubscription</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.InitialPendingSiteSubscription</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.Parameter</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.ParameterLevel</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.PendingSharedSubscription</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.PendingSiteSubscription</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.Provider</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.SharedSubscription</value>
|
||||||
|
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.SiteSubscription</value>
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
|
@ -1,42 +0,0 @@
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
|
||||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
|
||||||
|
|
||||||
<bean id="FederatedRegistryMonitor" class="com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor">
|
|
||||||
<constructor-arg ref="metadataTxTemplate"/>
|
|
||||||
<constructor-arg ref="registryObjectDao"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="RegistryReplicationManager" class="com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager">
|
|
||||||
<constructor-arg ref="ebxmlSubscriptionsEnabled"/>
|
|
||||||
<constructor-arg ref="registryObjectDao"/>
|
|
||||||
<constructor-arg ref="FederatedRegistryMonitor"/>
|
|
||||||
<constructor-arg ref="metadataTxTemplate"/>
|
|
||||||
<property name="dataDeliveryRestClient" ref="dataDeliveryRestClient"/>
|
|
||||||
<property name="registrySoapClient" ref="registryWebServiceClient"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
|
||||||
<property name="staticMethod"
|
|
||||||
value="com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager.addObjectTypesToSubscribeTo" />
|
|
||||||
<property name="arguments">
|
|
||||||
<list>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.DataSet</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.DataSetMetaData</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.DataSetName</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.GroupDefinition</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.InitialPendingSharedSubscription</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.InitialPendingSiteSubscription</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.Parameter</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.ParameterLevel</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.PendingSharedSubscription</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.PendingSiteSubscription</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.Provider</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.SharedSubscription</value>
|
|
||||||
<value>urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:com.raytheon.uf.common.datadelivery.registry.SiteSubscription</value>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
|
|
@ -12,7 +12,7 @@
|
||||||
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
|
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
|
||||||
|
|
||||||
<import resource="classpath:res/spring/registry-datadelivery.xml" />
|
<import resource="classpath:res/spring/registry-datadelivery.xml" />
|
||||||
<import resource="classpath:res/spring/registry-replication-datadelivery.xml"/>
|
<import resource="classpath:res/spring/registry-federation-datadelivery.xml"/>
|
||||||
|
|
||||||
<bean id="registryDataAccessService"
|
<bean id="registryDataAccessService"
|
||||||
class="com.raytheon.uf.edex.datadelivery.registry.web.RegistryDataAccessService">
|
class="com.raytheon.uf.edex.datadelivery.registry.web.RegistryDataAccessService">
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<bean id="registryStatus" class="com.raytheon.uf.edex.datadelivery.registry.web.RegistryFederationStatus">
|
<bean id="registryStatus" class="com.raytheon.uf.edex.datadelivery.registry.web.RegistryFederationStatus">
|
||||||
<property name="registryDao" ref="registryDao"/>
|
<property name="registryDao" ref="registryDao"/>
|
||||||
<property name="subscriptionDao" ref="subscriptionTypeDao"/>
|
<property name="subscriptionDao" ref="subscriptionTypeDao"/>
|
||||||
<property name="replicationManager" ref="RegistryReplicationManager"/>
|
<property name="federationManager" ref="RegistryFederationManager"/>
|
||||||
<property name="dataDeliveryRestClient" ref="dataDeliveryRestClient"/>
|
<property name="dataDeliveryRestClient" ref="dataDeliveryRestClient"/>
|
||||||
<property name="registrySoapServices" ref="registryWebServiceClient"/>
|
<property name="registrySoapServices" ref="registryWebServiceClient"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
|
@ -1,163 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.datadelivery.registry.federation;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager;
|
|
||||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.FederationType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.OrganizationType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.PersonType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
|
|
||||||
import com.raytheon.uf.common.registry.constants.StatusTypes;
|
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.NoReplicationServersAvailableException;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* NCF specific implementation of the federation manager
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* 5/22/2013 1707 bphillip Initial implementation
|
|
||||||
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
|
||||||
* 10/30/2013 1538 bphillip Override submitObjects method
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bphillip
|
|
||||||
* @version 1
|
|
||||||
*/
|
|
||||||
public class NcfRegistryFederationManager extends RegistryFederationManager
|
|
||||||
implements RegistryInitializedListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new NcfRegistryFederationManager
|
|
||||||
*/
|
|
||||||
protected NcfRegistryFederationManager() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new NcfRegistryFederationManager
|
|
||||||
*
|
|
||||||
* @param federationEnabled
|
|
||||||
* Boolean denoting if this registry is participating in the
|
|
||||||
* federation
|
|
||||||
* @param lcm
|
|
||||||
* The lifecycle manager that will be used
|
|
||||||
* @param federationPropertiesFileName
|
|
||||||
* The name of the file containing the registry properties
|
|
||||||
* @throws JAXBException
|
|
||||||
* If errors occur while creating the JAXB manager
|
|
||||||
* @throws SerializationException
|
|
||||||
* If errors occur while deserializing the federation properties
|
|
||||||
*/
|
|
||||||
protected NcfRegistryFederationManager(boolean federationEnabled,
|
|
||||||
LifecycleManager lcm, String federationPropertiesFileName,
|
|
||||||
RegistryReplicationManager replicationManager)
|
|
||||||
throws JAXBException, IOException, SerializationException {
|
|
||||||
super(federationEnabled, lcm, federationPropertiesFileName,
|
|
||||||
replicationManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void executeAfterRegistryInit() throws EbxmlRegistryException {
|
|
||||||
if (federationEnabled) {
|
|
||||||
List<RegistryObjectType> objects = new ArrayList<RegistryObjectType>(
|
|
||||||
5);
|
|
||||||
FederationType federation = getFederation();
|
|
||||||
RegistryType registry = federationProperties.createRegistryObject();
|
|
||||||
OrganizationType org = federationProperties.createOrganization();
|
|
||||||
PersonType primaryContact = federationProperties
|
|
||||||
.createPrimaryContactPerson();
|
|
||||||
AssociationType federationAssociation = getFederationAssociation(
|
|
||||||
registry, getFederation());
|
|
||||||
objects.add(federation);
|
|
||||||
objects.add(registry);
|
|
||||||
objects.add(org);
|
|
||||||
objects.add(primaryContact);
|
|
||||||
objects.add(federationAssociation);
|
|
||||||
submitObjects(objects);
|
|
||||||
replicationManager.submitRemoteSubscriptions(registry);
|
|
||||||
try {
|
|
||||||
replicationManager.checkDownTime();
|
|
||||||
} catch (NoReplicationServersAvailableException e) {
|
|
||||||
statusHandler
|
|
||||||
.warn("No replication servers have been specified!");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new EbxmlRegistryException("Error checking down time!", e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
statusHandler.info("Federation is disabled for this registry.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void submitObjects(List<RegistryObjectType> objects)
|
|
||||||
throws EbxmlRegistryException {
|
|
||||||
SubmitObjectsRequest submitObjectsRequest2 = new SubmitObjectsRequest(
|
|
||||||
"Federation Objects submission",
|
|
||||||
"Submitting federation related objects", null,
|
|
||||||
new RegistryObjectListType(objects), false,
|
|
||||||
Mode.CREATE_OR_REPLACE);
|
|
||||||
try {
|
|
||||||
lcm.submitObjects(submitObjectsRequest2);
|
|
||||||
} catch (MsgRegistryException e) {
|
|
||||||
throw new EbxmlRegistryException(
|
|
||||||
"Error submitting federation objects to registry", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected FederationType getFederation() throws EbxmlRegistryException {
|
|
||||||
FederationType federation = new FederationType();
|
|
||||||
federation.setId(FEDERATION_ID);
|
|
||||||
federation.setLid(FEDERATION_ID);
|
|
||||||
federation.setName(RegistryUtil
|
|
||||||
.getInternationalString("NWS EBXML Registry Federation"));
|
|
||||||
federation
|
|
||||||
.setDescription(RegistryUtil
|
|
||||||
.getInternationalString("Federation object for NWS EBXML Registries"));
|
|
||||||
federation.setOwner(RegistryUtil.DEFAULT_OWNER);
|
|
||||||
federation.setStatus(StatusTypes.APPROVED);
|
|
||||||
federation.setObjectType(RegistryObjectTypes.FEDERATION);
|
|
||||||
federation.setReplicationSyncLatency(this.federationProperties
|
|
||||||
.getFederationReplicationSyncLatency());
|
|
||||||
return federation;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,292 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.datadelivery.registry.federation;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.query.v4.ResponseOptionType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.FederationType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.OrganizationType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.PersonType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
|
||||||
import com.raytheon.uf.common.util.CollectionUtil;
|
|
||||||
import com.raytheon.uf.edex.database.RunnableWithTransaction;
|
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager;
|
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.web.DataDeliveryRESTServices;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* WFO specific implementation of the federation manager.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* 5/22/2013 1707 bphillip Initial implementation
|
|
||||||
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
|
||||||
* 10/20/2013 1682 bphillip Fixed query invocation
|
|
||||||
* 10/30/2013 1538 bphillip This class now uses non-static rest/soap clients
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bphillip
|
|
||||||
* @version 1
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Transactional
|
|
||||||
public class WfoRegistryFederationManager extends RegistryFederationManager
|
|
||||||
implements RegistryInitializedListener {
|
|
||||||
|
|
||||||
/** The transaction template used to manually handle transactions */
|
|
||||||
private TransactionTemplate txTemplate;
|
|
||||||
|
|
||||||
/** Data Delivery rest client services */
|
|
||||||
private DataDeliveryRESTServices dataDeliveryRestClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new WfoRegistryFederationManager
|
|
||||||
*/
|
|
||||||
protected WfoRegistryFederationManager() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new WfoRegistryFederationManager
|
|
||||||
*
|
|
||||||
* @param federationEnabled
|
|
||||||
* Boolean denoting if this registry is participating in the
|
|
||||||
* federation
|
|
||||||
* @param lcm
|
|
||||||
* The lifecycle manager that will be used
|
|
||||||
* @param federationPropertiesFileName
|
|
||||||
* The name of the file containing the registry properties
|
|
||||||
* @param ncfAddress
|
|
||||||
* The address of the NCF
|
|
||||||
* @throws JAXBException
|
|
||||||
* If errors occur while creating the JAXB manager
|
|
||||||
* @throws SerializationException
|
|
||||||
* If errors occur while deserializing the federation properties
|
|
||||||
*/
|
|
||||||
protected WfoRegistryFederationManager(boolean federationEnabled,
|
|
||||||
LifecycleManager lcm, String federationPropertiesFileName,
|
|
||||||
RegistryReplicationManager replicationManager)
|
|
||||||
throws JAXBException, IOException, SerializationException {
|
|
||||||
super(federationEnabled, lcm, federationPropertiesFileName,
|
|
||||||
replicationManager);
|
|
||||||
if (this.replicationManager.getServers() == null
|
|
||||||
|| CollectionUtil.isNullOrEmpty(replicationManager.getServers()
|
|
||||||
.getRegistryReplicationServers())) {
|
|
||||||
statusHandler
|
|
||||||
.warn("No servers configured for replication. Federation functionality is disabled");
|
|
||||||
this.federationEnabled = false;
|
|
||||||
this.replicationManager.setSubscriptionProcessingEnabled(false);
|
|
||||||
} else {
|
|
||||||
scheduler = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void executeAfterRegistryInit() throws EbxmlRegistryException {
|
|
||||||
if (federationEnabled) {
|
|
||||||
final RegisterWithFederationTask federationRegistrationTask = new RegisterWithFederationTask();
|
|
||||||
final ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
|
|
||||||
federationRegistrationTask, 0, 10, TimeUnit.SECONDS);
|
|
||||||
scheduler.schedule(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (federationRegistrationTask.success) {
|
|
||||||
statusHandler
|
|
||||||
.info("Federation registration successful. Cancelling future registration attempts.");
|
|
||||||
future.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}, 5, TimeUnit.SECONDS);
|
|
||||||
} else {
|
|
||||||
statusHandler.info("Federation is disabled for this registry.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers this registry with federation
|
|
||||||
*
|
|
||||||
* @throws EbxmlRegistryException
|
|
||||||
* If errors occur while registering this registry with the
|
|
||||||
* federation
|
|
||||||
*/
|
|
||||||
private void registerWithFederation() throws EbxmlRegistryException {
|
|
||||||
List<RegistryObjectType> objects = new ArrayList<RegistryObjectType>(5);
|
|
||||||
RegistryType registry = federationProperties.createRegistryObject();
|
|
||||||
OrganizationType org = federationProperties.createOrganization();
|
|
||||||
PersonType primaryContact = federationProperties
|
|
||||||
.createPrimaryContactPerson();
|
|
||||||
FederationType federation = getFederation();
|
|
||||||
AssociationType federationAssociation = null;
|
|
||||||
if (federation == null) {
|
|
||||||
statusHandler
|
|
||||||
.error("Unable to locate Federation Object! Registry is unable to join the federation at this time.");
|
|
||||||
} else {
|
|
||||||
federationAssociation = getFederationAssociation(registry,
|
|
||||||
federation);
|
|
||||||
}
|
|
||||||
objects.add(registry);
|
|
||||||
objects.add(org);
|
|
||||||
objects.add(primaryContact);
|
|
||||||
objects.add(federationAssociation);
|
|
||||||
submitObjects(objects);
|
|
||||||
replicationManager.setSubscriptionProcessingEnabled(true);
|
|
||||||
replicationManager.submitRemoteSubscriptions(registry);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected FederationType getFederation() throws EbxmlRegistryException {
|
|
||||||
statusHandler
|
|
||||||
.info("Attempting to acquire federation object from NCF...");
|
|
||||||
QueryType query = new QueryType();
|
|
||||||
query.setQueryDefinition(CanonicalQueryTypes.GET_OBJECT_BY_ID);
|
|
||||||
query.getSlot().add(
|
|
||||||
new SlotType(QueryConstants.ID, new StringValueType(
|
|
||||||
FEDERATION_ID)));
|
|
||||||
QueryRequest request = new QueryRequest();
|
|
||||||
request.setResponseOption(new ResponseOptionType(
|
|
||||||
ResponseOptionType.RETURN_TYPE.RegistryObject.toString(), true));
|
|
||||||
request.setId("Query For Federation");
|
|
||||||
request.setQuery(query);
|
|
||||||
QueryResponse response = null;
|
|
||||||
try {
|
|
||||||
response = registrySoapServices.getQueryServiceForHost(ncfAddress)
|
|
||||||
.executeQuery(request);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new EbxmlRegistryException(
|
|
||||||
"Error getting Federation from NCF!", e);
|
|
||||||
}
|
|
||||||
if (response.getRegistryObjectList() == null
|
|
||||||
|| response.getRegistryObjectList().getRegistryObject()
|
|
||||||
.isEmpty()) {
|
|
||||||
throw new EbxmlRegistryException("Federation not found at NCF!");
|
|
||||||
} else {
|
|
||||||
List<RegistryObjectType> responseObjects = response
|
|
||||||
.getRegistryObjectList().getRegistryObject();
|
|
||||||
return (FederationType) responseObjects.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Runnable task that continuously attempts to register this registry with
|
|
||||||
* the federation until it succeeds
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* 5/22/2013 1707 bphillip Initial implementation
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bphillip
|
|
||||||
* @version 1
|
|
||||||
*/
|
|
||||||
private class RegisterWithFederationTask extends RunnableWithTransaction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Denotes if this task has successfully registered this registry with
|
|
||||||
* the federation
|
|
||||||
*/
|
|
||||||
private boolean success = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new RegisterwithFederationTask
|
|
||||||
*/
|
|
||||||
public RegisterWithFederationTask() {
|
|
||||||
super(txTemplate);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void runWithTransaction() {
|
|
||||||
if (!success) {
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
if (dataDeliveryRestClient
|
|
||||||
.isRegistryAvailable(ncfAddress)) {
|
|
||||||
statusHandler
|
|
||||||
.info("NCF Registry is available. Attempting to join federation...");
|
|
||||||
} else {
|
|
||||||
statusHandler
|
|
||||||
.error("NCF is currently unreachable. Local registry is unable to join the federation at this time. Retrying in 10 seconds...");
|
|
||||||
replicationManager
|
|
||||||
.setSubscriptionProcessingEnabled(false);
|
|
||||||
success = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
registerWithFederation();
|
|
||||||
replicationManager.checkDownTime();
|
|
||||||
success = true;
|
|
||||||
} catch (EbxmlRegistryException e) {
|
|
||||||
statusHandler.error(
|
|
||||||
"Error registering with federation", e);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Error initializing EBXML database!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTxTemplate(TransactionTemplate txTemplate) {
|
|
||||||
this.txTemplate = txTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataDeliveryRestClient(
|
|
||||||
DataDeliveryRESTServices dataDeliveryRestClient) {
|
|
||||||
this.dataDeliveryRestClient = dataDeliveryRestClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -35,6 +35,7 @@ import javax.xml.bind.annotation.XmlElement;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 4/9/2013 1802 bphillip Initial implementation
|
* 4/9/2013 1802 bphillip Initial implementation
|
||||||
* 6/4/2013 1707 bphillip Renamed and changed fields for clarity
|
* 6/4/2013 1707 bphillip Renamed and changed fields for clarity
|
||||||
|
* 11/20/2013 2534 bphillip Added reciprocate field
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -55,6 +56,10 @@ public class NotificationHostConfiguration {
|
||||||
@XmlElement
|
@XmlElement
|
||||||
private String registryBaseURL;
|
private String registryBaseURL;
|
||||||
|
|
||||||
|
/** True if subscriptions should be reciprocated */
|
||||||
|
@XmlElement
|
||||||
|
private boolean reciprocate = false;
|
||||||
|
|
||||||
public NotificationHostConfiguration() {
|
public NotificationHostConfiguration() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,4 +95,11 @@ public class NotificationHostConfiguration {
|
||||||
this.registryBaseURL = registryBaseURL;
|
this.registryBaseURL = registryBaseURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isReciprocate() {
|
||||||
|
return reciprocate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReciprocate(boolean reciprocate) {
|
||||||
|
this.reciprocate = reciprocate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.edex.datadelivery.registry.replication;
|
package com.raytheon.uf.edex.datadelivery.registry.replication;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
@ -54,17 +54,18 @@ public class NotificationServers {
|
||||||
|
|
||||||
/** The server located upstream from this server */
|
/** The server located upstream from this server */
|
||||||
@XmlElements({ @XmlElement(name = "registry", type = NotificationHostConfiguration.class) })
|
@XmlElements({ @XmlElement(name = "registry", type = NotificationHostConfiguration.class) })
|
||||||
private List<NotificationHostConfiguration> registryReplicationServers;
|
private CopyOnWriteArrayList<NotificationHostConfiguration> registryReplicationServers;
|
||||||
|
|
||||||
public List<NotificationHostConfiguration> getRegistryReplicationServers() {
|
public List<NotificationHostConfiguration> getRegistryReplicationServers() {
|
||||||
if (registryReplicationServers == null) {
|
if (registryReplicationServers == null) {
|
||||||
registryReplicationServers = new ArrayList<NotificationHostConfiguration>();
|
registryReplicationServers = new CopyOnWriteArrayList<NotificationHostConfiguration>();
|
||||||
}
|
}
|
||||||
return registryReplicationServers;
|
return registryReplicationServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistryReplicationServers(
|
public void setRegistryReplicationServers(
|
||||||
List<NotificationHostConfiguration> registryReplicationServers) {
|
List<NotificationHostConfiguration> registryReplicationServers) {
|
||||||
this.registryReplicationServers = registryReplicationServers;
|
this.registryReplicationServers = new CopyOnWriteArrayList<NotificationHostConfiguration>(
|
||||||
|
registryReplicationServers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,763 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.datadelivery.registry.replication;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.datatype.DatatypeFactory;
|
|
||||||
import javax.xml.datatype.Duration;
|
|
||||||
import javax.xml.transform.dom.DOMResult;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
|
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DeliveryInfoType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.VersionInfoType;
|
|
||||||
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
|
||||||
import org.w3c.dom.Attr;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
|
|
||||||
import com.raytheon.uf.common.registry.EbxmlNamespaces;
|
|
||||||
import com.raytheon.uf.common.registry.RegistryException;
|
|
||||||
import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
|
||||||
import com.raytheon.uf.common.registry.constants.DeliveryMethodTypes;
|
|
||||||
import com.raytheon.uf.common.registry.constants.NotificationOptionTypes;
|
|
||||||
import com.raytheon.uf.common.registry.constants.QueryLanguages;
|
|
||||||
import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
|
|
||||||
import com.raytheon.uf.common.registry.constants.StatusTypes;
|
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
|
||||||
import com.raytheon.uf.common.registry.services.RegistrySOAPServices;
|
|
||||||
import com.raytheon.uf.common.serialization.JAXBManager;
|
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
|
||||||
import com.raytheon.uf.common.util.CollectionUtil;
|
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor;
|
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.web.DataDeliveryRESTServices;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.NoReplicationServersAvailableException;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Manages subscriptions associated with Data Delivery Registry replication
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* 4/24/2013 1675 bphillip Initial implementation
|
|
||||||
* 6/4/2013 1707 bphillip Changed to use new NotificationServer objects
|
|
||||||
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
|
||||||
* 8/1/2013 1693 bphillip Switch to use rest service instead of query manager for federation synchronization
|
|
||||||
* 9/5/2013 1538 bphillip Changed when the registry availability monitor is started
|
|
||||||
* 10/20/2013 1682 bphillip Fixed query invocation
|
|
||||||
* 10/30/2013 1538 bphillip Changed method visibility, added add/remove/save notification servers and updated to use non-static rest/soap clients
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bphillip
|
|
||||||
* @version 1
|
|
||||||
*/
|
|
||||||
public class RegistryReplicationManager {
|
|
||||||
|
|
||||||
/** The logger instance */
|
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
|
||||||
.getHandler(RegistryReplicationManager.class);
|
|
||||||
|
|
||||||
private FederatedRegistryMonitor federatedRegistryMonitor;
|
|
||||||
|
|
||||||
private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_DAY
|
|
||||||
* 2 - TimeUtil.MILLIS_PER_HOUR;
|
|
||||||
|
|
||||||
/** Scheduler service for monitoring subscription submission tasks */
|
|
||||||
private ScheduledExecutorService scheduler;
|
|
||||||
|
|
||||||
/** The servers that we are subscribing to */
|
|
||||||
private NotificationServers servers;
|
|
||||||
|
|
||||||
private RegistryObjectDao dao;
|
|
||||||
|
|
||||||
private TransactionTemplate txTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The JAXBManager instance for marshalling/unmarshalling objects
|
|
||||||
*/
|
|
||||||
private JAXBManager jaxbManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the configuration files defining which servers we are
|
|
||||||
* sending/receiving replicated objects to/from
|
|
||||||
*/
|
|
||||||
private String replicationConfigFileName;
|
|
||||||
|
|
||||||
/** Environment variable denoting whether subscription processing is enabled */
|
|
||||||
private boolean subscriptionProcessingEnabled;
|
|
||||||
|
|
||||||
/** Object types to automatically create subscriptions for */
|
|
||||||
private static List<String> objectTypes = new ArrayList<String>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When a federation sync is necessary, this is the number of threads that
|
|
||||||
* will be used for synchronization. Configurable in the
|
|
||||||
* com.raytheon.uf.edex.registry.ebxml.properties file. Default is 5
|
|
||||||
*/
|
|
||||||
private int registrySyncThreads = 5;
|
|
||||||
|
|
||||||
/** Maximum times this registry will try to sync data before failure */
|
|
||||||
private int maxSyncRetries = 3;
|
|
||||||
|
|
||||||
/** Data Delivery REST services client */
|
|
||||||
private DataDeliveryRESTServices dataDeliveryRestClient;
|
|
||||||
|
|
||||||
/** REgistry Soap client */
|
|
||||||
private RegistrySOAPServices registrySoapClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new RegistryReplicationManager
|
|
||||||
*
|
|
||||||
* @param subscriptionProcessingEnabled
|
|
||||||
* The state of subscription processing
|
|
||||||
* @param notificationServerConfigFileName
|
|
||||||
* The replication configuration files
|
|
||||||
* @throws JAXBException
|
|
||||||
* If errors occur while creating the JAXBManager
|
|
||||||
* @throws SerializationException
|
|
||||||
* @throws MalformedURLException
|
|
||||||
*/
|
|
||||||
public RegistryReplicationManager(boolean subscriptionProcessingEnabled,
|
|
||||||
RegistryObjectDao dao,
|
|
||||||
FederatedRegistryMonitor availabilityMonitor,
|
|
||||||
TransactionTemplate txTemplate) throws JAXBException,
|
|
||||||
SerializationException, MalformedURLException {
|
|
||||||
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
|
|
||||||
if (System.getProperty("edex.run.mode").equals("centralRegistry")) {
|
|
||||||
this.replicationConfigFileName = "ebxml/notification/notificationServers_NCF.xml";
|
|
||||||
} else {
|
|
||||||
this.replicationConfigFileName = "ebxml/notification/notificationServers_WFO.xml";
|
|
||||||
}
|
|
||||||
this.dao = dao;
|
|
||||||
this.txTemplate = txTemplate;
|
|
||||||
this.federatedRegistryMonitor = availabilityMonitor;
|
|
||||||
if (System.getProperty("ebxml-federation-sync-threads") != null) {
|
|
||||||
registrySyncThreads = Integer.valueOf(System
|
|
||||||
.getProperty("ebxml-federation-sync-threads"));
|
|
||||||
}
|
|
||||||
jaxbManager = new JAXBManager(NotificationServers.class,
|
|
||||||
SubscriptionType.class);
|
|
||||||
File notificationServerConfigFile = PathManagerFactory.getPathManager()
|
|
||||||
.getStaticFile(replicationConfigFileName);
|
|
||||||
|
|
||||||
if (notificationServerConfigFile == null) {
|
|
||||||
statusHandler
|
|
||||||
.error("Notification server config file not found! Registry replication will be disabled");
|
|
||||||
this.subscriptionProcessingEnabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
servers = jaxbManager.unmarshalFromXmlFile(NotificationServers.class,
|
|
||||||
notificationServerConfigFile);
|
|
||||||
scheduler = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a notificationServer based on the URL.
|
|
||||||
*
|
|
||||||
* @param baseURL
|
|
||||||
* The URL of the server to be removed
|
|
||||||
*/
|
|
||||||
public void removeNotificationServer(String baseURL) {
|
|
||||||
NotificationHostConfiguration toRemove = null;
|
|
||||||
for (NotificationHostConfiguration hostConfig : this.servers
|
|
||||||
.getRegistryReplicationServers()) {
|
|
||||||
if (hostConfig.getRegistryBaseURL().equals(baseURL)) {
|
|
||||||
toRemove = hostConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (toRemove != null) {
|
|
||||||
this.servers.getRegistryReplicationServers().remove(toRemove);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a notification server to the list.
|
|
||||||
*
|
|
||||||
* @param host
|
|
||||||
* The host to be added
|
|
||||||
*/
|
|
||||||
public void addNotificationServer(NotificationHostConfiguration host) {
|
|
||||||
for (NotificationHostConfiguration hostConfig : this.servers
|
|
||||||
.getRegistryReplicationServers()) {
|
|
||||||
if (hostConfig.getRegistryBaseURL().equals(
|
|
||||||
host.getRegistryBaseURL())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.servers.getRegistryReplicationServers().add(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Persists the list of notification servers to the localized file
|
|
||||||
*/
|
|
||||||
public void saveNotificationServers() {
|
|
||||||
IPathManager pm = PathManagerFactory.getPathManager();
|
|
||||||
LocalizationContext lc = pm.getContext(LocalizationType.EDEX_STATIC,
|
|
||||||
LocalizationLevel.CONFIGURED);
|
|
||||||
LocalizationFile lf = pm.getLocalizationFile(lc,
|
|
||||||
this.replicationConfigFileName);
|
|
||||||
File file = lf.getFile();
|
|
||||||
|
|
||||||
try {
|
|
||||||
jaxbManager.marshalToXmlFile(this.servers, file.getAbsolutePath());
|
|
||||||
lf.save();
|
|
||||||
} catch (SerializationException e) {
|
|
||||||
statusHandler.error("Unable to update replication server file!", e);
|
|
||||||
} catch (LocalizationOpFailedException e) {
|
|
||||||
statusHandler.handle(Priority.ERROR, e.getLocalizedMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks how long a registry has been down. If the registry has been down
|
|
||||||
* for over 2 days, the registry is synchronized with one of the federation
|
|
||||||
* members
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public void checkDownTime() throws Exception {
|
|
||||||
long currentTime = TimeUtil.currentTimeMillis();
|
|
||||||
long lastKnownUp = federatedRegistryMonitor.getLastKnownUptime();
|
|
||||||
long downTime = currentTime - lastKnownUp;
|
|
||||||
statusHandler
|
|
||||||
.info("Registry has been down since: "
|
|
||||||
+ new Date(currentTime - downTime)
|
|
||||||
+ ". Checking if synchronization with the federation is necessary...");
|
|
||||||
|
|
||||||
// The registry has been down for ~2 days, this requires a
|
|
||||||
// synchronization of the
|
|
||||||
// data from the federation
|
|
||||||
if (currentTime - lastKnownUp > MAX_DOWN_TIME_DURATION) {
|
|
||||||
int syncAttempt = 1;
|
|
||||||
for (; syncAttempt <= maxSyncRetries; syncAttempt++) {
|
|
||||||
try {
|
|
||||||
statusHandler
|
|
||||||
.warn("Registry has been down for ~2 days. Initiating federated registry data synchronization attempt #"
|
|
||||||
+ syncAttempt
|
|
||||||
+ "/"
|
|
||||||
+ maxSyncRetries
|
|
||||||
+ "...");
|
|
||||||
List<NotificationHostConfiguration> notificationServers = servers
|
|
||||||
.getRegistryReplicationServers();
|
|
||||||
if (servers == null
|
|
||||||
|| CollectionUtil.isNullOrEmpty(servers
|
|
||||||
.getRegistryReplicationServers())) {
|
|
||||||
statusHandler
|
|
||||||
.error("No servers configured for replication. Unable to synchronize registry data with federation!");
|
|
||||||
} else {
|
|
||||||
NotificationHostConfiguration registryToSyncFrom = null;
|
|
||||||
for (NotificationHostConfiguration config : notificationServers) {
|
|
||||||
statusHandler
|
|
||||||
.info("Checking availability of registry at: "
|
|
||||||
+ config.getRegistryBaseURL());
|
|
||||||
if (dataDeliveryRestClient
|
|
||||||
.isRegistryAvailable(config
|
|
||||||
.getRegistryBaseURL())) {
|
|
||||||
registryToSyncFrom = config;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
statusHandler.info("Registry at "
|
|
||||||
+ config.getRegistryBaseURL()
|
|
||||||
+ " is not available...");
|
|
||||||
}
|
|
||||||
|
|
||||||
// No available registry was found!
|
|
||||||
if (registryToSyncFrom == null) {
|
|
||||||
throw new NoReplicationServersAvailableException(
|
|
||||||
"No available registries found! Registry data will not be synchronized with the federation!");
|
|
||||||
} else {
|
|
||||||
synchronizeRegistryWithFederation(registryToSyncFrom
|
|
||||||
.getRegistryBaseURL());
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// If no servers are found, don't retry, just throw the
|
|
||||||
// exception
|
|
||||||
if (e instanceof NoReplicationServersAvailableException) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
if (syncAttempt < maxSyncRetries) {
|
|
||||||
statusHandler.error(
|
|
||||||
"Federation registry data synchronization attempt #"
|
|
||||||
+ syncAttempt + "/" + maxSyncRetries
|
|
||||||
+ " failed! Retrying...", e);
|
|
||||||
} else {
|
|
||||||
statusHandler
|
|
||||||
.fatal("Federation registry data synchronization has failed",
|
|
||||||
e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statusHandler.info("Starting federated uptime monitor...");
|
|
||||||
scheduler.scheduleAtFixedRate(federatedRegistryMonitor, 0, 1,
|
|
||||||
TimeUnit.MINUTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Synchronizes this registry's data with the registry at the specified URL
|
|
||||||
*
|
|
||||||
* @param remoteRegistryUrl
|
|
||||||
* The URL of the registry to sync with
|
|
||||||
* @throws EbxmlRegistryException
|
|
||||||
* If the thread executor fails to shut down properly
|
|
||||||
*/
|
|
||||||
public void synchronizeRegistryWithFederation(String remoteRegistryUrl)
|
|
||||||
throws EbxmlRegistryException {
|
|
||||||
ExecutorService executor = Executors
|
|
||||||
.newFixedThreadPool(this.registrySyncThreads);
|
|
||||||
for (String objectType : objectTypes) {
|
|
||||||
Set<String> localIds = new HashSet<String>();
|
|
||||||
Set<String> remoteIds = new HashSet<String>();
|
|
||||||
statusHandler
|
|
||||||
.info("Getting registry object Ids from local registry...");
|
|
||||||
Collection<String> response = dataDeliveryRestClient
|
|
||||||
.getRegistryDataAccessService(
|
|
||||||
RegistryUtil.LOCAL_REGISTRY_ADDRESS)
|
|
||||||
.getRegistryObjectIdsOfType(objectType).getPayload();
|
|
||||||
if (response != null) {
|
|
||||||
localIds.addAll(response);
|
|
||||||
}
|
|
||||||
statusHandler.info(localIds.size() + " objects of type "
|
|
||||||
+ objectType + " present in local registry.");
|
|
||||||
statusHandler.info("Getting registry object Ids from "
|
|
||||||
+ remoteRegistryUrl + "...");
|
|
||||||
response = dataDeliveryRestClient
|
|
||||||
.getRegistryDataAccessService(remoteRegistryUrl)
|
|
||||||
.getRegistryObjectIdsOfType(objectType).getPayload();
|
|
||||||
if (response != null) {
|
|
||||||
remoteIds.addAll(response);
|
|
||||||
}
|
|
||||||
statusHandler.info(remoteIds.size() + " objects of type "
|
|
||||||
+ objectType + " present on registry at "
|
|
||||||
+ remoteRegistryUrl);
|
|
||||||
statusHandler.info("Synchronizing objects of type " + objectType
|
|
||||||
+ "...");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Iterate through local objects and compare them with the remote
|
|
||||||
* object inventory to determine if they need to be updated or
|
|
||||||
* deleted locally
|
|
||||||
*/
|
|
||||||
for (String localId : localIds) {
|
|
||||||
if (remoteIds.contains(localId)) {
|
|
||||||
executor.submit(new RegistrySubmitTask(txTemplate, dao,
|
|
||||||
localId, remoteRegistryUrl, dataDeliveryRestClient));
|
|
||||||
} else {
|
|
||||||
RegistryRemoveTask removeTask = new RegistryRemoveTask(
|
|
||||||
txTemplate, dao, localId);
|
|
||||||
executor.submit(removeTask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Iterate through the remote objects to see if there are any
|
|
||||||
* objects on the remote registry that do not exist local. If found,
|
|
||||||
* retrieve them and add them to the local registry
|
|
||||||
*/
|
|
||||||
for (String remoteId : remoteIds) {
|
|
||||||
if (!localIds.contains(remoteId)) {
|
|
||||||
executor.submit(new RegistrySubmitTask(txTemplate, dao,
|
|
||||||
remoteId, remoteRegistryUrl, dataDeliveryRestClient));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for all threads to complete
|
|
||||||
executor.shutdown();
|
|
||||||
try {
|
|
||||||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
statusHandler
|
|
||||||
.error("Registry synchronization using ["
|
|
||||||
+ remoteRegistryUrl
|
|
||||||
+ "] did not complete successfully!", e);
|
|
||||||
throw new EbxmlRegistryException(
|
|
||||||
"Task executor did not shutdown properly!", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
statusHandler.info("Registry synchronization using ["
|
|
||||||
+ remoteRegistryUrl + "] completed successfully!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static method only used during the Spring container to inject the object
|
|
||||||
* types to subscribe to for registry replication
|
|
||||||
*
|
|
||||||
* @param types
|
|
||||||
* The object types to subscribe to
|
|
||||||
*/
|
|
||||||
public static void addObjectTypesToSubscribeTo(String... types) {
|
|
||||||
for (String type : types) {
|
|
||||||
objectTypes.add(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Submits subscriptions to the registry at the provided URL
|
|
||||||
*
|
|
||||||
* @param baseURL
|
|
||||||
* The url of the registry to send the subscriptions to
|
|
||||||
*/
|
|
||||||
public void submitRemoteSubscriptions(RegistryType registry) {
|
|
||||||
|
|
||||||
if (subscriptionProcessingEnabled) {
|
|
||||||
statusHandler.info("Registry Replication is enabled.");
|
|
||||||
} else {
|
|
||||||
statusHandler.warn("Registry Replication is disabled");
|
|
||||||
// TODO: Add code in here to remove replication
|
|
||||||
// subscriptions from remote servers if replication is disabled
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NotificationHostConfiguration> replicationRegistries = servers
|
|
||||||
.getRegistryReplicationServers();
|
|
||||||
|
|
||||||
if (CollectionUtil.isNullOrEmpty(replicationRegistries)) {
|
|
||||||
statusHandler.info("No registry replication servers configured.");
|
|
||||||
} else {
|
|
||||||
statusHandler
|
|
||||||
.info("Submitting subscriptions to registry replication servers...");
|
|
||||||
for (NotificationHostConfiguration config : replicationRegistries) {
|
|
||||||
scheduleSubscriptionSubmission(config, registry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedules a task to submit subscriptions
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* The server configuration
|
|
||||||
* @param baseURL
|
|
||||||
* The url of the registry to submit the subscriptions to
|
|
||||||
*/
|
|
||||||
private void scheduleSubscriptionSubmission(
|
|
||||||
NotificationHostConfiguration config, RegistryType registry) {
|
|
||||||
final SubmitSubscriptionTask submitSubscriptionTask = new SubmitSubscriptionTask(
|
|
||||||
config, registry);
|
|
||||||
final ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
|
|
||||||
submitSubscriptionTask, 0, 10, TimeUnit.SECONDS);
|
|
||||||
scheduler.schedule(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (submitSubscriptionTask.success) {
|
|
||||||
statusHandler
|
|
||||||
.info("Subscription submission successful. Cancelling future subscription submission retries");
|
|
||||||
future.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}, 5, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and submits objects to the server described in the config object
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* The object describing the destination server to make registry
|
|
||||||
* replication subscriptions to
|
|
||||||
*/
|
|
||||||
public void submitSubscriptionsToHost(NotificationHostConfiguration config,
|
|
||||||
RegistryType localRegistry) {
|
|
||||||
statusHandler
|
|
||||||
.info("Generating registry replication subscriptions for registry at ["
|
|
||||||
+ config.getRegistrySiteName()
|
|
||||||
+ "] at URL ["
|
|
||||||
+ config.getRegistryBaseURL() + "]");
|
|
||||||
|
|
||||||
List<RegistryObjectType> subscriptions = new ArrayList<RegistryObjectType>();
|
|
||||||
for (String objectType : objectTypes) {
|
|
||||||
SubscriptionType subscription;
|
|
||||||
try {
|
|
||||||
subscription = createSubscription(config.getRegistryBaseURL(),
|
|
||||||
objectType, localRegistry);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RegistryException("Error creating subscription", e);
|
|
||||||
}
|
|
||||||
subscriptions.add(subscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
SubmitObjectsRequest request = new SubmitObjectsRequest(
|
|
||||||
"Subscription Submission", "Subscription Submission", null,
|
|
||||||
new RegistryObjectListType(subscriptions), false,
|
|
||||||
Mode.CREATE_OR_REPLACE);
|
|
||||||
registrySoapClient.sendSubmitObjectsRequest(request,
|
|
||||||
config.getRegistryBaseURL());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new subscription object
|
|
||||||
*
|
|
||||||
* @param host
|
|
||||||
* The destination host
|
|
||||||
* @param objectType
|
|
||||||
* The object type to create the subscription for
|
|
||||||
* @return The subscription object
|
|
||||||
* @throws Exception
|
|
||||||
* If errors occur while creating the subscription object
|
|
||||||
*/
|
|
||||||
private SubscriptionType createSubscription(String host, String objectType,
|
|
||||||
RegistryType registry) throws Exception {
|
|
||||||
// Set normal registry object fields
|
|
||||||
String subscriptionDetail = "Replication Subscription for ["
|
|
||||||
+ objectType + "] objects for server [" + registry.getBaseURL()
|
|
||||||
+ "]";
|
|
||||||
SubscriptionType sub = new SubscriptionType();
|
|
||||||
sub.setId(subscriptionDetail);
|
|
||||||
sub.setLid(subscriptionDetail);
|
|
||||||
sub.setObjectType(RegistryObjectTypes.SUBSCRIPTION);
|
|
||||||
sub.setName(RegistryUtil.getInternationalString(subscriptionDetail));
|
|
||||||
sub.setDescription(RegistryUtil
|
|
||||||
.getInternationalString(subscriptionDetail));
|
|
||||||
VersionInfoType version = new VersionInfoType();
|
|
||||||
version.setVersionName("1");
|
|
||||||
version.setUserVersionName("1");
|
|
||||||
sub.setVersionInfo(version);
|
|
||||||
sub.setOwner(registry.getOwner());
|
|
||||||
sub.setStatus(StatusTypes.APPROVED);
|
|
||||||
|
|
||||||
sub.setStartTime(EbxmlObjectUtil.getTimeAsXMLGregorianCalendar(0));
|
|
||||||
QueryType selectorQuery = new QueryType();
|
|
||||||
selectorQuery.setQueryDefinition(CanonicalQueryTypes.ADHOC_QUERY);
|
|
||||||
|
|
||||||
SlotType expressionSlot = new SlotType();
|
|
||||||
StringValueType expressionValue = new StringValueType();
|
|
||||||
expressionValue
|
|
||||||
.setValue("FROM RegistryObjectType obj where obj.objectType='"
|
|
||||||
+ objectType + "'");
|
|
||||||
expressionSlot.setName(QueryConstants.QUERY_EXPRESSION);
|
|
||||||
expressionSlot.setSlotValue(expressionValue);
|
|
||||||
selectorQuery.getSlot().add(expressionSlot);
|
|
||||||
|
|
||||||
SlotType languageSlot = new SlotType();
|
|
||||||
StringValueType languageValue = new StringValueType();
|
|
||||||
languageValue.setValue(QueryLanguages.HQL);
|
|
||||||
languageSlot.setName(QueryConstants.QUERY_LANGUAGE);
|
|
||||||
languageSlot.setSlotValue(languageValue);
|
|
||||||
selectorQuery.getSlot().add(languageSlot);
|
|
||||||
|
|
||||||
sub.setSelector(selectorQuery);
|
|
||||||
|
|
||||||
Duration notificationInterval = DatatypeFactory.newInstance()
|
|
||||||
.newDuration(0);
|
|
||||||
sub.setNotificationInterval(notificationInterval);
|
|
||||||
|
|
||||||
String endpointType = DeliveryMethodTypes.SOAP;
|
|
||||||
W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
|
|
||||||
builder.address(registrySoapClient.getNotificationListenerServiceUrl(
|
|
||||||
registry.getBaseURL()).toString());
|
|
||||||
W3CEndpointReference ref = builder.build();
|
|
||||||
DOMResult dom = new DOMResult();
|
|
||||||
ref.writeTo(dom);
|
|
||||||
Document doc = (Document) dom.getNode();
|
|
||||||
NodeList nodes = doc.getElementsByTagNameNS(
|
|
||||||
EbxmlNamespaces.ADDRESSING_URI, "Address");
|
|
||||||
for (int i = 0; i < nodes.getLength(); i++) {
|
|
||||||
Node addressNode = nodes.item(i);
|
|
||||||
Attr endpointTypeAttr = doc.createAttributeNS(
|
|
||||||
EbxmlNamespaces.RIM_URI, "endpointType");
|
|
||||||
endpointTypeAttr.setValue(endpointType);
|
|
||||||
addressNode.getAttributes().setNamedItemNS(endpointTypeAttr);
|
|
||||||
}
|
|
||||||
ref = new W3CEndpointReference(new DOMSource(dom.getNode()));
|
|
||||||
|
|
||||||
// Set subscription specific fields
|
|
||||||
DeliveryInfoType deliveryInfo = new DeliveryInfoType();
|
|
||||||
deliveryInfo.setNotificationOption(NotificationOptionTypes.OBJECT_REFS);
|
|
||||||
deliveryInfo.setNotifyTo(ref);
|
|
||||||
sub.getDeliveryInfo().add(deliveryInfo);
|
|
||||||
return sub;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Task for submitting subscriptions to a remote registry
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* 5/21/2013 1707 bphillip Initial implementation
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bphillip
|
|
||||||
* @version 1
|
|
||||||
*/
|
|
||||||
private class SubmitSubscriptionTask implements Runnable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Denotes if the subscription has successfully been submitted to the
|
|
||||||
* remote server
|
|
||||||
*/
|
|
||||||
private boolean success = false;
|
|
||||||
|
|
||||||
/** The server configuration */
|
|
||||||
private NotificationHostConfiguration config;
|
|
||||||
|
|
||||||
/** The remote registry */
|
|
||||||
private RegistryType registry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new SubmitSubscriptionTask
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* The server configuration
|
|
||||||
* @param baseURL
|
|
||||||
* The base URL of the remote registry
|
|
||||||
*/
|
|
||||||
public SubmitSubscriptionTask(NotificationHostConfiguration config,
|
|
||||||
RegistryType registry) {
|
|
||||||
this.config = config;
|
|
||||||
this.registry = registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!success) {
|
|
||||||
final String remoteRegistryBaseURL = config
|
|
||||||
.getRegistryBaseURL();
|
|
||||||
statusHandler.info("Checking if remote registry at ["
|
|
||||||
+ remoteRegistryBaseURL + "] is available...");
|
|
||||||
|
|
||||||
if (dataDeliveryRestClient
|
|
||||||
.isRegistryAvailable(remoteRegistryBaseURL)) {
|
|
||||||
statusHandler.info("Registry at [" + remoteRegistryBaseURL
|
|
||||||
+ "] is available!");
|
|
||||||
} else {
|
|
||||||
statusHandler.error("Registry at [" + remoteRegistryBaseURL
|
|
||||||
+ "] is not available! Retrying in 10 seconds...");
|
|
||||||
success = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
statusHandler
|
|
||||||
.info("Removing remote subscriptions prior to submission of new subscriptions");
|
|
||||||
dataDeliveryRestClient.getRegistryDataAccessService(
|
|
||||||
config.getRegistryBaseURL())
|
|
||||||
.removeSubscriptionsForSite(registry.getOwner());
|
|
||||||
submitSubscriptionsToHost(config, registry);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds a hook to remove the subscriptions from the remote
|
|
||||||
* server when this server shuts down
|
|
||||||
*/
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
|
||||||
public void run() {
|
|
||||||
statusHandler
|
|
||||||
.info("Registry shutting down. Removing subscriptions from: ["
|
|
||||||
+ remoteRegistryBaseURL + "]");
|
|
||||||
dataDeliveryRestClient
|
|
||||||
.getRegistryDataAccessService(
|
|
||||||
remoteRegistryBaseURL)
|
|
||||||
.removeSubscriptionsForSite(
|
|
||||||
registry.getOwner());
|
|
||||||
statusHandler.info("Subscriptions removed from: ["
|
|
||||||
+ remoteRegistryBaseURL + "]");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
success = true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
statusHandler
|
|
||||||
.error("Error submitting subscriptions! Retrying in 10 seconds...",
|
|
||||||
e);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> getObjectTypes() {
|
|
||||||
return Collections.unmodifiableList(objectTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubscriptionProcessingEnabled(
|
|
||||||
boolean subscriptionProcessingEnabled) {
|
|
||||||
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationServers getServers() {
|
|
||||||
return servers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataDeliveryRestClient(
|
|
||||||
DataDeliveryRESTServices dataDeliveryRestClient) {
|
|
||||||
this.dataDeliveryRestClient = dataDeliveryRestClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRegistrySoapClient(RegistrySOAPServices registrySoapClient) {
|
|
||||||
this.registrySoapClient = registrySoapClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,21 +19,15 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.edex.datadelivery.registry.web;
|
package com.raytheon.uf.edex.datadelivery.registry.web;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryAvailableRestService;
|
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryAvailableRestService;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryDataAccessService;
|
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryDataAccessService;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryFederationService;
|
||||||
import com.raytheon.uf.common.registry.constants.RegistryAvailability;
|
import com.raytheon.uf.common.registry.constants.RegistryAvailability;
|
||||||
import com.raytheon.uf.common.registry.services.RegistryRESTServices;
|
import com.raytheon.uf.common.registry.services.RegistryRESTServices;
|
||||||
import com.raytheon.uf.common.registry.services.RegistryServiceException;
|
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
|
||||||
|
@ -47,6 +41,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 10/30/2013 1538 bphillip Initial Creation
|
* 10/30/2013 1538 bphillip Initial Creation
|
||||||
|
* 11/20/2013 2534 bphillip Eliminated service caching
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -63,30 +58,15 @@ public class DataDeliveryRESTServices extends RegistryRESTServices {
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(RegistryRESTServices.class);
|
.getHandler(RegistryRESTServices.class);
|
||||||
|
|
||||||
/** Map of known registry availability services */
|
|
||||||
private LoadingCache<String, IRegistryAvailableRestService> registryAvailabilityServiceMap = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, IRegistryAvailableRestService>() {
|
|
||||||
public IRegistryAvailableRestService load(String url) {
|
|
||||||
return getPort(url + DATA_DELIVERY_REST_SERVICE_PATH,
|
|
||||||
IRegistryAvailableRestService.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Map of known registry data access services */
|
|
||||||
private LoadingCache<String, IRegistryDataAccessService> registryDataAccessServiceMap = CacheBuilder
|
|
||||||
.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES)
|
|
||||||
.build(new CacheLoader<String, IRegistryDataAccessService>() {
|
|
||||||
public IRegistryDataAccessService load(String url) {
|
|
||||||
return getPort(url + DATA_DELIVERY_REST_SERVICE_PATH,
|
|
||||||
IRegistryDataAccessService.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
public DataDeliveryRESTServices() throws JAXBException {
|
public DataDeliveryRESTServices() throws JAXBException {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IRegistryFederationService getFederationService(String baseURL) {
|
||||||
|
return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH,
|
||||||
|
IRegistryFederationService.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the registry available service implementation
|
* Gets the registry available service implementation
|
||||||
*
|
*
|
||||||
|
@ -96,12 +76,8 @@ public class DataDeliveryRESTServices extends RegistryRESTServices {
|
||||||
*/
|
*/
|
||||||
public IRegistryAvailableRestService getRegistryAvailableService(
|
public IRegistryAvailableRestService getRegistryAvailableService(
|
||||||
String baseURL) {
|
String baseURL) {
|
||||||
try {
|
return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH,
|
||||||
return registryAvailabilityServiceMap.get(baseURL);
|
IRegistryAvailableRestService.class);
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting Registry Availability Rest Service", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,11 +118,8 @@ public class DataDeliveryRESTServices extends RegistryRESTServices {
|
||||||
*/
|
*/
|
||||||
public IRegistryDataAccessService getRegistryDataAccessService(
|
public IRegistryDataAccessService getRegistryDataAccessService(
|
||||||
String baseURL) {
|
String baseURL) {
|
||||||
try {
|
return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH,
|
||||||
return registryDataAccessServiceMap.get(baseURL);
|
IRegistryDataAccessService.class);
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RegistryServiceException(
|
|
||||||
"Error getting Registry Availability Rest Service", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
import javax.xml.transform.dom.DOMResult;
|
import javax.xml.transform.dom.DOMResult;
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryFederationService;
|
||||||
import com.raytheon.uf.common.registry.EbxmlNamespaces;
|
import com.raytheon.uf.common.registry.EbxmlNamespaces;
|
||||||
import com.raytheon.uf.common.registry.constants.AssociationTypes;
|
import com.raytheon.uf.common.registry.constants.AssociationTypes;
|
||||||
import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
||||||
|
@ -54,13 +56,13 @@ import com.raytheon.uf.common.registry.constants.QueryLanguages;
|
||||||
import com.raytheon.uf.common.registry.constants.QueryReturnTypes;
|
import com.raytheon.uf.common.registry.constants.QueryReturnTypes;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
import com.raytheon.uf.common.registry.services.RegistrySOAPServices;
|
import com.raytheon.uf.common.registry.services.RegistrySOAPServices;
|
||||||
|
import com.raytheon.uf.common.registry.services.RegistryServiceException;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.util.CollectionUtil;
|
import com.raytheon.uf.common.util.CollectionUtil;
|
||||||
import com.raytheon.uf.common.util.StringUtil;
|
import com.raytheon.uf.common.util.StringUtil;
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.federation.RegistryFederationManager;
|
import com.raytheon.uf.edex.datadelivery.registry.federation.RegistryFederationManager;
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.replication.NotificationHostConfiguration;
|
import com.raytheon.uf.edex.datadelivery.registry.replication.NotificationHostConfiguration;
|
||||||
import com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao;
|
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.SubscriptionDao;
|
import com.raytheon.uf.edex.registry.ebxml.dao.SubscriptionDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager;
|
import com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager;
|
||||||
|
@ -75,17 +77,15 @@ import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 10/30/2013 1538 bphillip Initial Creation
|
* 10/30/2013 1538 bphillip Initial Creation
|
||||||
|
* 11/20/2013 2534 bphillip Added interface
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
* @version 1
|
* @version 1
|
||||||
**/
|
**/
|
||||||
@Path(RegistryFederationStatus.REGISTRY_FEDERATION_STATUS_PATH)
|
@Path(IRegistryFederationService.REGISTRY_FEDERATION_STATUS_PATH)
|
||||||
@Transactional
|
@Transactional
|
||||||
public class RegistryFederationStatus {
|
public class RegistryFederationStatus implements IRegistryFederationService {
|
||||||
|
|
||||||
/** The path to these set of services */
|
|
||||||
protected static final String REGISTRY_FEDERATION_STATUS_PATH = "/status/";
|
|
||||||
|
|
||||||
/** The logger instance */
|
/** The logger instance */
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
@ -106,7 +106,7 @@ public class RegistryFederationStatus {
|
||||||
private SubscriptionDao subscriptionDao;
|
private SubscriptionDao subscriptionDao;
|
||||||
|
|
||||||
/** The registry replication manager */
|
/** The registry replication manager */
|
||||||
private RegistryReplicationManager replicationManager;
|
private RegistryFederationManager federationManager;
|
||||||
|
|
||||||
/** Data Delivery rest services client */
|
/** Data Delivery rest services client */
|
||||||
private DataDeliveryRESTServices dataDeliveryRestClient;
|
private DataDeliveryRESTServices dataDeliveryRestClient;
|
||||||
|
@ -120,35 +120,18 @@ public class RegistryFederationStatus {
|
||||||
*/
|
*/
|
||||||
private String ncfAddress = System.getenv("NCF_ADDRESS");
|
private String ncfAddress = System.getenv("NCF_ADDRESS");
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if this registry is participating in the federation
|
|
||||||
*
|
|
||||||
* @return The value of the EBXML_REGISTRY_FEDERATION_ENABLED environment
|
|
||||||
* variable
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("isFederated")
|
@Path("isFederated")
|
||||||
public String isFederated() {
|
public String isFederated() {
|
||||||
return System.getenv("EBXML_REGISTRY_FEDERATION_ENABLED");
|
return System.getenv("EBXML_REGISTRY_FEDERATION_ENABLED");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if this registry is processing registry replication subscriptions
|
|
||||||
*
|
|
||||||
* @return The value of the EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED environment
|
|
||||||
* variable
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("isProcessingSubscriptions")
|
@Path("isProcessingSubscriptions")
|
||||||
public String isProcessingSubscriptions() {
|
public String isProcessingSubscriptions() {
|
||||||
return System.getenv("EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED");
|
return System.getenv("EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets information about this registry
|
|
||||||
*
|
|
||||||
* @return Information pertaining to the local registry
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("getMyRegistryInfo")
|
@Path("getMyRegistryInfo")
|
||||||
public String getMyRegistryInfo() {
|
public String getMyRegistryInfo() {
|
||||||
|
@ -160,13 +143,6 @@ public class RegistryFederationStatus {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the NCF registry to get a list of registries in the federation
|
|
||||||
*
|
|
||||||
* @return The list of registries in the federation
|
|
||||||
* @throws MsgRegistryException
|
|
||||||
* If an error occurs while querying the NCF registry
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("getFederationMembers")
|
@Path("getFederationMembers")
|
||||||
public String getFederationMembers() throws MsgRegistryException {
|
public String getFederationMembers() throws MsgRegistryException {
|
||||||
|
@ -199,20 +175,15 @@ public class RegistryFederationStatus {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the list of registry that the local registry is subscribed to
|
|
||||||
*
|
|
||||||
* @return The list of registries that the local registry is subscribed to
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("getRegistriesSubscribedTo")
|
@Path("getRegistriesSubscribedTo")
|
||||||
public String getRegistriesSubscribedTo() {
|
public String getRegistriesSubscribedTo() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
if (this.replicationManager.getServers() != null
|
if (this.federationManager.getServers() != null
|
||||||
&& !CollectionUtil.isNullOrEmpty(this.replicationManager
|
&& !CollectionUtil.isNullOrEmpty(this.federationManager
|
||||||
.getServers().getRegistryReplicationServers())) {
|
.getServers().getRegistryReplicationServers())) {
|
||||||
List<RegistryObjectType> registries = new ArrayList<RegistryObjectType>();
|
List<RegistryObjectType> registries = new ArrayList<RegistryObjectType>();
|
||||||
for (NotificationHostConfiguration hostConfig : this.replicationManager
|
for (NotificationHostConfiguration hostConfig : this.federationManager
|
||||||
.getServers().getRegistryReplicationServers()) {
|
.getServers().getRegistryReplicationServers()) {
|
||||||
|
|
||||||
SlotType queryLanguageSlot = new SlotType(
|
SlotType queryLanguageSlot = new SlotType(
|
||||||
|
@ -259,11 +230,6 @@ public class RegistryFederationStatus {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of registries that are subscribing to the local registry
|
|
||||||
*
|
|
||||||
* @return The list of registries that are subscribing to the local registry
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("getRegistrySubscribing")
|
@Path("getRegistrySubscribing")
|
||||||
public String getRegistrySubscribing() {
|
public String getRegistrySubscribing() {
|
||||||
|
@ -302,28 +268,16 @@ public class RegistryFederationStatus {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the list of object types that are currently being replicated
|
|
||||||
*
|
|
||||||
* @return The object list
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("getObjectTypesReplicated")
|
@Path("getObjectTypesReplicated")
|
||||||
public String getObjectTypesReplicated() {
|
public String getObjectTypesReplicated() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (String objectType : RegistryReplicationManager.getObjectTypes()) {
|
for (String objectType : RegistryFederationManager.getObjectTypes()) {
|
||||||
builder.append(objectType).append(StringUtil.NEWLINE);
|
builder.append(objectType).append(StringUtil.NEWLINE);
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Kicks of a full registry sync with the specified registry
|
|
||||||
*
|
|
||||||
* @param registryId
|
|
||||||
* The registry ID to sync with
|
|
||||||
* @return status message
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("syncWithRegistry/{registryId}")
|
@Path("syncWithRegistry/{registryId}")
|
||||||
public String syncWithRegistry(@PathParam("registryId") String registryId) {
|
public String syncWithRegistry(@PathParam("registryId") String registryId) {
|
||||||
|
@ -334,7 +288,7 @@ public class RegistryFederationStatus {
|
||||||
+ "] not in federation. Unable to synchronize.");
|
+ "] not in federation. Unable to synchronize.");
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
replicationManager.synchronizeRegistryWithFederation(registry
|
federationManager.synchronizeRegistryWithFederation(registry
|
||||||
.getBaseURL());
|
.getBaseURL());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.error("Error synchronizing registry!", e);
|
statusHandler.error("Error synchronizing registry!", e);
|
||||||
|
@ -345,43 +299,29 @@ public class RegistryFederationStatus {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribes to replication notifications from the specified registry
|
|
||||||
*
|
|
||||||
* @param registryId
|
|
||||||
* The ID of the registry to subscribe to
|
|
||||||
* @return Status message
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("subscribeToRegistry/{registryId}")
|
@Path("subscribeToRegistry/{registryId}")
|
||||||
public String subscribeToRegistry(@PathParam("registryId") String registryId) {
|
public String subscribeToRegistry(@PathParam("registryId") String registryId)
|
||||||
|
throws RegistryServiceException, JAXBException {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
RegistryType registry = registryDao.getById(registryId);
|
RegistryType registry = dataDeliveryRestClient.getRegistryObject(
|
||||||
|
RegistryType.class, ncfAddress, registryId);
|
||||||
if (registry == null) {
|
if (registry == null) {
|
||||||
builder.append("Registry [" + registryId
|
builder.append("Registry [")
|
||||||
+ "] not in federation. Unable to submit subscriptions.");
|
.append(registryId)
|
||||||
|
.append("] not in federation. Unable to submit subscriptions.");
|
||||||
} else {
|
} else {
|
||||||
RegistryType localRegistry = registryDao
|
if (!federationManager.isSubscribedTo(registry)) {
|
||||||
.getRegistryByBaseURL(RegistryUtil.LOCAL_REGISTRY_ADDRESS);
|
federationManager.submitSubscriptionsToRegistry(registry);
|
||||||
|
builder.append("Successfully subscribed to registry [")
|
||||||
NotificationHostConfiguration config = new NotificationHostConfiguration(
|
.append(registryId).append("]");
|
||||||
registry.getId(), registry.getId(), registry.getBaseURL());
|
this.federationManager.addNotificationServer(registry);
|
||||||
replicationManager.submitSubscriptionsToHost(config, localRegistry);
|
federationManager.saveNotificationServers();
|
||||||
builder.append("Successfully subscribed to registry [" + registryId
|
}
|
||||||
+ "]");
|
|
||||||
this.replicationManager.addNotificationServer(config);
|
|
||||||
replicationManager.saveNotificationServers();
|
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribes from the specified registry
|
|
||||||
*
|
|
||||||
* @param registryId
|
|
||||||
* The ID of the registry to unsubscribe from
|
|
||||||
* @return The status message
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
@Path("unsubscribeFromRegistry/{registryId}")
|
@Path("unsubscribeFromRegistry/{registryId}")
|
||||||
public String unsubscribeFromRegistry(
|
public String unsubscribeFromRegistry(
|
||||||
|
@ -399,8 +339,8 @@ public class RegistryFederationStatus {
|
||||||
localRegistry.getOwner());
|
localRegistry.getOwner());
|
||||||
builder.append("Successfully unsubscribed from registry ["
|
builder.append("Successfully unsubscribed from registry ["
|
||||||
+ registryId + "]");
|
+ registryId + "]");
|
||||||
replicationManager.removeNotificationServer(registry.getBaseURL());
|
federationManager.removeNotificationServer(registry.getBaseURL());
|
||||||
replicationManager.saveNotificationServers();
|
federationManager.saveNotificationServers();
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
@ -421,9 +361,8 @@ public class RegistryFederationStatus {
|
||||||
builder.append(StringUtil.NEWLINE);
|
builder.append(StringUtil.NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReplicationManager(
|
public void setFederationManager(RegistryFederationManager federationManager) {
|
||||||
RegistryReplicationManager replicationManager) {
|
this.federationManager = federationManager;
|
||||||
this.replicationManager = replicationManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistryDao(RegistryDao registryDao) {
|
public void setRegistryDao(RegistryDao registryDao) {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!-- This file is intended to be overridden by sites. It contains the list of
|
||||||
|
registries that this registry wishes to subscribe to
|
||||||
|
|
||||||
|
The Registry site name is the WFO identifier of the target registry.
|
||||||
|
The registry description is an arbitrary description of that registry
|
||||||
|
The registry base URL is the base URL of the registry of the form http://HOST_NAME:8082
|
||||||
|
The reciprocate field instructs the target registry to subscribe to this registry.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<NotificationServers>
|
||||||
|
<!-- Default configuration for the NCF does not define any servers -->
|
||||||
|
<!-- These are defined at the site level -->
|
||||||
|
<!-- <registry>-->
|
||||||
|
<!-- <registrySiteName>SITE_NAME</registrySiteName>-->
|
||||||
|
<!-- <registryDescription>Description of registry</registryDescription>-->
|
||||||
|
<!-- <registryBaseURL>BASE_URL</registryBaseURL>-->
|
||||||
|
<!-- <reciprocate>false</reciprocate> -->
|
||||||
|
<!-- </registry>-->
|
||||||
|
</NotificationServers>
|
|
@ -6,10 +6,6 @@
|
||||||
<constructor-arg value="${EBXML_REGISTRY_FEDERATION_ENABLED}" />
|
<constructor-arg value="${EBXML_REGISTRY_FEDERATION_ENABLED}" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="ebxmlSubscriptionsEnabled" class="java.lang.Boolean">
|
|
||||||
<constructor-arg value="${EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED}" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="ebxmlEmailEnabled" class="java.lang.Boolean">
|
<bean id="ebxmlEmailEnabled" class="java.lang.Boolean">
|
||||||
<constructor-arg value="${ebxml-email.enabled}" />
|
<constructor-arg value="${ebxml-email.enabled}" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
<bean name="RegistrySubscriptionManager"
|
<bean name="RegistrySubscriptionManager"
|
||||||
class="com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager">
|
class="com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager">
|
||||||
<constructor-arg ref="ebxmlSubscriptionsEnabled" />
|
|
||||||
<property name="subscriptionDao" ref="subscriptionTypeDao" />
|
<property name="subscriptionDao" ref="subscriptionTypeDao" />
|
||||||
<property name="notificationManager" ref="RegistryNotificationManager" />
|
<property name="notificationManager" ref="RegistryNotificationManager" />
|
||||||
<property name="notificationListenerFactory" ref="notificationListenerFactory" />
|
<property name="notificationListenerFactory" ref="notificationListenerFactory" />
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
<list>
|
<list>
|
||||||
<bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
<bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
||||||
<property name="port" value="${EBXML_REGISTRY_WEBSERVER_PORT}" />
|
<property name="port" value="${EBXML_REGISTRY_WEBSERVER_PORT}" />
|
||||||
<property name="maxIdleTime" value="300000" />
|
<property name="maxIdleTime" value="5000" />
|
||||||
<property name="acceptors" value="2" />
|
<property name="acceptors" value="8" />
|
||||||
<property name="confidentialPort"
|
<property name="confidentialPort"
|
||||||
value="${EBXML_REGISTRY_WEBSERVER_CONFIDENTIAL_PORT}" />
|
value="${EBXML_REGISTRY_WEBSERVER_CONFIDENTIAL_PORT}" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
|
@ -13,5 +13,5 @@ ebxml-email.enabled=false
|
||||||
# in a registry replication notification
|
# in a registry replication notification
|
||||||
ebxml-notification-batch-size=50
|
ebxml-notification-batch-size=50
|
||||||
# Configuration of thread pool used to handle web service requests
|
# Configuration of thread pool used to handle web service requests
|
||||||
ebxml-webserver-min-threads=2
|
ebxml-webserver-min-threads=5
|
||||||
ebxml-webserver-max-threads=5
|
ebxml-webserver-max-threads=20
|
|
@ -19,7 +19,6 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.edex.registry.ebxml.services.notification;
|
package com.raytheon.uf.edex.registry.ebxml.services.notification;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -27,16 +26,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.datatype.Duration;
|
import javax.xml.datatype.Duration;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import javax.xml.transform.dom.DOMResult;
|
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
||||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.NotificationListener;
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.NotificationListener;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DateTimeValueType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DateTimeValueType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DeliveryInfoType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
||||||
|
|
||||||
|
@ -46,14 +41,9 @@ import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.raytheon.uf.common.registry.EbxmlNamespaces;
|
|
||||||
import com.raytheon.uf.common.registry.constants.DeliveryMethodTypes;
|
|
||||||
import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
|
import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
|
||||||
import com.raytheon.uf.common.registry.event.InsertRegistryEvent;
|
import com.raytheon.uf.common.registry.event.InsertRegistryEvent;
|
||||||
import com.raytheon.uf.common.registry.event.RemoveRegistryEvent;
|
import com.raytheon.uf.common.registry.event.RemoveRegistryEvent;
|
||||||
|
@ -88,6 +78,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||||
* 10/8/2013 1682 bphillip Moved getObjectsOfInterest into RegistryNotificationManager
|
* 10/8/2013 1682 bphillip Moved getObjectsOfInterest into RegistryNotificationManager
|
||||||
* 10/23/2013 1538 bphillip Removed debug code and added a change to properly update subscription run time
|
* 10/23/2013 1538 bphillip Removed debug code and added a change to properly update subscription run time
|
||||||
* to not create duplicate slots on objects
|
* to not create duplicate slots on objects
|
||||||
|
* 11/20/2013 2534 bphillip Moved method to get notification destinations to utility
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -150,9 +141,6 @@ public class RegistrySubscriptionManager implements
|
||||||
/** The XML endpointType tag */
|
/** The XML endpointType tag */
|
||||||
public static final String ENDPOINT_TAG = "endpointType";
|
public static final String ENDPOINT_TAG = "endpointType";
|
||||||
|
|
||||||
/** Status of whether subscriptions are being processed */
|
|
||||||
private boolean subscriptionProcessingEnabled;
|
|
||||||
|
|
||||||
/** The notification manager */
|
/** The notification manager */
|
||||||
private RegistryNotificationManager notificationManager;
|
private RegistryNotificationManager notificationManager;
|
||||||
|
|
||||||
|
@ -169,11 +157,6 @@ public class RegistrySubscriptionManager implements
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegistrySubscriptionManager(boolean subscriptionProcessingEnabled)
|
|
||||||
throws JAXBException {
|
|
||||||
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeAfterRegistryInit() throws EbxmlRegistryException {
|
public void executeAfterRegistryInit() throws EbxmlRegistryException {
|
||||||
for (SubscriptionType subscription : subscriptionDao.eagerLoadAll()) {
|
for (SubscriptionType subscription : subscriptionDao.eagerLoadAll()) {
|
||||||
|
@ -237,7 +220,8 @@ public class RegistrySubscriptionManager implements
|
||||||
try {
|
try {
|
||||||
List<NotificationListenerWrapper> listeners = Lists.newArrayList();
|
List<NotificationListenerWrapper> listeners = Lists.newArrayList();
|
||||||
// Get the list of destinations for the notifications
|
// Get the list of destinations for the notifications
|
||||||
final List<NotificationDestination> destinations = getNotificationDestinations(subscription);
|
final List<NotificationDestination> destinations = EbxmlObjectUtil
|
||||||
|
.getNotificationDestinations(subscription);
|
||||||
if (destinations.isEmpty()) {
|
if (destinations.isEmpty()) {
|
||||||
statusHandler.warn("No destinations found for notification!");
|
statusHandler.warn("No destinations found for notification!");
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,62 +241,11 @@ public class RegistrySubscriptionManager implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts where the notifications are to be sent from the subscription
|
|
||||||
* object
|
|
||||||
*
|
|
||||||
* @param subscription
|
|
||||||
* The subscriptions to get the delivery information from
|
|
||||||
* @return The list of destinations for the notifications
|
|
||||||
* @throws Exception
|
|
||||||
* If errors occur while extracting the destinations
|
|
||||||
*/
|
|
||||||
public List<NotificationDestination> getNotificationDestinations(
|
|
||||||
final SubscriptionType subscription) throws EbxmlRegistryException {
|
|
||||||
List<NotificationDestination> addresses = new ArrayList<NotificationDestination>();
|
|
||||||
|
|
||||||
List<DeliveryInfoType> deliveryInfos = subscription.getDeliveryInfo();
|
|
||||||
try {
|
|
||||||
for (DeliveryInfoType deliveryInfo : deliveryInfos) {
|
|
||||||
W3CEndpointReference endpointReference = deliveryInfo
|
|
||||||
.getNotifyTo();
|
|
||||||
DOMResult dom = new DOMResult();
|
|
||||||
endpointReference.writeTo(dom);
|
|
||||||
Document doc = (Document) dom.getNode();
|
|
||||||
NodeList nodes = doc.getElementsByTagNameNS(
|
|
||||||
EbxmlNamespaces.ADDRESSING_URI,
|
|
||||||
RegistrySubscriptionManager.ADDRESS_TAG);
|
|
||||||
Node addressNode = nodes.item(0);
|
|
||||||
String serviceAddress = addressNode.getTextContent().trim();
|
|
||||||
String endpointType = addressNode
|
|
||||||
.getAttributes()
|
|
||||||
.getNamedItemNS(EbxmlNamespaces.RIM_URI,
|
|
||||||
RegistrySubscriptionManager.ENDPOINT_TAG)
|
|
||||||
.getNodeValue();
|
|
||||||
final NotificationDestination destination = new NotificationDestination(
|
|
||||||
endpointType, serviceAddress);
|
|
||||||
if (endpointType.equals(DeliveryMethodTypes.EMAIL)) {
|
|
||||||
destination
|
|
||||||
.setEmailNotificationFormatter((String) deliveryInfo
|
|
||||||
.getSlotValue(EbxmlObjectUtil.EMAIL_NOTIFICATION_FORMATTER_SLOT));
|
|
||||||
}
|
|
||||||
addresses.add(destination);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new EbxmlRegistryException(
|
|
||||||
"Error getting destinations from subscription!", e);
|
|
||||||
}
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void processSubscriptions() {
|
public void processSubscriptions() {
|
||||||
if (!subscriptionProcessingEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!running.compareAndSet(false, true)) {
|
if (!running.compareAndSet(false, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||||
* 4/9/2013 1802 bphillip Changed abstract method signature, modified return processing, and changed static variables
|
* 4/9/2013 1802 bphillip Changed abstract method signature, modified return processing, and changed static variables
|
||||||
* Jun 24, 2013 2106 djohnson Requires a transaction to be open, will not create one.
|
* Jun 24, 2013 2106 djohnson Requires a transaction to be open, will not create one.
|
||||||
* 10/8/2013 1682 bphillip Refactored querying
|
* 10/8/2013 1682 bphillip Refactored querying
|
||||||
|
* 11/20/2013 2534 bphillip Changed call to getNotificationDestinations which is not in a utility class
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -102,7 +103,7 @@ public class GetNotification extends RegistryQueryPlugin {
|
||||||
|
|
||||||
List<NotificationDestination> destinations;
|
List<NotificationDestination> destinations;
|
||||||
try {
|
try {
|
||||||
destinations = subscriptionManager
|
destinations = EbxmlObjectUtil
|
||||||
.getNotificationDestinations(subscription);
|
.getNotificationDestinations(subscription);
|
||||||
} catch (EbxmlRegistryException e1) {
|
} catch (EbxmlRegistryException e1) {
|
||||||
throw EbxmlExceptionUtil.createMsgRegistryException(
|
throw EbxmlExceptionUtil.createMsgRegistryException(
|
||||||
|
|
|
@ -35,8 +35,10 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.xml.datatype.DatatypeConfigurationException;
|
import javax.xml.datatype.DatatypeConfigurationException;
|
||||||
import javax.xml.datatype.DatatypeFactory;
|
import javax.xml.datatype.DatatypeFactory;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
import javax.xml.transform.dom.DOMResult;
|
||||||
import javax.xml.ws.WebServiceContext;
|
import javax.xml.ws.WebServiceContext;
|
||||||
import javax.xml.ws.handler.MessageContext;
|
import javax.xml.ws.handler.MessageContext;
|
||||||
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DeliveryInfoType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DeliveryInfoType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ExtensibleObjectType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ExtensibleObjectType;
|
||||||
|
@ -46,11 +48,20 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ValueType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ValueType;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.registry.EbxmlNamespaces;
|
||||||
|
import com.raytheon.uf.common.registry.constants.DeliveryMethodTypes;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
import com.raytheon.uf.common.util.CollectionUtil;
|
import com.raytheon.uf.common.util.CollectionUtil;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.services.notification.NotificationDestination;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General utility class containing the ebXML object factories.
|
* General utility class containing the ebXML object factories.
|
||||||
|
@ -65,6 +76,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
* 3/18/2013 1082 bphillip Removed utility methods for VersionInfoType
|
* 3/18/2013 1082 bphillip Removed utility methods for VersionInfoType
|
||||||
* 4/9/2013 1802 bphillip Removed unused methods and addded a few new ones
|
* 4/9/2013 1802 bphillip Removed unused methods and addded a few new ones
|
||||||
* 8/1/2013 1693 bphillip Removed increment version method
|
* 8/1/2013 1693 bphillip Removed increment version method
|
||||||
|
* 11/20/2013 2534 bphillip Added getNotificationDestinations method
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -395,4 +407,53 @@ public class EbxmlObjectUtil {
|
||||||
}
|
}
|
||||||
return clientHost;
|
return clientHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts where the notifications are to be sent from the subscription
|
||||||
|
* object
|
||||||
|
*
|
||||||
|
* @param subscription
|
||||||
|
* The subscriptions to get the delivery information from
|
||||||
|
* @return The list of destinations for the notifications
|
||||||
|
* @throws Exception
|
||||||
|
* If errors occur while extracting the destinations
|
||||||
|
*/
|
||||||
|
public static List<NotificationDestination> getNotificationDestinations(
|
||||||
|
final SubscriptionType subscription) throws EbxmlRegistryException {
|
||||||
|
|
||||||
|
List<DeliveryInfoType> deliveryInfos = subscription.getDeliveryInfo();
|
||||||
|
List<NotificationDestination> addresses = new ArrayList<NotificationDestination>(
|
||||||
|
deliveryInfos.size());
|
||||||
|
try {
|
||||||
|
for (DeliveryInfoType deliveryInfo : deliveryInfos) {
|
||||||
|
W3CEndpointReference endpointReference = deliveryInfo
|
||||||
|
.getNotifyTo();
|
||||||
|
DOMResult dom = new DOMResult();
|
||||||
|
endpointReference.writeTo(dom);
|
||||||
|
Document doc = (Document) dom.getNode();
|
||||||
|
NodeList nodes = doc.getElementsByTagNameNS(
|
||||||
|
EbxmlNamespaces.ADDRESSING_URI,
|
||||||
|
RegistrySubscriptionManager.ADDRESS_TAG);
|
||||||
|
Node addressNode = nodes.item(0);
|
||||||
|
String serviceAddress = addressNode.getTextContent().trim();
|
||||||
|
String endpointType = addressNode
|
||||||
|
.getAttributes()
|
||||||
|
.getNamedItemNS(EbxmlNamespaces.RIM_URI,
|
||||||
|
RegistrySubscriptionManager.ENDPOINT_TAG)
|
||||||
|
.getNodeValue();
|
||||||
|
final NotificationDestination destination = new NotificationDestination(
|
||||||
|
endpointType, serviceAddress);
|
||||||
|
if (endpointType.equals(DeliveryMethodTypes.EMAIL)) {
|
||||||
|
destination
|
||||||
|
.setEmailNotificationFormatter((String) deliveryInfo
|
||||||
|
.getSlotValue(EbxmlObjectUtil.EMAIL_NOTIFICATION_FORMATTER_SLOT));
|
||||||
|
}
|
||||||
|
addresses.add(destination);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new EbxmlRegistryException(
|
||||||
|
"Error getting destinations from subscription!", e);
|
||||||
|
}
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<NotificationServers>
|
|
||||||
<!-- <registry> -->
|
|
||||||
<!-- <registrySiteName>DEV08</registrySiteName> -->
|
|
||||||
<!-- <registryDescription>Registry running on Ben's box</registryDescription> -->
|
|
||||||
<!-- <registryBaseURL>http://147.18.136.21:8082</registryBaseURL> -->
|
|
||||||
<!-- </registry> -->
|
|
||||||
</NotificationServers>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<NotificationServers>
|
|
||||||
<!-- Default configuration for the NCF does not define any servers -->
|
|
||||||
<!-- These are defined at the site level -->
|
|
||||||
<!-- <registry>-->
|
|
||||||
<!-- <registrySiteName>SITE_NAME</registrySiteName>-->
|
|
||||||
<!-- <registryDescription>Description of registry</registryDescription>-->
|
|
||||||
<!-- <registryBaseURL>BASE_URL</registryBaseURL>-->
|
|
||||||
<!-- </registry>-->
|
|
||||||
</NotificationServers>
|
|
Loading…
Add table
Reference in a new issue