Issue #2534 Added reciprocated registry replication subscriptions

Change-Id: I6844d65ccab6c4246f37ce212fa17af09851da27

Former-commit-id: 31b53f4ad9 [formerly f4144fca06 [formerly 212bbeb379] [formerly 31b53f4ad9 [formerly 2c52a6ee6f7d491d484c423359b8440975ad6d1e]]]
Former-commit-id: f4144fca06 [formerly 212bbeb379]
Former-commit-id: f4144fca06
Former-commit-id: 67f6ee0999
This commit is contained in:
Benjamin Phillippe 2013-11-20 10:25:23 -06:00
parent 04c1f9aa95
commit 64e533994c
29 changed files with 1549 additions and 1738 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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");

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
} }

View file

@ -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);
} }
} }

View file

@ -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;
}
}

View file

@ -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);
}
} }
} }

View file

@ -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) {

View file

@ -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>

View file

@ -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>

View file

@ -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" />

View file

@ -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>

View file

@ -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

View file

@ -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;
} }

View file

@ -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(

View file

@ -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;
}
} }

View file

@ -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>

View file

@ -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>