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
# Currently the registry is hosted on datadelivery, but this could be changed in the future
export EBXML_REGISTRY_HOST=${DATADELIVERY_HOST}
export EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED=false
export EBXML_REGISTRY_FEDERATION_ENABLED=false
export EBXML_REGISTRY_FEDERATION_ENABLED=true
# moved here from environment.xml
# 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.net.URL;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.xml.bind.JAXBElement;
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 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.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.raytheon.uf.common.comm.ProxyConfiguration;
import com.raytheon.uf.common.registry.RegistryJaxbManager;
import com.raytheon.uf.common.registry.RegistryNamespaceMapper;
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
* 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
* 11/20/2013 2534 bphillip Added HTTPClient policy for rest connections. Eliminated service caching.
* </pre>
*
* @author bphillip
@ -65,30 +67,30 @@ import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService
*/
public class RegistryRESTServices {
/** The url path to this set of services */
private static final String REGISTRY_REST_SERVICE_PATH = "/rest";
/** Map of known registry object request services */
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);
}
});
/** JAXB Manager */
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 {
jaxbManager = new RegistryJaxbManager(new RegistryNamespaceMapper());
}
@ -101,12 +103,8 @@ public class RegistryRESTServices {
* @return The service implementation
*/
public IRegistryObjectsRestService getRegistryObjectService(String baseURL) {
try {
return registryObjectServiceMap.get(baseURL);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting Registry Object Rest Service", e);
}
return getPort(baseURL + REGISTRY_REST_SERVICE_PATH,
IRegistryObjectsRestService.class);
}
/**
@ -143,12 +141,8 @@ public class RegistryRESTServices {
* @return The service implementation
*/
public IRepositoryItemsRestService getRepositoryItemService(String baseURL) {
try {
return repositoryItemServiceMap.get(baseURL);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting Repository Item Rest Service", e);
}
return getPort(baseURL + REGISTRY_REST_SERVICE_PATH,
IRepositoryItemsRestService.class);
}
/**
@ -192,8 +186,13 @@ public class RegistryRESTServices {
}
protected <T extends Object> T getPort(String url, Class<T> serviceClass) {
T service = JAXRSClientFactory.create(url, serviceClass);
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
client.header(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME,
RegistryUtil.LOCAL_REGISTRY_ADDRESS);

View file

@ -27,8 +27,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
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.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.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.ProxyUtil;
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
* 9/5/2013 1538 bphillip Add HTTP header information
* 10/30/2013 1538 bphillip Made methods in this class non-static
*
* 11/20/2013 2534 bphillip Eliminated service caching
* </pre>
*
* @author bphillip
@ -88,6 +83,12 @@ public class RegistrySOAPServices {
private static final IUFStatusHandler statusHandler = UFStatus
.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 */
private static final String PATH_SEPARATOR = "/";
@ -111,7 +112,7 @@ public class RegistrySOAPServices {
private static final ProxyConfiguration proxyConfig;
private static final HTTPClientPolicy httpClientPolicy;
protected static final HTTPClientPolicy httpClientPolicy;
static {
proxyConfig = getProxyConfiguration();
httpClientPolicy = new HTTPClientPolicy();
@ -123,7 +124,7 @@ public class RegistrySOAPServices {
statusHandler
.error("ebxml-http-receive-timeout not specified. Using default value of 1 minute",
e);
httpClientPolicy.setReceiveTimeout(60000);
httpClientPolicy.setReceiveTimeout(DEFAULT_RECEIVE_TIMEOUT);
}
try {
httpClientPolicy.setConnectionTimeout(Long.parseLong(System
@ -132,9 +133,9 @@ public class RegistrySOAPServices {
statusHandler
.error("ebxml-http-connection-timeout not specified. Using default value of 10 seconds",
e);
httpClientPolicy.setReceiveTimeout(10000);
httpClientPolicy.setConnectionTimeout(DEFAULT_CONNECT_TIMEOUT);
}
httpClientPolicy.setConnection(ConnectionType.KEEP_ALIVE);
httpClientPolicy.setConnection(ConnectionType.CLOSE);
httpClientPolicy.setMaxRetransmits(5);
if (proxyConfig != null) {
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
*
@ -209,11 +165,9 @@ public class RegistrySOAPServices {
* @param host
* The host to get the notification listener service for
* @return The notification listener service for the given host
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public NotificationListener getNotificationListenerServiceForHost(
final String host) throws RegistryServiceException {
final String host) {
return getNotificationListenerServiceForUrl(host + PATH_SEPARATOR
+ NOTIFICATION_SERVICE_NAME);
}
@ -224,17 +178,10 @@ public class RegistrySOAPServices {
* @param url
* The url
* @return The notification listener service at the given URL
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public NotificationListener getNotificationListenerServiceForUrl(
final String url) throws RegistryServiceException {
try {
return notificationManagerServices.get(url);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting notification service!", e);
}
return getPort(url, NotificationListener.class);
}
/**
@ -243,11 +190,8 @@ public class RegistrySOAPServices {
* @param host
* The host to get the lifecycle manager service for
* @return The lifecycle manager service for the given host
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public LifecycleManager getLifecycleManagerServiceForHost(final String host)
throws RegistryServiceException {
public LifecycleManager getLifecycleManagerServiceForHost(final String host) {
return getLifecycleManagerServiceForUrl(host + PATH_SEPARATOR
+ LIFECYCLE_MANAGER_SERVICE_NAME);
}
@ -258,17 +202,9 @@ public class RegistrySOAPServices {
* @param url
* The service URL
* @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)
throws RegistryServiceException {
try {
return lifecycleManagerServices.get(url);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting lifecycleManager service", e);
}
public LifecycleManager getLifecycleManagerServiceForUrl(final String url) {
return getPort(url, LifecycleManager.class);
}
/**
@ -277,11 +213,8 @@ public class RegistrySOAPServices {
* @param host
* The host to get the cataloger service for
* @return The cataloger service at the given host
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public Cataloger getCatalogerServiceForHost(final String host)
throws RegistryServiceException {
public Cataloger getCatalogerServiceForHost(final String host) {
return getCatalogerServiceForUrl(host + PATH_SEPARATOR
+ CATALOGER_SERVICE_NAME);
}
@ -292,17 +225,9 @@ public class RegistrySOAPServices {
* @param url
* the url string
* @return The cataloger service
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public Cataloger getCatalogerServiceForUrl(final String url)
throws RegistryServiceException {
try {
return catalogerServices.get(url);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting cataloger service!", e);
}
public Cataloger getCatalogerServiceForUrl(final String url) {
return getPort(url, Cataloger.class);
}
/**
@ -311,11 +236,8 @@ public class RegistrySOAPServices {
* @param host
* The host name
* @return The query manager service
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public QueryManager getQueryServiceForHost(final String host)
throws RegistryServiceException {
public QueryManager getQueryServiceForHost(final String host) {
return getQueryServiceForUrl(host + PATH_SEPARATOR + QUERY_SERVICE_NAME);
}
@ -325,17 +247,9 @@ public class RegistrySOAPServices {
* @param serviceUrl
* The 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)
throws RegistryServiceException {
try {
return queryServices.get(url);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error gett queryManager service!", e);
}
public QueryManager getQueryServiceForUrl(final String url) {
return getPort(url, QueryManager.class);
}
/**
@ -347,8 +261,7 @@ public class RegistrySOAPServices {
* @throws RegistryServiceException
* If errors occur creating the URL object
*/
public Validator getValidatorServiceForHost(final String host)
throws RegistryServiceException {
public Validator getValidatorServiceForHost(final String host) {
return getValidatorServiceForUrl(host + PATH_SEPARATOR
+ VALIDATOR_SERVICE_NAME);
}
@ -359,17 +272,10 @@ public class RegistrySOAPServices {
* @param serviceUrl
* The 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)
throws RegistryServiceException {
try {
return validatorServices.get(url);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting validator service!", e);
}
return getPort(url, Validator.class);
}
/**
@ -447,7 +353,7 @@ public class RegistrySOAPServices {
*
* @return The proxy configuration
*/
private static ProxyConfiguration getProxyConfiguration() {
protected static ProxyConfiguration getProxyConfiguration() {
ProxyConfiguration proxyConfig = null;
File proxyFile = PathManagerFactory.getPathManager().getStaticFile(
"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.reflections;bundle-version="0.9.9",
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

@ -3,9 +3,25 @@
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="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">
<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">
<list>
<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:Person</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>
</property>
</bean>
</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: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"
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">
<property name="registryDao" ref="registryDao"/>
<property name="subscriptionDao" ref="subscriptionTypeDao"/>
<property name="replicationManager" ref="RegistryReplicationManager"/>
<property name="federationManager" ref="RegistryFederationManager"/>
<property name="dataDeliveryRestClient" ref="dataDeliveryRestClient"/>
<property name="registrySoapServices" ref="registryWebServiceClient"/>
</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
* 6/4/2013 1707 bphillip Renamed and changed fields for clarity
* 11/20/2013 2534 bphillip Added reciprocate field
* </pre>
*
* @author bphillip
@ -55,6 +56,10 @@ public class NotificationHostConfiguration {
@XmlElement
private String registryBaseURL;
/** True if subscriptions should be reciprocated */
@XmlElement
private boolean reciprocate = false;
public NotificationHostConfiguration() {
}
@ -90,4 +95,11 @@ public class NotificationHostConfiguration {
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;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -54,17 +54,18 @@ public class NotificationServers {
/** The server located upstream from this server */
@XmlElements({ @XmlElement(name = "registry", type = NotificationHostConfiguration.class) })
private List<NotificationHostConfiguration> registryReplicationServers;
private CopyOnWriteArrayList<NotificationHostConfiguration> registryReplicationServers;
public List<NotificationHostConfiguration> getRegistryReplicationServers() {
if (registryReplicationServers == null) {
registryReplicationServers = new ArrayList<NotificationHostConfiguration>();
registryReplicationServers = new CopyOnWriteArrayList<NotificationHostConfiguration>();
}
return registryReplicationServers;
}
public void setRegistryReplicationServers(
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;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.xml.bind.JAXBException;
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.IRegistryDataAccessService;
import com.raytheon.uf.common.datadelivery.registry.web.IRegistryFederationService;
import com.raytheon.uf.common.registry.constants.RegistryAvailability;
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.UFStatus;
@ -47,6 +41,7 @@ import com.raytheon.uf.common.status.UFStatus;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 10/30/2013 1538 bphillip Initial Creation
* 11/20/2013 2534 bphillip Eliminated service caching
* </pre>
*
* @author bphillip
@ -63,30 +58,15 @@ public class DataDeliveryRESTServices extends RegistryRESTServices {
private static final IUFStatusHandler statusHandler = UFStatus
.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 {
super();
}
public IRegistryFederationService getFederationService(String baseURL) {
return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH,
IRegistryFederationService.class);
}
/**
* Gets the registry available service implementation
*
@ -96,12 +76,8 @@ public class DataDeliveryRESTServices extends RegistryRESTServices {
*/
public IRegistryAvailableRestService getRegistryAvailableService(
String baseURL) {
try {
return registryAvailabilityServiceMap.get(baseURL);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting Registry Availability Rest Service", e);
}
return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH,
IRegistryAvailableRestService.class);
}
/**
@ -142,11 +118,8 @@ public class DataDeliveryRESTServices extends RegistryRESTServices {
*/
public IRegistryDataAccessService getRegistryDataAccessService(
String baseURL) {
try {
return registryDataAccessServiceMap.get(baseURL);
} catch (ExecutionException e) {
throw new RegistryServiceException(
"Error getting Registry Availability Rest Service", e);
}
return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH,
IRegistryDataAccessService.class);
}
}

View file

@ -27,6 +27,7 @@ import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.xml.bind.JAXBException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
@ -46,6 +47,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.Node;
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.constants.AssociationTypes;
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.ebxml.RegistryUtil;
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.UFStatus;
import com.raytheon.uf.common.util.CollectionUtil;
import com.raytheon.uf.common.util.StringUtil;
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.RegistryReplicationManager;
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.services.notification.RegistrySubscriptionManager;
@ -75,17 +77,15 @@ import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 10/30/2013 1538 bphillip Initial Creation
* 11/20/2013 2534 bphillip Added interface
* </pre>
*
* @author bphillip
* @version 1
**/
@Path(RegistryFederationStatus.REGISTRY_FEDERATION_STATUS_PATH)
@Path(IRegistryFederationService.REGISTRY_FEDERATION_STATUS_PATH)
@Transactional
public class RegistryFederationStatus {
/** The path to these set of services */
protected static final String REGISTRY_FEDERATION_STATUS_PATH = "/status/";
public class RegistryFederationStatus implements IRegistryFederationService {
/** The logger instance */
private static final IUFStatusHandler statusHandler = UFStatus
@ -106,7 +106,7 @@ public class RegistryFederationStatus {
private SubscriptionDao subscriptionDao;
/** The registry replication manager */
private RegistryReplicationManager replicationManager;
private RegistryFederationManager federationManager;
/** Data Delivery rest services client */
private DataDeliveryRESTServices dataDeliveryRestClient;
@ -120,35 +120,18 @@ public class RegistryFederationStatus {
*/
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
@Path("isFederated")
public String isFederated() {
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
@Path("isProcessingSubscriptions")
public String isProcessingSubscriptions() {
return System.getenv("EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED");
}
/**
* Gets information about this registry
*
* @return Information pertaining to the local registry
*/
@GET
@Path("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
@Path("getFederationMembers")
public String getFederationMembers() throws MsgRegistryException {
@ -199,20 +175,15 @@ public class RegistryFederationStatus {
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
@Path("getRegistriesSubscribedTo")
public String getRegistriesSubscribedTo() {
StringBuilder builder = new StringBuilder();
if (this.replicationManager.getServers() != null
&& !CollectionUtil.isNullOrEmpty(this.replicationManager
if (this.federationManager.getServers() != null
&& !CollectionUtil.isNullOrEmpty(this.federationManager
.getServers().getRegistryReplicationServers())) {
List<RegistryObjectType> registries = new ArrayList<RegistryObjectType>();
for (NotificationHostConfiguration hostConfig : this.replicationManager
for (NotificationHostConfiguration hostConfig : this.federationManager
.getServers().getRegistryReplicationServers()) {
SlotType queryLanguageSlot = new SlotType(
@ -259,11 +230,6 @@ public class RegistryFederationStatus {
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
@Path("getRegistrySubscribing")
public String getRegistrySubscribing() {
@ -302,28 +268,16 @@ public class RegistryFederationStatus {
return builder.toString();
}
/**
* Gets the list of object types that are currently being replicated
*
* @return The object list
*/
@GET
@Path("getObjectTypesReplicated")
public String getObjectTypesReplicated() {
StringBuilder builder = new StringBuilder();
for (String objectType : RegistryReplicationManager.getObjectTypes()) {
for (String objectType : RegistryFederationManager.getObjectTypes()) {
builder.append(objectType).append(StringUtil.NEWLINE);
}
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
@Path("syncWithRegistry/{registryId}")
public String syncWithRegistry(@PathParam("registryId") String registryId) {
@ -334,7 +288,7 @@ public class RegistryFederationStatus {
+ "] not in federation. Unable to synchronize.");
} else {
try {
replicationManager.synchronizeRegistryWithFederation(registry
federationManager.synchronizeRegistryWithFederation(registry
.getBaseURL());
} catch (Exception e) {
statusHandler.error("Error synchronizing registry!", e);
@ -345,43 +299,29 @@ public class RegistryFederationStatus {
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
@Path("subscribeToRegistry/{registryId}")
public String subscribeToRegistry(@PathParam("registryId") String registryId) {
public String subscribeToRegistry(@PathParam("registryId") String registryId)
throws RegistryServiceException, JAXBException {
StringBuilder builder = new StringBuilder();
RegistryType registry = registryDao.getById(registryId);
RegistryType registry = dataDeliveryRestClient.getRegistryObject(
RegistryType.class, ncfAddress, registryId);
if (registry == null) {
builder.append("Registry [" + registryId
+ "] not in federation. Unable to submit subscriptions.");
builder.append("Registry [")
.append(registryId)
.append("] not in federation. Unable to submit subscriptions.");
} else {
RegistryType localRegistry = registryDao
.getRegistryByBaseURL(RegistryUtil.LOCAL_REGISTRY_ADDRESS);
NotificationHostConfiguration config = new NotificationHostConfiguration(
registry.getId(), registry.getId(), registry.getBaseURL());
replicationManager.submitSubscriptionsToHost(config, localRegistry);
builder.append("Successfully subscribed to registry [" + registryId
+ "]");
this.replicationManager.addNotificationServer(config);
replicationManager.saveNotificationServers();
if (!federationManager.isSubscribedTo(registry)) {
federationManager.submitSubscriptionsToRegistry(registry);
builder.append("Successfully subscribed to registry [")
.append(registryId).append("]");
this.federationManager.addNotificationServer(registry);
federationManager.saveNotificationServers();
}
}
return builder.toString();
}
/**
* 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(
@ -399,8 +339,8 @@ public class RegistryFederationStatus {
localRegistry.getOwner());
builder.append("Successfully unsubscribed from registry ["
+ registryId + "]");
replicationManager.removeNotificationServer(registry.getBaseURL());
replicationManager.saveNotificationServers();
federationManager.removeNotificationServer(registry.getBaseURL());
federationManager.saveNotificationServers();
}
return builder.toString();
}
@ -421,9 +361,8 @@ public class RegistryFederationStatus {
builder.append(StringUtil.NEWLINE);
}
public void setReplicationManager(
RegistryReplicationManager replicationManager) {
this.replicationManager = replicationManager;
public void setFederationManager(RegistryFederationManager federationManager) {
this.federationManager = federationManager;
}
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}" />
</bean>
<bean id="ebxmlSubscriptionsEnabled" class="java.lang.Boolean">
<constructor-arg value="${EBXML_REGISTRY_SUBSCRIPTIONS_ENABLED}" />
</bean>
<bean id="ebxmlEmailEnabled" class="java.lang.Boolean">
<constructor-arg value="${ebxml-email.enabled}" />
</bean>

View file

@ -22,7 +22,6 @@
<bean name="RegistrySubscriptionManager"
class="com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager">
<constructor-arg ref="ebxmlSubscriptionsEnabled" />
<property name="subscriptionDao" ref="subscriptionTypeDao" />
<property name="notificationManager" ref="RegistryNotificationManager" />
<property name="notificationListenerFactory" ref="notificationListenerFactory" />

View file

@ -16,8 +16,8 @@
<list>
<bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<property name="port" value="${EBXML_REGISTRY_WEBSERVER_PORT}" />
<property name="maxIdleTime" value="300000" />
<property name="acceptors" value="2" />
<property name="maxIdleTime" value="5000" />
<property name="acceptors" value="8" />
<property name="confidentialPort"
value="${EBXML_REGISTRY_WEBSERVER_CONFIDENTIAL_PORT}" />
</bean>

View file

@ -13,5 +13,5 @@ ebxml-email.enabled=false
# in a registry replication notification
ebxml-notification-batch-size=50
# Configuration of thread pool used to handle web service requests
ebxml-webserver-min-threads=2
ebxml-webserver-max-threads=5
ebxml-webserver-min-threads=5
ebxml-webserver-max-threads=20

View file

@ -19,7 +19,6 @@
**/
package com.raytheon.uf.edex.registry.ebxml.services.notification;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
@ -27,16 +26,12 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.bind.JAXBException;
import javax.xml.datatype.Duration;
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.NotificationListener;
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.SubscriptionType;
@ -46,14 +41,9 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
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.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.event.InsertRegistryEvent;
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/23/2013 1538 bphillip Removed debug code and added a change to properly update subscription run time
* to not create duplicate slots on objects
* 11/20/2013 2534 bphillip Moved method to get notification destinations to utility
* </pre>
*
* @author bphillip
@ -150,9 +141,6 @@ public class RegistrySubscriptionManager implements
/** The XML endpointType tag */
public static final String ENDPOINT_TAG = "endpointType";
/** Status of whether subscriptions are being processed */
private boolean subscriptionProcessingEnabled;
/** The notification manager */
private RegistryNotificationManager notificationManager;
@ -169,11 +157,6 @@ public class RegistrySubscriptionManager implements
}
public RegistrySubscriptionManager(boolean subscriptionProcessingEnabled)
throws JAXBException {
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
}
@Override
public void executeAfterRegistryInit() throws EbxmlRegistryException {
for (SubscriptionType subscription : subscriptionDao.eagerLoadAll()) {
@ -237,7 +220,8 @@ public class RegistrySubscriptionManager implements
try {
List<NotificationListenerWrapper> listeners = Lists.newArrayList();
// Get the list of destinations for the notifications
final List<NotificationDestination> destinations = getNotificationDestinations(subscription);
final List<NotificationDestination> destinations = EbxmlObjectUtil
.getNotificationDestinations(subscription);
if (destinations.isEmpty()) {
statusHandler.warn("No destinations found for notification!");
} 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}
*/
@Override
public void processSubscriptions() {
if (!subscriptionProcessingEnabled) {
return;
}
if (!running.compareAndSet(false, true)) {
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
* Jun 24, 2013 2106 djohnson Requires a transaction to be open, will not create one.
* 10/8/2013 1682 bphillip Refactored querying
* 11/20/2013 2534 bphillip Changed call to getNotificationDestinations which is not in a utility class
*
* </pre>
*
@ -102,7 +103,7 @@ public class GetNotification extends RegistryQueryPlugin {
List<NotificationDestination> destinations;
try {
destinations = subscriptionManager
destinations = EbxmlObjectUtil
.getNotificationDestinations(subscription);
} catch (EbxmlRegistryException e1) {
throw EbxmlExceptionUtil.createMsgRegistryException(

View file

@ -35,8 +35,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.WebServiceContext;
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.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.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.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.util.CollectionUtil;
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.
@ -65,6 +76,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
* 3/18/2013 1082 bphillip Removed utility methods for VersionInfoType
* 4/9/2013 1802 bphillip Removed unused methods and addded a few new ones
* 8/1/2013 1693 bphillip Removed increment version method
* 11/20/2013 2534 bphillip Added getNotificationDestinations method
*
* </pre>
*
@ -395,4 +407,53 @@ public class EbxmlObjectUtil {
}
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>