diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/web/IRegistryFederationManager.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/web/IRegistryFederationManager.java new file mode 100644 index 0000000000..460c40fe65 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/web/IRegistryFederationManager.java @@ -0,0 +1,109 @@ +/** + * 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; + +/** + * + * Interface for the registry federation manager for exposing web services for + * the web interface + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 2/27/2014    2769        bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +@Path(IRegistryFederationManager.REGISTRY_FEDERATION_MANAGER_PATH) +public interface IRegistryFederationManager { + + /** The path to these set of services */ + public static final String REGISTRY_FEDERATION_MANAGER_PATH = "/federation/"; + + /** + * 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(); + + @GET + @Path("dataDeliveryId") + public String dataDeliveryId(); + + @GET + @Path("siteId") + public String siteId(); + + @GET + @Path("getObjectTypesReplicated") + public String getObjectTypesReplicated(); + + @GET + @Path("getFederationMembers") + public String getFederationMembers() throws Exception; + + @GET + @Path("getReplicatingTo") + public String getReplicatingTo(); + + @GET + @Path("getReplicatingFrom") + public String getReplicatingFrom() throws Exception; + + @GET + @Path("subscribeToRegistry/{registryId}") + public void subscribeToRegistry(@PathParam("registryId") String registryId) + throws Exception; + + @GET + @Path("unsubscribeFromRegistry/{registryId}") + public void unsubscribeFromRegistry( + @PathParam("registryId") String registryId) throws Exception; + + @GET + @Path("addReplicationServer/{registryId}") + public void addReplicationServer(@PathParam("registryId") String registryId) + throws Exception; + + @GET + @Path("removeReplicationServer/{registryId}") + public void removeReplicationServer( + @PathParam("registryId") String registryId) throws Exception; + + @GET + @Path("synchronizeWithRegistry/{registryId}") + public void synchronizeWithRegistry( + @PathParam("registryId") String registryId) throws Exception; + +} diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/web/IRegistryFederationService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/web/IRegistryFederationService.java deleted file mode 100644 index bbcde6d0b9..0000000000 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/web/IRegistryFederationService.java +++ /dev/null @@ -1,145 +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.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; - -/** - *
- * Interface for Registry federation status
- *  
- *  SOFTWARE HISTORY
- *  
- *  Date         Ticket#     Engineer    Description
- *  ------------ ----------  ----------- --------------------------
- *  11/20/2013   2534        bphillip    Initial Creation
- * 
- * - * @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 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); - -} diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java index 685acdcdc4..a04c4019ae 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java @@ -62,6 +62,7 @@ import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService * 11/20/2013 2534 bphillip Added HTTPClient policy for rest connections. Eliminated service caching. * 12/2/2013 1829 bphillip Removed expectedType argument on getRegistryObject method * 1/15/2014 2613 bphillip Removed Service cache due to unexpected behavior + * 2/19/2014 2769 bphillip Added service cache * * * @author bphillip @@ -105,7 +106,7 @@ public class RegistryRESTServices { * @return The service implementation */ public IRegistryObjectsRestService getRegistryObjectService(String baseURL) { - return getPort(baseURL + REGISTRY_REST_SERVICE_PATH, + return createService(baseURL + REGISTRY_REST_SERVICE_PATH, IRegistryObjectsRestService.class); } @@ -142,7 +143,7 @@ public class RegistryRESTServices { * @return The service implementation */ public IRepositoryItemsRestService getRepositoryItemService(String baseURL) { - return getPort(baseURL + REGISTRY_REST_SERVICE_PATH, + return createService(baseURL + REGISTRY_REST_SERVICE_PATH, IRepositoryItemsRestService.class); } @@ -171,7 +172,8 @@ public class RegistryRESTServices { public Object accessXMLRestService(String url) { String response = null; try { - response = Resources.toString(new URL(url), Charset.forName("UTF8")); + response = Resources + .toString(new URL(url), Charset.forName("UTF8")); } catch (Exception e) { throw new RegistryServiceException( "Error accessing REST service at URL: [" + url + "]", e); @@ -185,11 +187,6 @@ public class RegistryRESTServices { } } - protected T getPort(String serviceUrl, - final Class serviceInterface) { - return createService(serviceUrl, serviceInterface); - } - protected T createService(String url, Class serviceClass) { T service = JAXRSClientFactory.create(url, serviceClass); diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java index bf82d70bc6..5e9ef91209 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java @@ -73,6 +73,7 @@ import com.raytheon.uf.common.status.UFStatus; * 10/30/2013 1538 bphillip Made methods in this class non-static * 11/20/2013 2534 bphillip Eliminated service caching * 1/15/2014 2613 bphillip Eliminated service caching...again + * 2/19/2014 2769 bphillip Renamed getPort method * * * @author bphillip @@ -81,37 +82,37 @@ import com.raytheon.uf.common.status.UFStatus; public class RegistrySOAPServices { /** The logger */ - private static final IUFStatusHandler statusHandler = UFStatus + protected static final IUFStatusHandler statusHandler = UFStatus .getHandler(RegistrySOAPServices.class); /** Default timeout for receiving HTTP data */ - private static final long DEFAULT_RECEIVE_TIMEOUT = 60000; + protected static final long DEFAULT_RECEIVE_TIMEOUT = 60000; /** Default value for establishing an HTTP connection */ - private static final long DEFAULT_CONNECT_TIMEOUT = 10000; + protected static final long DEFAULT_CONNECT_TIMEOUT = 10000; /** Path separator */ - private static final String PATH_SEPARATOR = "/"; + protected static final String PATH_SEPARATOR = "/"; /** WSDL suffix */ - private static final String WSDL = "?wsdl"; + protected static final String WSDL = "?wsdl"; /** The name of the notification listener service */ - private static final String NOTIFICATION_SERVICE_NAME = "notificationListener"; + protected static final String NOTIFICATION_SERVICE_NAME = "notificationListener"; /** The name of the lifecycle manager service */ - private static final String LIFECYCLE_MANAGER_SERVICE_NAME = "lifecycleManager"; + protected static final String LIFECYCLE_MANAGER_SERVICE_NAME = "lifecycleManager"; /** The name of the cataloger service */ - private static final String CATALOGER_SERVICE_NAME = "cataloger"; + protected static final String CATALOGER_SERVICE_NAME = "cataloger"; /** The name of the query service */ - private static final String QUERY_SERVICE_NAME = "queryManager"; + protected static final String QUERY_SERVICE_NAME = "queryManager"; /** The name of the validator service */ - private static final String VALIDATOR_SERVICE_NAME = "validator"; + protected static final String VALIDATOR_SERVICE_NAME = "validator"; - private static final ProxyConfiguration proxyConfig; + protected static final ProxyConfiguration proxyConfig; protected static final HTTPClientPolicy httpClientPolicy; @@ -187,7 +188,7 @@ public class RegistrySOAPServices { */ public NotificationListener getNotificationListenerServiceForUrl( final String url) throws RegistryServiceException { - return getPort(url, NotificationListener.class); + return createService(url, NotificationListener.class); } /** @@ -210,7 +211,7 @@ public class RegistrySOAPServices { * @return The lifecycle manager service at the given URL string */ public LifecycleManager getLifecycleManagerServiceForUrl(final String url) { - return getPort(url, LifecycleManager.class); + return createService(url, LifecycleManager.class); } /** @@ -233,7 +234,7 @@ public class RegistrySOAPServices { * @return The cataloger service */ public Cataloger getCatalogerServiceForUrl(final String url) { - return getPort(url, Cataloger.class); + return createService(url, Cataloger.class); } /** @@ -255,7 +256,7 @@ public class RegistrySOAPServices { * @return The query manager service at the given url string */ public QueryManager getQueryServiceForUrl(final String url) { - return getPort(url, QueryManager.class); + return createService(url, QueryManager.class); } /** @@ -281,7 +282,7 @@ public class RegistrySOAPServices { */ public Validator getValidatorServiceForUrl(final String url) throws RegistryServiceException { - return getPort(url, Validator.class); + return createService(url, Validator.class); } /** @@ -336,7 +337,7 @@ public class RegistrySOAPServices { } @SuppressWarnings("unchecked") - private T createService(String serviceUrl, + protected T createService(String serviceUrl, Class serviceInterface) throws RegistryServiceException { W3CEndpointReferenceBuilder endpointBuilder = new W3CEndpointReferenceBuilder(); endpointBuilder.wsdlDocumentLocation(serviceUrl.toString() + WSDL); @@ -354,11 +355,6 @@ public class RegistrySOAPServices { return port; } - private T getPort(String serviceUrl, - final Class serviceInterface) { - return createService(serviceUrl, serviceInterface); - } - /** * Gets the proxy configuration * diff --git a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/wsdl/registry/services/v4/QueryManager.java b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/wsdl/registry/services/v4/QueryManager.java index 61aeed51a3..a6d74baf7a 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/wsdl/registry/services/v4/QueryManager.java +++ b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/wsdl/registry/services/v4/QueryManager.java @@ -31,6 +31,8 @@ import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest; import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse; import org.apache.cxf.annotations.FastInfoset; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.registry.EbxmlNamespaces; @@ -44,6 +46,7 @@ import com.raytheon.uf.common.registry.EbxmlNamespaces; * 2012 bphillip Initial implementation * 10/17/2013 1682 bphillip Added software history * 12/9/2013 2613 bphillip Changed to use FastInfoset + * 2/19/2014 2769 bphillip Added Transactional annotation to executeQuery method * * * @author bphillip @@ -71,6 +74,7 @@ public interface QueryManager { */ @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException; diff --git a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/ISessionManagedDao.java b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/ISessionManagedDao.java index 9a18ade7ec..311e23de1a 100644 --- a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/ISessionManagedDao.java +++ b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/ISessionManagedDao.java @@ -37,6 +37,7 @@ import com.raytheon.uf.common.dataplugin.persist.IPersistableDataObject; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Feb 13, 2013 1543 djohnson Initial creation + * 2/19/2014 2769 bphillip Added loadById method * * * @@ -110,6 +111,17 @@ public interface ISessionManagedDao * @@ -148,21 +149,34 @@ public abstract class SessionManagedDao entityClass = getEntityClass(); return entityClass.cast(template.get(entityClass, id)); } + @Override + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) + public ENTITY loadById(IDENTIFIER id) { + final Class entityClass = getEntityClass(); + return entityClass.cast(template.load(entityClass, id)); + } + /** * {@inheritDoc} */ @Override - @Transactional(propagation = Propagation.REQUIRED) + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAll() { return query("from " + getEntityClass().getSimpleName()); } + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) + public List loadAll() { + return this.template.loadAll(getEntityClass()); + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public ENTITY uniqueResult(String queryString) { return uniqueResult(queryString, new Object[0]); } @@ -174,7 +188,7 @@ public abstract class SessionManagedDao results = executeHQLQuery(queryString, params); if (results.isEmpty()) { @@ -186,6 +200,7 @@ public abstract class SessionManagedDao query(String queryString) { return executeHQLQuery(queryString); } @@ -197,12 +212,12 @@ public abstract class SessionManagedDao query(String queryString, Object... params) { return executeHQLQuery(queryString, 0, params); } - @Transactional(propagation = Propagation.REQUIRED) + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List query(String queryString, Integer maxResults, Object... params) { return executeHQLQuery(queryString, maxResults, params); @@ -220,7 +235,7 @@ public abstract class SessionManagedDao List executeHQLQuery(String queryString) { return executeHQLQuery(queryString, 0); } @@ -242,7 +257,7 @@ public abstract class SessionManagedDao List executeHQLQuery(String queryString, Object... params) { return executeHQLQuery(queryString, 0, params); @@ -270,7 +285,7 @@ public abstract class SessionManagedDao List executeHQLQuery(final String queryString, Integer maxResults, Object... params) { if (params.length % 2 != 0) { @@ -297,7 +312,7 @@ public abstract class SessionManagedDao Iterator getQueryIterator( final String queryString, Object... params) { if (params.length == 0) { @@ -391,7 +406,7 @@ public abstract class SessionManagedDao List executeCriteriaQuery( final DetachedCriteria criteria) { if (criteria == null) { @@ -404,6 +419,11 @@ public abstract class SessionManagedDao + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml index 792e13219a..47f4fcb0e9 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml @@ -4,18 +4,28 @@ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - + + + + + + + + - - - - + - + + + + + + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/webservices.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/webservices.xml index ca45f6f03e..fe9e466e9c 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/webservices.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/webservices.xml @@ -23,19 +23,21 @@ - - - - - - - - + + + + + + + + + + @@ -45,7 +47,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/availability/FederatedRegistryMonitor.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/availability/FederatedRegistryMonitor.java index 4f89ab97c2..23b4df24ad 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/availability/FederatedRegistryMonitor.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/availability/FederatedRegistryMonitor.java @@ -26,14 +26,13 @@ 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.VersionInfoType; -import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.registry.constants.StatusTypes; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.time.util.TimeUtil; -import com.raytheon.uf.edex.database.RunnableWithTransaction; 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.util.EbxmlObjectUtil; @@ -53,12 +52,14 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * ------------ ---------- ----------- -------------------------- * 7/29/2013 2191 bphillip Initial implementation * 12/2/2013 1829 bphillip Uses correct getter for getting date time value + * 2/19/2014 2769 bphillip Refactored to no longer extend Runnable * * * @author bphillip * @version 1 */ -public class FederatedRegistryMonitor extends RunnableWithTransaction { +@Transactional +public class FederatedRegistryMonitor { /** The logger instance */ private static final IUFStatusHandler statusHandler = UFStatus @@ -74,9 +75,7 @@ public class FederatedRegistryMonitor extends RunnableWithTransaction { super(); } - public FederatedRegistryMonitor(TransactionTemplate txTemplate, - RegistryObjectDao registryObjectDao) { - super(txTemplate); + public FederatedRegistryMonitor(RegistryObjectDao registryObjectDao) { this.registryObjectDao = registryObjectDao; } @@ -95,9 +94,9 @@ public class FederatedRegistryMonitor extends RunnableWithTransaction { return cal.getTimeInMillis(); } - @Override - public void runWithTransaction() { + public void updateTime() { try { + statusHandler.info("Updating registry uptime"); RegistryObjectType regObj = registryObjectDao .getById(REGISTRY_AVAILABLE_ID); if (regObj == null) { diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java new file mode 100644 index 0000000000..96f75328e9 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java @@ -0,0 +1,60 @@ +/** + * 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.dao; + +import java.util.List; + +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import com.raytheon.uf.edex.database.dao.SessionManagedDao; +import com.raytheon.uf.edex.datadelivery.registry.federation.ReplicationEvent; + +/** + *
+ * 
+ * Data Access object for interactions with ReplicationEvent objects
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 2/19/2014    2769       bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class ReplicationEventDao extends + SessionManagedDao { + + private static final String GET_REPLICATION_EVENT_QUERY = "from ReplicationEvent event where (event.source is null or event.source != '%s') and (event.replicatedTo is null or event.replicatedTo not like '%%%s%%') order by event.eventTime asc"; + + @Override + protected Class getEntityClass() { + return ReplicationEvent.class; + } + + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) + public List getReplicationEvents(String remoteRegistry) { + return this.executeHQLQuery(String.format(GET_REPLICATION_EVENT_QUERY, + remoteRegistry, remoteRegistry)); + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationDbInit.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationDbInit.java new file mode 100644 index 0000000000..fdc3393a84 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationDbInit.java @@ -0,0 +1,65 @@ +/** + * 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 org.hibernate.cfg.AnnotationConfiguration; + +import com.raytheon.uf.edex.database.init.DbInit; + +/** + *
+ * 
+ * Creates the database tables necessary for federation replication to function
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 2/19/2014    2769       bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class FederationDbInit extends DbInit { + + /** Query to check which tables exist in the ebxml database */ + private static final String TABLE_CHECK_QUERY = "SELECT tablename FROM pg_tables where schemaname = 'awips' and tablename='registryreplicationevents';"; + + protected FederationDbInit() { + super("Data Delivery Federation"); + } + + @Override + protected String getTableCheckQuery() { + return TABLE_CHECK_QUERY; + } + + @Override + protected AnnotationConfiguration getAnnotationConfiguration() { + /* + * Create a new configuration object which holds all the classes that + * this Hibernate SessionFactory is aware of + */ + AnnotationConfiguration aConfig = new AnnotationConfiguration(); + aConfig.addAnnotatedClass(ReplicationEvent.class); + return aConfig; + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationProperties.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationProperties.java index 133bdc5098..c5ddfc87ba 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationProperties.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/FederationProperties.java @@ -25,6 +25,8 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.datatype.Duration; +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.PersonNameType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.PersonType; @@ -32,6 +34,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.PostalAddressType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.TelephoneNumberType; +import com.raytheon.uf.common.registry.constants.AssociationTypes; import com.raytheon.uf.common.registry.constants.RegistryObjectTypes; import com.raytheon.uf.common.registry.constants.StatusTypes; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; @@ -50,6 +53,7 @@ import com.raytheon.uf.edex.datadelivery.util.DataDeliveryIdUtil; * ------------ ---------- ----------- -------------------------- * 5/22/2013 1707 bphillip Initial implementation * Feb 11, 2014 2771 bgonzale Removed siteIdentifier field and use Data Delivery ID instead. + * 2/19/2014 2769 bphillip Moved getFederationAssociation from RegistryFederationManager * * * @author bphillip @@ -59,6 +63,9 @@ import com.raytheon.uf.edex.datadelivery.util.DataDeliveryIdUtil; @XmlAccessorType(XmlAccessType.FIELD) public class FederationProperties { + /** Constant used for names of registries in the registry database */ + public static final String REGISTRY_SUFFIX = " Registry"; + /** * A RegistryType instance MAY have an attribute named conformanceProfile * that declares the conformance profile that the server supports. The @@ -180,11 +187,11 @@ public class FederationProperties { */ public RegistryType createRegistryObject() { RegistryType registryObj = new RegistryType(); - registryObj.setId(DataDeliveryIdUtil.getId() + " Registry"); + registryObj.setId(DataDeliveryIdUtil.getId() + REGISTRY_SUFFIX); registryObj.setLid(registryObj.getId()); registryObj.setName(RegistryUtil .getInternationalString(DataDeliveryIdUtil.getId() - + " Registry Specification")); + + " Registry Specification")); registryObj.setObjectType(RegistryObjectTypes.REGISTRY); registryObj.setDescription(registryObj.getName()); registryObj.setOwner(DataDeliveryIdUtil.getId()); @@ -271,6 +278,24 @@ public class FederationProperties { return siteAddress; } + protected AssociationType getFederationAssociation(RegistryType registry, + FederationType federation) { + AssociationType association = new AssociationType(); + association.setId(registry.getId() + + " Federation Membership Association"); + association.setLid(association.getId()); + association.setObjectType(RegistryObjectTypes.ASSOCIATION); + association.setOwner(DataDeliveryIdUtil.getId()); + association.setType(AssociationTypes.HAS_FEDERATION_MEMBER); + association.setStatus(StatusTypes.APPROVED); + association.setName(RegistryUtil.getInternationalString(registry + .getId() + " Federation Membership")); + association.setDescription(association.getName()); + association.setTargetObject(registry.getId()); + association.setSourceObject(federation.getId()); + return association; + } + public String getConformanceProfile() { return conformanceProfile; } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java index 9baa000d14..b4b386c947 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java @@ -20,62 +20,52 @@ package com.raytheon.uf.edex.datadelivery.registry.federation; import java.io.File; -import java.math.BigInteger; +import java.io.FileNotFoundException; +import java.net.URLEncoder; +import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; 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.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; 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.wsdl.registry.services.v4.LifecycleManager; import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException; -import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.QueryManager; import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode; import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.RemoveObjectsRequest; import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest; -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.DeliveryInfoType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.FederationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefListType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType; 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.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.stereotype.Service; import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; 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.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.datadelivery.registry.web.IRegistryFederationManager; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; @@ -83,14 +73,8 @@ 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.AssociationTypes; -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.QueryReturnTypes; +import com.raytheon.uf.common.registry.constants.ActionTypes; +import com.raytheon.uf.common.registry.constants.DeletionScope; import com.raytheon.uf.common.registry.constants.RegistryObjectTypes; import com.raytheon.uf.common.registry.constants.StatusTypes; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; @@ -103,20 +87,21 @@ 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.database.DataAccessLayerException; -import com.raytheon.uf.edex.database.RunnableWithTransaction; +import com.raytheon.uf.common.util.StringUtil; import com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor; -import com.raytheon.uf.edex.datadelivery.registry.replication.NotificationHostConfiguration; +import com.raytheon.uf.edex.datadelivery.registry.dao.ReplicationEventDao; import com.raytheon.uf.edex.datadelivery.registry.replication.NotificationServers; import com.raytheon.uf.edex.datadelivery.registry.web.DataDeliveryRESTServices; import com.raytheon.uf.edex.datadelivery.util.DataDeliveryIdUtil; +import com.raytheon.uf.edex.registry.ebxml.dao.DbInit; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao; 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.init.RegistryInitializedListener; -import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; +import com.raytheon.uf.edex.registry.ebxml.services.query.RegistryQueryUtil; import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; +import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent; /** * @@ -159,33 +144,38 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * 1/15/2014 2613 bphillip Added leaveFederation method to prevent inactive registries from participating in the federation unintentionally. * 1/21/2014 2613 bphillip Changed max down time which requires a sync * Feb 11, 2014 2771 bgonzale Use Data Delivery ID instead of Site. + * 2/13/2014 2769 bphillip Refactored registry sync. Created quartz tasks to monitor registry uptime as well as subscription integrity * * * @author bphillip * @version 1 */ +@Path(IRegistryFederationManager.REGISTRY_FEDERATION_MANAGER_PATH) @Service -@Transactional -public class RegistryFederationManager implements RegistryInitializedListener { +public class RegistryFederationManager implements IRegistryFederationManager, + RegistryInitializedListener { /** The logger instance */ protected static final IUFStatusHandler statusHandler = UFStatus .getHandler(RegistryFederationManager.class); - /** The federation identifier */ + private static Set replicatedObjectTypes = new HashSet(); + public static final String FEDERATION_ID = "Registry Federation"; + /** The mode that EDEX was started in */ + public static final boolean centralRegistry = System.getProperty( + "edex.run.mode").equals("centralRegistry"); + + private static final String FEDERATION_CONFIG_FILE = "datadelivery/registry/federationConfig.xml"; + /** * The name of the configuration files defining which servers we are * sending/receiving replicated objects to/from */ private static final String NOTIFICATION_SERVERS_FILE = "datadelivery/registry/notificationServers.xml"; - /** - * The name of the configuration file defining the characteristics of the - * federation - */ - private static final String FEDERATION_CONFIG_FILE = "datadelivery/registry/federationConfig.xml"; + private static FederationProperties federationProperties; /** * The maximum time a registry can be down before a full synchronization is @@ -193,208 +183,657 @@ public class RegistryFederationManager implements RegistryInitializedListener { */ private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_HOUR * 6; - /** The central registry mode string */ - private static final String CENTRAL_REGISTRY_MODE = "centralRegistry"; + /** Cutoff parameter for the query to get the expired events */ + private static final String GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER = "cutoff"; - /** String format for ids of replication subscriptions */ - private static final String SUBSCRIPTION_DETAIL_FORMAT = "Replication Subscription for [%s] objects for server [" - + RegistryUtil.LOCAL_REGISTRY_ADDRESS + "]"; - - /** Query used for synchronizing registries */ - private static final String SYNC_QUERY = "FROM RegistryObjectType obj where obj.objectType='%s' order by obj.id asc"; - - /** Batch size for registry synchronization queries */ - private static final int SYNC_BATCH_SIZE = 250; - - /** The address of the NCF */ - protected String ncfAddress = System.getenv("NCF_ADDRESS"); - - /** The mode that EDEX was started in */ - public static final boolean centralRegistry = System.getProperty( - "edex.run.mode").equals(CENTRAL_REGISTRY_MODE); - - private static final String FEDERATION_SYNC_THREADS_PROPERTY = "ebxml-federation-sync-threads"; - - /** - * 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; + /** Query to get Expired AuditableEvents */ + private static final String GET_EXPIRED_EVENTS_QUERY = "FROM ReplicationEvent event where event.eventTime < :" + + GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER; /** Maximum times this registry will try to sync data before failure */ private int maxSyncRetries = 3; - /** The servers that we are subscribing to */ - private static NotificationServers servers; - - /** Object types to automatically create subscriptions for */ - private static Set objectTypes = new HashSet(); - - /** - * Hibernate transaction template used for transaction isolation when - * synchronizing with other registries - */ - private TransactionTemplate txTemplate; - - /** Monitors how long this registry has been connected to the federation */ - private FederatedRegistryMonitor federatedRegistryMonitor; - - /** - * The scheduler service used for registering this registry with the - * federation - */ - protected ScheduledExecutorService scheduler; - - /** Denotes if this registry is participating in the federation */ - protected boolean federationEnabled; - - /** The lifecycle manager */ - protected LifecycleManager lcm; - - /** The JAXB Manager for serializing registry objects */ - protected JAXBManager jaxbManager; - - /** The properties describing this registry in the federation */ - protected static FederationProperties federationProperties; - - /** Data access object for registry objects */ - protected RegistryObjectDao registryObjectDao; - - /** Data Access object for RegistryType objects */ - protected RegistryDao registryDao; - - /** Registry SOAP Service Client */ - protected RegistrySOAPServices registrySoapServices; - - /** Data Delivery REST services client */ - private DataDeliveryRESTServices dataDeliveryRestClient; - /** * Denotes if initialization has already occurred for this class. It is a * static variable because at this time, multiple Spring containers load * this class, yet it only needs to be initialized once */ - private static AtomicBoolean initialized = new AtomicBoolean(false); + public static AtomicBoolean initialized = new AtomicBoolean(false); - private Long subscriptionStartTime = 0l; + private boolean federationEnabled = Boolean.parseBoolean(System + .getenv("EBXML_REGISTRY_FEDERATION_ENABLED")); - /** - * Creates a new RegistryFederationManager - */ - protected RegistryFederationManager() { + private static AtomicBoolean running = new AtomicBoolean(false); + /** The servers that we are subscribing to */ + private static NotificationServers servers; + + private String ncfAddress = System.getenv("NCF_ADDRESS"); + + /** Monitors how long this registry has been connected to the federation */ + private FederatedRegistryMonitor federatedRegistryMonitor; + + /** The JAXB Manager for serializing registry objects */ + protected JAXBManager jaxbManager; + + private ReplicationEventDao replicationEventDao; + + private RegistryDao registryDao; + + private TransactionTemplate txTemplate; + + private RegistrySOAPServices soapService; + + private LifecycleManager localLifecycleManager; + + private DataDeliveryRESTServices dataDeliveryRestClient; + + private RegistryObjectDao registryObjectDao; + + private FederationDbInit federationDbInit; + + public RegistryFederationManager() throws JAXBException { + jaxbManager = new JAXBManager(SubmitObjectsRequest.class, + FederationProperties.class, NotificationServers.class, + SubscriptionType.class); } - /** - * Creates a new RegistryFederationManager - * - * @param federationEnabled - * Boolean denoting if the federation is enabled - * @param lcm - * The lifecycle manager to be used - * @param federationPropertiesFileName - * The name of the file containing the properties for this - * registry - * @throws EbxmlRegistryException - * If errors occur during initialization - */ - protected RegistryFederationManager(LifecycleManager lcm, - FederatedRegistryMonitor federatedRegistryMonitor, - TransactionTemplate txTemplate) throws EbxmlRegistryException { - this.federationEnabled = Boolean.parseBoolean(System - .getenv("EBXML_REGISTRY_FEDERATION_ENABLED")); - this.federatedRegistryMonitor = federatedRegistryMonitor; - this.lcm = lcm; - this.txTemplate = txTemplate; - + @Override + @Transactional + public void executeAfterRegistryInit() throws EbxmlRegistryException { try { - jaxbManager = new JAXBManager(SubmitObjectsRequest.class, - FederationProperties.class, NotificationServers.class, - SubscriptionType.class); - } catch (JAXBException e) { + this.federationDbInit.initDb(); + } catch (Exception e) { throw new EbxmlRegistryException( - "Error initializing JAXB Manager!", e); + "Error initializing database for federation!", e); } - - if (System.getProperty(FEDERATION_SYNC_THREADS_PROPERTY) != null) { - registrySyncThreads = Integer.valueOf(System - .getProperty(FEDERATION_SYNC_THREADS_PROPERTY)); - } - - /* - * Check if federation capability is enabled. If so, load the - * properties. - */ - if (federationEnabled) { - if (federationProperties == null) { - statusHandler.info("Loading Federation Configuration..."); - File federationPropertiesFile = PathManagerFactory - .getPathManager().getStaticFile(FEDERATION_CONFIG_FILE); - if (federationPropertiesFile == null) { - throw new EbxmlRegistryException( - "Unable to locate federation configuration file: " - + FEDERATION_CONFIG_FILE); - } else { - try { + if (federationEnabled && !initialized.get()) { + try { + if (federationProperties == null) { + statusHandler.info("Loading Federation Configuration..."); + File federationPropertiesFile = PathManagerFactory + .getPathManager().getStaticFile( + FEDERATION_CONFIG_FILE); + if (federationPropertiesFile == null) { + throw new FileNotFoundException( + "Unable to locate federation configuration file: " + + FEDERATION_CONFIG_FILE); + } else { federationProperties = (FederationProperties) jaxbManager .unmarshalFromXmlFile( FederationProperties.class, federationPropertiesFile); + } + } + if (servers == null) { + File notificationServerConfigFile = PathManagerFactory + .getPathManager().getStaticFile( + NOTIFICATION_SERVERS_FILE); + + // If this registry is participating in the federation and + // the + // config + // file is not found, throw an error + if (federationEnabled + && notificationServerConfigFile == null) { + throw new EbxmlRegistryException( + "Notification server config file not found!"); + } + + try { + statusHandler.info("Loading replication servers from [" + + notificationServerConfigFile.getPath() + + "]..."); + servers = jaxbManager.unmarshalFromXmlFile( + NotificationServers.class, + notificationServerConfigFile); } catch (SerializationException e) { throw new EbxmlRegistryException( - "Error unmarshalling federation properties file", + "Error unmarshalling notification servers file!", e); } + statusHandler.info("Found " + + servers.getRegistryReplicationServers().size() + + " servers for replication"); + } + + if (!joinFederation()) { + throw new EbxmlRegistryException( + "Error joining federation!!"); + } + if (!centralRegistry) { + checkDownTime(); + } + federatedRegistryMonitor.updateTime(); + + } catch (Exception e1) { + throw new EbxmlRegistryException( + "Error initializing RegistryReplicationManager", e1); + } + + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult( + TransactionStatus status) { + leaveFederation(); + } + }); + } + }); + } + initialized.set(true); + } + + /** + * 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 + */ + private 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 more than " + + (MAX_DOWN_TIME_DURATION / TimeUtil.MILLIS_PER_HOUR) + + " hours. Initiating federated registry data synchronization attempt #" + + syncAttempt + "/" + maxSyncRetries + + "..."); + if (CollectionUtil.isNullOrEmpty(servers + .getRegistryReplicationServers())) { + statusHandler + .error("No servers configured for replication. Unable to synchronize registry data with federation!"); + break; + } else { + RegistryType registryToSyncFrom = null; + for (String remoteRegistryId : servers + .getRegistryReplicationServers()) { + statusHandler.info("Checking availability of [" + + remoteRegistryId + "]..."); + RegistryType remoteRegistry = dataDeliveryRestClient + .getRegistryObject( + ncfAddress, + remoteRegistryId + + FederationProperties.REGISTRY_SUFFIX); + if (remoteRegistry == null) { + statusHandler + .warn("Registry at [" + + remoteRegistryId + + "] not found in federation. Unable to use as synchronization source."); + } else if (dataDeliveryRestClient + .isRegistryAvailable(remoteRegistry + .getBaseURL())) { + registryToSyncFrom = remoteRegistry; + break; + } else { + statusHandler + .info("Registry at [" + + remoteRegistryId + + "] is not available. Unable to use as synchronization source."); + } + } + + // 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 { + synchronizeWithRegistry(registryToSyncFrom.getId()); + + 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; + } } } + } + } - if (servers == null) { - File notificationServerConfigFile = PathManagerFactory - .getPathManager().getStaticFile( - NOTIFICATION_SERVERS_FILE); - - // If this registry is participating in the federation and - // the - // config - // file is not found, throw an error - if (federationEnabled && notificationServerConfigFile == null) { - throw new EbxmlRegistryException( - "Notification server config file not found!"); - } - - try { - statusHandler.info("Loading replication servers from [" - + notificationServerConfigFile.getPath() + "]..."); - servers = jaxbManager.unmarshalFromXmlFile( - NotificationServers.class, - notificationServerConfigFile); - } catch (SerializationException e) { - throw new EbxmlRegistryException( - "Error unmarshalling notification servers file!", e); - } - statusHandler.info("Found " - + servers.getRegistryReplicationServers().size() - + " servers for replication"); + public boolean joinFederation() { + try { + final List objects = new ArrayList( + 5); + final RegistryType registry = federationProperties + .createRegistryObject(); + final OrganizationType org = federationProperties + .createOrganization(); + final PersonType primaryContact = federationProperties + .createPrimaryContactPerson(); + FederationType federation = null; + try { + federation = getFederation(); + } catch (Exception e) { + throw new EbxmlRegistryException("Error getting federation", e); } - scheduler = Executors.newScheduledThreadPool(1); - } else { - statusHandler.info("Federation capabilities disabled"); + if (federation != null) { + final AssociationType federationAssociation = federationProperties + .getFederationAssociation(registry, federation); + + if (centralRegistry) { + objects.add(federation); + } + objects.add(registry); + objects.add(org); + objects.add(primaryContact); + objects.add(federationAssociation); + + SubmitObjectsRequest submitObjectsRequest = new SubmitObjectsRequest( + "Federation Objects submission", + "Submitting federation related objects", null, + new RegistryObjectListType(objects), false, + Mode.CREATE_OR_REPLACE); + submitObjectsRequest + .getSlot() + .add(new SlotType(EbxmlObjectUtil.EVENT_SOURCE_SLOT, + new StringValueType(DataDeliveryIdUtil.getId()))); + try { + statusHandler + .info("Submitting federation registration objects to local registry..."); + localLifecycleManager.submitObjects(submitObjectsRequest); + statusHandler + .info("Successfully submitted federation registration objects to local registry!"); + } catch (MsgRegistryException e) { + throw new EbxmlRegistryException( + "Error submitting federation objects to registry", + e); + } + if (!centralRegistry) { + statusHandler + .info("Submitting federation registration objects to NCF..."); + try { + soapService.getLifecycleManagerServiceForHost( + ncfAddress).submitObjects(submitObjectsRequest); + statusHandler + .info("Successfully submitted federation registration objects to NCF!"); + } catch (MsgRegistryException e) { + throw new EbxmlRegistryException( + "Error submitting federation objects to registry", + e); + } + } + + for (String registryId : servers + .getRegistryReplicationServers()) { + try { + subscribeToRegistry(registryId); + } catch (Exception e) { + statusHandler + .error("Error establishing replication connection with [" + + registryId + "]"); + } + } + } + } catch (Throwable e) { + statusHandler.error("Error joining federation!", e); + return false; } + return true; } - @Override - public void executeAfterRegistryInit() throws EbxmlRegistryException { + public boolean leaveFederation() { + try { + final RegistryType registry = federationProperties + .createRegistryObject(); + final OrganizationType org = federationProperties + .createOrganization(); + final PersonType primaryContact = federationProperties + .createPrimaryContactPerson(); + FederationType federation = getFederation(); - if (federationEnabled && !initialized.getAndSet(true)) { - statusHandler - .info("Federation/Replication enabled for this registry. Scheduling Federation registration task..."); - final RegisterWithFederationTask federationRegistrationTask = new RegisterWithFederationTask(); - scheduler.schedule(federationRegistrationTask, 0, TimeUnit.SECONDS); + if (federation != null) { + final AssociationType federationAssociation = federationProperties + .getFederationAssociation(registry, federation); + ObjectRefListType refList = new ObjectRefListType(); + refList.getObjectRef().add(new ObjectRefType(registry.getId())); + refList.getObjectRef().add(new ObjectRefType(org.getId())); + refList.getObjectRef().add( + new ObjectRefType(primaryContact.getId())); + refList.getObjectRef().add( + new ObjectRefType(federationAssociation.getId())); + RemoveObjectsRequest req = new RemoveObjectsRequest(); + req.setId("Removing [" + registry.getId() + + "] from the federation..."); + req.setComment("Remove request to remove federation related objects"); + req.setDeleteChildren(true); + req.setObjectRefList(refList); + statusHandler.info("Disconnecting from federation..."); + for (String registryId : servers + .getRegistryReplicationServers()) { + unsubscribeFromRegistry(registryId); + } + try { + if (RegistryFederationManager.centralRegistry) { + localLifecycleManager.removeObjects(req); + } else { + soapService.getLifecycleManagerServiceForHost( + ncfAddress).removeObjects(req); + } + statusHandler + .info("Registry disconnected from federation."); + } catch (MsgRegistryException e) { + statusHandler.error( + "Error while disconnecting from federation!", e); + } + + } + } catch (Throwable e) { + statusHandler.error("Error leaving federation", e); + return false; } + return true; + } + + /** + * 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 + * @throws MsgRegistryException + */ + @Transactional + @GET + @Path("synchronizeWithRegistry/{registryId}") + public void synchronizeWithRegistry( + @PathParam("registryId") String registryId) throws Exception { + long start = TimeUtil.currentTimeMillis(); + RegistryType remoteRegistry = null; + try { + if (!registryId.endsWith(FederationProperties.REGISTRY_SUFFIX)) { + registryId += FederationProperties.REGISTRY_SUFFIX; + } + remoteRegistry = dataDeliveryRestClient.getRegistryObject( + ncfAddress, registryId); + } catch (Exception e) { + throw new EbxmlRegistryException( + "Error retrieving info for remote registry [" + registryId + + "] ", e); + } + if (remoteRegistry == null) { + throw new EbxmlRegistryException("Unable to synchronize with [" + + registryId + "]. Registry not found in federation"); + } + String remoteRegistryUrl = remoteRegistry.getBaseURL(); + + for (final String objectType : replicatedObjectTypes) { + registryObjectDao + .deleteAll(registryObjectDao + .query("FROM RegistryObjectType obj where obj.objectType=:objectType", + "objectType", objectType)); + + final Collection remoteIds = dataDeliveryRestClient + .getRegistryDataAccessService(remoteRegistryUrl) + .getRegistryObjectIdsOfType(objectType).getPayload(); + + if (CollectionUtil.isNullOrEmpty(remoteIds)) { + statusHandler.info("No objects present of type: " + objectType); + continue; + } + statusHandler.info("Synchronizing " + remoteIds.size() + + " objects of type: " + objectType); + try { + + for (String remoteId : remoteIds) { + RegistryObjectType remoteObject = dataDeliveryRestClient + .getRegistryObject(remoteRegistryUrl, + URLEncoder.encode(remoteId, "UTF-8") + .replaceAll("\\+", "%20")); + if (remoteObject != null) { + registryObjectDao.create(remoteObject); + } + + } + } catch (Exception e) { + throw new RuntimeException("Error synching object type [" + + objectType + "] with registry at [" + + remoteRegistryUrl + "]", e); + } + } + statusHandler.info("Registry synchronization using [" + + remoteRegistryUrl + "] completed successfully in " + + (TimeUtil.currentTimeMillis() - start) + " ms"); + } + + @GET + @Path("isFederated") + @Transactional + public String isFederated() { + return System.getenv("EBXML_REGISTRY_FEDERATION_ENABLED"); + } + + @GET + @Path("dataDeliveryId") + public String dataDeliveryId() { + return DataDeliveryIdUtil.getId(); + } + + @GET + @Path("siteId") + public String siteId() { + return System.getenv("AW_SITE_IDENTIFIER"); + } + + @GET + @Path("getObjectTypesReplicated") + public String getObjectTypesReplicated() { + return RegistryQueryUtil.formatArrayString(replicatedObjectTypes + .toArray()); + } + + @GET + @Path("getFederationMembers") + @Transactional + public String getFederationMembers() throws Exception { + Comparator sorter = new Comparator() { + @Override + public int compare(RegistryObjectType o1, RegistryObjectType o2) { + return o1.getId().compareTo(o2.getId()); + } + }; + StringBuilder builder = new StringBuilder(); + List registries = getFederatedRegistries(); + Collections.sort(registries, sorter); + for (RegistryType registry : registries) { + appendRegistryInfo(registry, builder); + } + return builder.toString(); + } + + @GET + @Path("getReplicatingTo") + @Transactional + public String getReplicatingTo() { + return RegistryQueryUtil.formatArrayString(servers + .getRegistryReplicationServers().toArray()); + } + + @GET + @Path("getReplicatingFrom") + @Transactional + public String getReplicatingFrom() throws Exception { + Set registrySet = new HashSet(); + List registries = getFederatedRegistries(); + for (RegistryType registry : registries) { + String remoteReplicatingTo = null; + try { + remoteReplicatingTo = dataDeliveryRestClient + .getRegistryFederationManager(registry.getBaseURL()) + .getReplicatingTo(); + } catch (Exception e) { + statusHandler.error("Error getting replication list from [" + + registry.getId() + "]", e); + continue; + } + if (remoteReplicatingTo.contains(DataDeliveryIdUtil.getId())) { + registrySet.add(registry.getId().replace( + FederationProperties.REGISTRY_SUFFIX, "")); + } + } + return RegistryQueryUtil.formatArrayString(registrySet.toArray()); + } + + @GET + @Path("subscribeToRegistry/{registryId}") + @Transactional + public void subscribeToRegistry(@PathParam("registryId") String registryId) + throws Exception { + statusHandler.info("Establishing replication with [" + registryId + + "]..."); + RegistryType remoteRegistry = getRegistry(registryId); + dataDeliveryRestClient.getRegistryFederationManager( + remoteRegistry.getBaseURL()).addReplicationServer( + DataDeliveryIdUtil.getId()); + statusHandler.info("Established replication with [" + registryId + "]"); + } + + @GET + @Path("unsubscribeFromRegistry/{registryId}") + @Transactional + public void unsubscribeFromRegistry( + @PathParam("registryId") String registryId) throws Exception { + statusHandler.info("Disconnecting replication with [" + registryId + + "]..."); + RegistryType remoteRegistry = getRegistry(registryId); + dataDeliveryRestClient.getRegistryFederationManager( + remoteRegistry.getBaseURL()).removeReplicationServer( + DataDeliveryIdUtil.getId()); + statusHandler + .info("Disconnected replication with [" + registryId + "]"); + } + + @GET + @Path("addReplicationServer/{registryId}") + @Transactional + public void addReplicationServer(@PathParam("registryId") String registryId) + throws Exception { + getRegistry(registryId); + servers.addReplicationServer(registryId); + saveNotificationServers(); + } + + @GET + @Path("removeReplicationServer/{registryId}") + @Transactional + public void removeReplicationServer( + @PathParam("registryId") String registryId) throws Exception { + getRegistry(registryId); + servers.removeReplicationServer(registryId); + saveNotificationServers(); + } + + /** + * Appends registry information to the stringbuilder + * + * @param registry + * The registry to get information for + * @param builder + * The string builder to append to + */ + private void appendRegistryInfo(RegistryType registry, StringBuilder builder) { + builder.append( + registry.getId().replace(FederationProperties.REGISTRY_SUFFIX, + "")).append(","); + builder.append(registry.getBaseURL()).append(","); + builder.append(registry.getConformanceProfile()).append(","); + builder.append(registry.getSpecificationVersion()); + builder.append(StringUtil.NEWLINE); + } + + /** + * Persists the list of notification servers to the localized file + */ + private void saveNotificationServers() { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext lc = pm.getContext(LocalizationType.EDEX_STATIC, + LocalizationLevel.SITE); + LocalizationFile lf = pm.getLocalizationFile(lc, + NOTIFICATION_SERVERS_FILE); + File file = lf.getFile(); + + try { + jaxbManager.marshalToXmlFile(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); + } + } + + private List getFederatedRegistries() + throws EbxmlRegistryException { + final Collection remoteIds = dataDeliveryRestClient + .getRegistryDataAccessService(ncfAddress) + .getRegistryObjectIdsOfType(RegistryObjectTypes.REGISTRY) + .getPayload(); + if (remoteIds.isEmpty()) { + return Collections.emptyList(); + } + List registries = new ArrayList( + remoteIds.size()); + for (String remoteId : remoteIds) { + registries.add(getRegistry(remoteId)); + } + return registries; + } + + private RegistryType getRegistry(String registryId) + throws EbxmlRegistryException { + RegistryType registry = null; + try { + if (!registryId.endsWith(FederationProperties.REGISTRY_SUFFIX)) { + registryId += FederationProperties.REGISTRY_SUFFIX; + } + registry = dataDeliveryRestClient.getRegistryObject(ncfAddress, + registryId); + } catch (Exception e) { + throw new EbxmlRegistryException("Error retrieving registry [" + + registryId + "] from NCF", e); + } + if (registry == null) { + throw new RegistryNotFoundException("Registry [" + registryId + + "] not found in federation"); + } + return registry; } /** @@ -433,1077 +872,264 @@ public class RegistryFederationManager implements RegistryInitializedListener { FEDERATION_ID); statusHandler .info("Federation object successfully retrieved from NCF!"); - } - return federation; } + @Subscribe + @Transactional(propagation = Propagation.REQUIRED) + public void processEvent(CreateAuditTrailEvent event) { + String sourceRegistry = event.getRequest().getSlotValue( + EbxmlObjectUtil.EVENT_SOURCE_SLOT); + String actionType = event.getActionType(); + List objsAffected = event.getObjectsAffected(); + for (RegistryObjectType affectedObj : objsAffected) { + if (replicatedObjectTypes.contains(affectedObj.getObjectType())) { + ReplicationEvent replicationEvent = new ReplicationEvent( + actionType, event.getEventTime(), affectedObj.getId(), + affectedObj.getObjectType(), sourceRegistry); + replicationEventDao.create(replicationEvent); + } + } + } + + public void processReplicationEvents() { + if (federationEnabled && DbInit.isDbInitialized() && initialized.get()) { + if (!running.getAndSet(true)) { + try { + for (final String remoteRegistryId : servers + .getRegistryReplicationServers()) { + txTemplate + .execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult( + TransactionStatus status) { + try { + long eventProcessingStart = TimeUtil + .currentTimeMillis(); + int eventsProcessed = processEventsFor(remoteRegistryId); + if (eventsProcessed > 0) { + statusHandler.info("Processed [" + + eventsProcessed + + "] replication events for [" + + remoteRegistryId + + "] in " + + (TimeUtil + .currentTimeMillis() - eventProcessingStart) + + " ms"); + } + } catch (EbxmlRegistryException e) { + throw new RuntimeException( + "Error processing events", + e); + } + } + }); + } + } finally { + running.set(false); + } + } + } + } + + private int processEventsFor(String remoteRegistryId) + throws EbxmlRegistryException { + int eventsProcessed = 0; + RegistryType remoteRegistry = registryDao.getById(remoteRegistryId + + FederationProperties.REGISTRY_SUFFIX); + if (remoteRegistry == null) { + statusHandler.warn("Registry [" + remoteRegistryId + + "] not present in federation. Skipping."); + } else if (dataDeliveryRestClient.isRegistryAvailable(remoteRegistry + .getBaseURL())) { + + List events = replicationEventDao + .getReplicationEvents(remoteRegistryId); + + List>> orderedBatchedEvents = new ArrayList>>(); + SimpleEntry> lastEntry = null; + String currentEventType = null; + for (ReplicationEvent event : events) { + event.addReplicatedTo(remoteRegistryId); + replicationEventDao.update(event); + currentEventType = event.getEventType(); + /* + * If this is the first event processed or the event type + * differs from the last, create a new entry + */ + if (lastEntry == null + || !currentEventType.equals(lastEntry.getKey())) { + List newList = new ArrayList(); + newList.add(event); + SimpleEntry> newEntry = new SimpleEntry>( + currentEventType, newList); + orderedBatchedEvents.add(newEntry); + lastEntry = newEntry; + } + /* + * If this event is of the same type as the last, append the + * event to the list + */ + else if (currentEventType.equals(lastEntry.getKey())) { + lastEntry.getValue().add(event); + } + } + + for (SimpleEntry> entry : orderedBatchedEvents) { + currentEventType = entry.getKey(); + if (currentEventType.equals(ActionTypes.create) + || currentEventType.equals(ActionTypes.update) + || currentEventType.equals(ActionTypes.version)) { + SubmitObjectsRequest request = null; + request = new SubmitObjectsRequest(); + request.setId("Replicate - Insert/Update events"); + List objIds = new ArrayList(entry + .getValue().size()); + for (ReplicationEvent event : entry.getValue()) { + objIds.add(event.getObjectId()); + } + request.getRegistryObjects().addAll( + registryObjectDao.getById(objIds)); + request.setCheckReferences(false); + request.setMode(Mode.CREATE_OR_REPLACE); + request.getSlot().add( + new SlotType(EbxmlObjectUtil.EVENT_SOURCE_SLOT, + new StringValueType(DataDeliveryIdUtil + .getId()))); + try { + if (!request.getRegistryObjects().isEmpty()) { + soapService.getLifecycleManagerServiceForHost( + remoteRegistry.getBaseURL()).submitObjects( + request); + } + } catch (MsgRegistryException e) { + throw new EbxmlRegistryException( + "Error processing events for [" + + remoteRegistryId + "]", e); + } + } else if (currentEventType.equals(ActionTypes.delete)) { + ObjectRefListType refList = new ObjectRefListType(); + for (ReplicationEvent event : entry.getValue()) { + refList.getObjectRef().add( + new ObjectRefType(event.getObjectId())); + } + RemoveObjectsRequest request = new RemoveObjectsRequest( + "Replicate - Remove events", "", null, null, + refList, false, true, DeletionScope.DELETE_ALL); + request.getSlot().add( + new SlotType(EbxmlObjectUtil.EVENT_SOURCE_SLOT, + new StringValueType(DataDeliveryIdUtil + .getId()))); + try { + if (!refList.getObjectRef().isEmpty()) { + soapService.getLifecycleManagerServiceForHost( + remoteRegistry.getBaseURL()).removeObjects( + request); + } + } catch (MsgRegistryException e) { + throw new EbxmlRegistryException( + "Error processing events for [" + + remoteRegistryId + "]", e); + } + + } + } + eventsProcessed = events.size(); + } else { + statusHandler.warn("Unable to replicate to [" + remoteRegistryId + + "]. Registry is currently unavailable."); + } + return eventsProcessed; + } + /** - * 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 + * Updates the record in the registry that keeps track of if this registry + * has been up. This method is called every minute via a quartz cron + * configured in Camel */ + @Transactional + public void updateUpTime() { + if (initialized.get()) { + federatedRegistryMonitor.updateTime(); + } + } + + @Transactional + public void deleteExpiredEvents() { + statusHandler.info("Purging expired replication events..."); + Calendar cutoffTime = TimeUtil.newGmtCalendar(); + cutoffTime.add(Calendar.HOUR_OF_DAY, -48); + List events = replicationEventDao.executeHQLQuery( + GET_EXPIRED_EVENTS_QUERY, + GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER, + cutoffTime.getTimeInMillis()); + replicationEventDao.deleteAll(events); + statusHandler.info("Purged " + events.size() + " expired events"); + } + + @Transactional + public void verifyReplication() throws Exception { + if (federationEnabled && servers != null + && !servers.getRegistryReplicationServers().isEmpty()) { + statusHandler + .info("Verifying replication with the following registries: " + + servers.getRegistryReplicationServers() + "..."); + for (String registryId : servers.getRegistryReplicationServers()) { + verifyReplicationFor(registryId + + FederationProperties.REGISTRY_SUFFIX); + } + statusHandler.info("Replication verification complete"); + } + } + + private void verifyReplicationFor(String registryId) throws Exception { + statusHandler.info("Verifying replication with [" + registryId + "]"); + RegistryType remoteRegistry = registryDao.getById(registryId); + String replicatingTo = dataDeliveryRestClient + .getRegistryFederationManager(remoteRegistry.getBaseURL()) + .getReplicatingTo(); + if (replicatingTo.contains(DataDeliveryIdUtil.getId())) { + statusHandler.info("Successfully verified replication with [" + + registryId + "]"); + } else { + statusHandler.info("Establishing replication with [" + registryId + + "]..."); + subscribeToRegistry(registryId); + statusHandler.info("Replication with [" + registryId + + "] established"); + } + } + public static void addObjectTypesToSubscribeTo(String... types) { for (String type : types) { - if (!objectTypes.contains(type)) { - objectTypes.add(type); + if (!replicatedObjectTypes.contains(type)) { + replicatedObjectTypes.add(type); statusHandler.info("Add object type for replication [" + type + "]"); } } } - /** - * Creates the association object between this registry and the federation - * - * @param registry - * The registry joining the federation - * @param federation - * The federation the registry is joining - * @return The association object - */ - protected AssociationType getFederationAssociation(RegistryType registry, - FederationType federation) { - AssociationType association = new AssociationType(); - association.setId(registry.getId() - + " Federation Membership Association"); - association.setLid(association.getId()); - association.setObjectType(RegistryObjectTypes.ASSOCIATION); - association.setOwner(DataDeliveryIdUtil.getId()); - association.setType(AssociationTypes.HAS_FEDERATION_MEMBER); - association.setStatus(StatusTypes.APPROVED); - association.setName(RegistryUtil.getInternationalString(registry - .getId() + " Federation Membership")); - association.setDescription(association.getName()); - association.setTargetObject(registry.getId()); - association.setSourceObject(federation.getId()); - return association; - } - - /** - * Submits objects necessary for the registry/federation to operate properly - * to the registry. This method first submits it locally, then submits the - * objects to the NCF - * - * @param objects - * The objects to submit - * @throws EbxmlRegistryException - * If object submission fails - */ - protected void submitObjects(List objects) - throws EbxmlRegistryException { - SubmitObjectsRequest submitObjectsRequest = new SubmitObjectsRequest( - "Federation Objects submission", - "Submitting federation related objects", null, - new RegistryObjectListType(objects), false, - Mode.CREATE_OR_REPLACE); - try { - statusHandler - .info("Submitting federation registration objects to local registry..."); - lcm.submitObjects(submitObjectsRequest); - statusHandler - .info("Successfully submitted federation registration objects to local registry!"); - } catch (MsgRegistryException e) { - throw new EbxmlRegistryException( - "Error submitting federation objects to registry", e); - } - - if (!centralRegistry) { - statusHandler - .info("Submitting federation registration objects to NCF..."); - try { - registrySoapServices.getLifecycleManagerServiceForHost( - ncfAddress).submitObjects(submitObjectsRequest); - statusHandler - .info("Successfully submitted federation registration objects to NCF!"); - } catch (MsgRegistryException e) { - throw new EbxmlRegistryException( - "Error submitting federation objects to registry", e); - } - } - } - - /** - * Removes a notificationServer based on the URL. - * - * @param baseURL - * The URL of the server to be removed - */ - public void removeNotificationServer(String baseURL) { - statusHandler.info("Removing replication registry for URL [" + baseURL - + "]"); - NotificationHostConfiguration toRemove = null; - for (NotificationHostConfiguration hostConfig : servers - .getRegistryReplicationServers()) { - if (hostConfig.getRegistryBaseURL().equals(baseURL)) { - toRemove = hostConfig; - } - } - if (toRemove == null) { - statusHandler.warn("Replication registry at URL [" + baseURL - + "] not present in configration"); - } else { - servers.getRegistryReplicationServers().remove(toRemove); - } - - } - - /** - * Adds a notification server to the list. - * - * @param host - * The host to be added - */ - public void addNotificationServer(RegistryType registry) { - statusHandler.info("Adding registry [" + registry.getId() - + "] to list of registries for replication"); - if (!notificationServersContainRegistry(registry)) { - servers.getRegistryReplicationServers().add( - new NotificationHostConfiguration(registry.getId(), - registry.getId(), registry.getBaseURL())); - statusHandler - .info("Registry [" - + registry.getId() - + "] successfully added to list of registries for replication"); - } - - } - - public boolean notificationServersContainRegistry(RegistryType registry) { - for (NotificationHostConfiguration hostConfig : servers - .getRegistryReplicationServers()) { - if (hostConfig.getRegistryBaseURL().equals(registry.getBaseURL())) { - return true; - } - } - - return false; - } - - /** - * 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.SITE); - LocalizationFile lf = pm.getLocalizationFile(lc, - NOTIFICATION_SERVERS_FILE); - File file = lf.getFile(); - - try { - jaxbManager.marshalToXmlFile(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); - } - } - - /** - * Submits subscriptions to the remote registries - * - * @param baseURL - * The url of the registry to send the subscriptions to - */ - public void submitRemoteSubscriptions() { - - statusHandler - .info("Submitting subscriptions to registry replication servers..."); - List replicationRegistries = servers - .getRegistryReplicationServers(); - - if (CollectionUtil.isNullOrEmpty(replicationRegistries)) { - statusHandler.info("No registry replication servers configured."); - } else { - for (NotificationHostConfiguration config : replicationRegistries) { - statusHandler - .info("Scheduling subscription submission to registry at [" - + config.getRegistryBaseURL() + "]..."); - final SubmitSubscriptionTask submitSubscriptionTask = new SubmitSubscriptionTask( - config); - scheduler.schedule(submitSubscriptionTask, 0, TimeUnit.SECONDS); - statusHandler - .info("Successfully scheduled subscription submission to registry at [" - + config.getRegistryBaseURL() + "]"); - } - } - } - - public void submitSubscriptionsToRegistry(RegistryType registry) { - statusHandler.info("Submitting subscriptions to registry [" - + registry.getId() + "]..."); - - NotificationHostConfiguration config = new NotificationHostConfiguration( - registry.getId(), registry.getId(), registry.getBaseURL()); - SubmitSubscriptionTask task = new SubmitSubscriptionTask(config); - task.run(); - if (task.scheduleSubscriptions()) { - statusHandler - .info("Successfully submitted subscriptions to registry [" - + registry.getId() + "]"); - } else { - statusHandler.warn("Unable to submit subscriptions to registry [" - + registry.getId() + "]"); - } - } - - public boolean isSubscribedTo(RegistryType registry) { - for (NotificationHostConfiguration config : servers - .getRegistryReplicationServers()) { - if (config.getRegistryBaseURL().equals(registry.getBaseURL())) { - return true; - } - } - return false; - } - - /** - * 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, - boolean reciprocateSubscription) throws Exception { - // Set normal registry object fields - String subscriptionDetail = String.format(SUBSCRIPTION_DETAIL_FORMAT, - objectType); - 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(DataDeliveryIdUtil.getId()); - sub.setStatus(StatusTypes.APPROVED); - - sub.setStartTime(EbxmlObjectUtil - .getTimeAsXMLGregorianCalendar(subscriptionStartTime - .longValue())); - QueryType selectorQuery = new QueryType(); - selectorQuery.setQueryDefinition(CanonicalQueryTypes.ADHOC_QUERY); - - SlotType expressionSlot = new SlotType(); - StringValueType expressionValue = new StringValueType(); - expressionValue - .setStringValue("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.setStringValue(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(registrySoapServices - .getNotificationListenerServiceUrl(RegistryUtil.LOCAL_REGISTRY_ADDRESS)); - 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; - } - - /** - * 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 - */ - private 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 notificationServers = servers - .getRegistryReplicationServers(); - if (servers == null - || CollectionUtil.isNullOrEmpty(servers - .getRegistryReplicationServers())) { - statusHandler - .error("No servers configured for replication. Unable to synchronize registry data with federation!"); - break; - } 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; - } - } - } - } else { - subscriptionStartTime = federatedRegistryMonitor - .getLastKnownUptime(); - } - 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 - * @throws MsgRegistryException - */ - public void synchronizeRegistryWithFederation(final String remoteRegistryUrl) - throws EbxmlRegistryException, MsgRegistryException { - long start = TimeUtil.currentTimeMillis(); - subscriptionStartTime = start; - ExecutorService executor = Executors - .newFixedThreadPool(this.registrySyncThreads); - - for (final String objectType : objectTypes) { - executor.submit(new RunnableWithTransaction(txTemplate) { - - @Override - public void runWithTransaction() { - try { - syncObjectType(objectType, remoteRegistryUrl); - } catch (Exception e) { - throw new RuntimeException( - "Error synching object type [" + objectType - + "] with registry at [" - + remoteRegistryUrl + "]", e); - } - } - }); - } - - // 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 in " - + (TimeUtil.currentTimeMillis() - start) + " ms"); - } - - /** - * Synchronizes objects of the specified type with the specified remote - * registry - * - * @param objectType - * The object type to synchronize - * @param remoteRegistryUrl - * The url of the remote registry - * @throws EbxmlRegistryException - * If there are errors deleting existing objects - * @throws MsgRegistryException - * If there are errors executing the remote soap query - */ - public void syncObjectType(String objectType, String remoteRegistryUrl) - throws EbxmlRegistryException, MsgRegistryException { - - try { - statusHandler.info("Deleting objects of type: " + objectType); - int deleteCount = registryObjectDao - .executeHQLStatement( - "DELETE FROM RegistryObjectType obj where obj.objectType=:objectType", - "objectType", objectType); - statusHandler.info(deleteCount + " objects of type [" + objectType - + "] deleted from registry"); - } catch (DataAccessLayerException e) { - throw new EbxmlRegistryException("Error deleting objects of type " - + objectType, e); - } - - statusHandler.info("Querying " + remoteRegistryUrl - + " for objects of type: " + objectType); - - // Get the list of remote object ids so we can check later to ensure all - // objects were retrieved - Collection remoteIds = dataDeliveryRestClient - .getRegistryDataAccessService(remoteRegistryUrl) - .getRegistryObjectIdsOfType(objectType).getPayload(); - - SlotType queryLanguageSlot = new SlotType( - QueryConstants.QUERY_LANGUAGE, new StringValueType( - QueryLanguages.HQL)); - SlotType queryExpressionSlot = new SlotType( - QueryConstants.QUERY_EXPRESSION, new StringValueType("")); - QueryRequest queryRequest = new QueryRequest(); - QueryType query = new QueryType(); - query.setQueryDefinition(CanonicalQueryTypes.ADHOC_QUERY); - query.getSlot().add(queryLanguageSlot); - query.getSlot().add(queryExpressionSlot); - queryRequest.setQuery(query); - queryRequest.setResponseOption(new ResponseOptionType( - QueryReturnTypes.REGISTRY_OBJECT, true)); - - queryRequest.setStartIndex(new BigInteger("0")); - queryRequest.setMaxResults(new BigInteger(String - .valueOf(SYNC_BATCH_SIZE))); - queryRequest.setId("Synchronizing object type: " + objectType); - SlotType slot = queryRequest.getQuery().getSlotByName( - QueryConstants.QUERY_EXPRESSION); - slot.setSlotValue(new StringValueType(String.format(SYNC_QUERY, - objectType))); - - int queryCount = 0; - int resultCount = 0; - do { - BigInteger start = queryRequest.getStartIndex().add( - new BigInteger(String.valueOf(resultCount))); - queryRequest.setStartIndex(start); - statusHandler.info("Query #" + (++queryCount) + " to registry [" - + remoteRegistryUrl + "] for objectType [" + objectType - + "]"); - QueryResponse queryResponse = registrySoapServices - .getQueryServiceForHost(remoteRegistryUrl).executeQuery( - queryRequest); - List queryResult = queryResponse - .getRegistryObjects(); - resultCount = queryResult.size(); - - if (!queryResult.isEmpty()) { - for (RegistryObjectType registryObject : queryResult) { - remoteIds.remove(registryObject.getId()); - } - statusHandler.info("Persisting " + queryResult.size() - + " objects of type " + objectType - + " to local registry"); - registryObjectDao.persistAll(queryResult); - registryObjectDao.flushAndClearSession(); - } - } while (resultCount > 0); - - // Ensure we haven't missed any objects - if (!remoteIds.isEmpty()) { - for (String objectId : remoteIds) { - try { - RegistryObjectType remoteObject = dataDeliveryRestClient - .getRegistryObject(remoteRegistryUrl, objectId); - registryObjectDao.createOrUpdate(remoteObject); - } catch (Throwable e) { - statusHandler.error("Error retrieving object [" + objectId - + "] from [" + remoteRegistryUrl + "]", e); - } - } - } - } - - /** - * - * Task for submitting subscriptions to a remote registry - * - *
-     * 
-     * SOFTWARE HISTORY
-     * 
-     * Date         Ticket#     Engineer    Description
-     * ------------ ----------  ----------- --------------------------
-     * 5/21/2013    1707        bphillip    Initial implementation
-     * 
- * - * @author bphillip - * @version 1 - */ - private class SubmitSubscriptionTask implements Runnable { - - /** The server configuration */ - private NotificationHostConfiguration config; - - /** - * Creates a new SubmitSubscriptionTask - * - * @param config - * The server configuration - */ - public SubmitSubscriptionTask(NotificationHostConfiguration config) { - this.config = config; - } - - @Override - public void run() { - - if (scheduleSubscriptions()) { - statusHandler.info("Successfully submitted subscriptions to " - + config.getRegistryBaseURL()); - } else { - statusHandler - .warn("Subscriptions not submitted to registry at " - + config.getRegistryBaseURL() - + ". Retrying in 10 seconds..."); - scheduler.schedule(this, 10, TimeUnit.SECONDS); - } - - } - - public boolean scheduleSubscriptions() { - try { - final String remoteRegistryBaseURL = config - .getRegistryBaseURL(); - RegistryType remoteRegistry = getRemoteRegistryByURL(remoteRegistryBaseURL); - - if (remoteRegistry == null) { - statusHandler.error("Registry at URL [" - + remoteRegistryBaseURL - + "] not found in federation."); - return false; - } else { - - 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."); - return false; - } - - statusHandler - .info("Removing remote subscriptions prior to submission of new subscriptions"); - dataDeliveryRestClient.getRegistryDataAccessService( - remoteRegistryBaseURL).removeSubscriptionsForSite( - DataDeliveryIdUtil.getId()); - statusHandler - .info("Generating registry replication subscriptions for registry at [" - + config.getRegistrySiteName() - + "] at URL [" - + remoteRegistryBaseURL - + "]"); - - List subscriptions = new ArrayList( - objectTypes.size()); - for (String objectType : objectTypes) { - SubscriptionType subscription; - try { - subscription = createSubscription( - remoteRegistryBaseURL, objectType, - config.isReciprocate()); - } 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); - registrySoapServices.sendSubmitObjectsRequest(request, - remoteRegistryBaseURL); - statusHandler.info("Requesting subscriptions from [" - + remoteRegistryBaseURL + "]..."); - - if (dataDeliveryRestClient - .getFederationService(remoteRegistryBaseURL) - .isFederated().equalsIgnoreCase("true")) { - if (config.isReciprocate()) { - dataDeliveryRestClient.getFederationService( - remoteRegistryBaseURL).subscribeToRegistry( - federationProperties.createRegistryObject() - .getId()); - } - } else { - statusHandler - .warn("Registry at [" - + remoteRegistryBaseURL - + "] is not participating in the federation. Unable to request subscriptions"); - } - - /* - * 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 + "]"); - if (dataDeliveryRestClient - .isRegistryAvailable(remoteRegistryBaseURL)) { - dataDeliveryRestClient - .getRegistryDataAccessService( - remoteRegistryBaseURL) - .removeSubscriptionsForSite( - DataDeliveryIdUtil.getId()); - statusHandler - .info("Subscriptions removed from: [" - + remoteRegistryBaseURL + "]"); - } else { - statusHandler - .warn("Registry at [" - + remoteRegistryBaseURL - + "] is not available. Unable to remove subscriptions."); - } - - } - }); - return true; - } - } catch (Exception e) { - statusHandler.error("Error submitting subscriptions!.", e); - return false; - - } - } - } - - private RegistryType getRemoteRegistryByURL(String remoteRegistryBaseURL) - throws MsgRegistryException { - QueryManager ncfQueryManager = registrySoapServices - .getQueryServiceForHost(ncfAddress); - QueryType query = new QueryType(CanonicalQueryTypes.ADHOC_QUERY); - query.getSlot().add( - new SlotType(QueryConstants.QUERY_LANGUAGE, - new StringValueType(QueryLanguages.HQL))); - query.getSlot() - .add(new SlotType(QueryConstants.QUERY_EXPRESSION, - new StringValueType( - "FROM RegistryType reg WHERE reg.baseURL=:url"))); - query.getSlot() - .add(new SlotType("url", new StringValueType( - remoteRegistryBaseURL))); - - QueryRequest queryRequest = new QueryRequest("Registry Retrieval", - query, new ResponseOptionType(QueryReturnTypes.REGISTRY_OBJECT, - true)); - List registries = ncfQueryManager.executeQuery( - queryRequest).getRegistryObjects(); - for (RegistryObjectType registryObj : registries) { - RegistryType reg = (RegistryType) registryObj; - if (reg.getBaseURL().equals(remoteRegistryBaseURL)) { - return reg; - } - } - return null; - } - - /** - * - * Runnable task that continuously attempts to register this registry with - * the federation until it succeeds - * - *
-     * 
-     * SOFTWARE HISTORY
-     * 
-     * Date         Ticket#     Engineer    Description
-     * ------------ ----------  ----------- --------------------------
-     * 5/22/2013    1707        bphillip    Initial implementation
-     * 
- * - * @author bphillip - * @version 1 - */ - private class RegisterWithFederationTask extends RunnableWithTransaction { - - /** - * Creates a new RegisterwithFederationTask - */ - public RegisterWithFederationTask() { - super(txTemplate); - - } - - @Override - public void runWithTransaction() { - - boolean joinFederationSuccess = joinFederation(); - - if (joinFederationSuccess) { - statusHandler.info("Federation registration successful."); - submitRemoteSubscriptions(); - - statusHandler.info("Starting registry subscription monitor..."); - - Runnable subscriptionMonitor = new Runnable() { - @Override - public void run() { - List registries = null; - registries = servers.getRegistryReplicationServers(); - if (registries.isEmpty()) { - statusHandler - .info("Skipping replication subscription verification. No remote registries currently configured for replication."); - return; - } else { - statusHandler - .info("Verifying replication subscriptions on " - + registries.size() - + " remote registries"); - } - for (NotificationHostConfiguration config : registries) { - String remoteRegistryUrl = config - .getRegistryBaseURL(); - statusHandler - .info("Verifying replication subscriptions at [" - + remoteRegistryUrl + "]..."); - if (!dataDeliveryRestClient - .isRegistryAvailable(config - .getRegistryBaseURL())) { - statusHandler - .warn("Registry at [" - + remoteRegistryUrl - + "] is unavailable. Unable to verify subscriptions"); - continue; - } - - if (!Boolean.parseBoolean(dataDeliveryRestClient - .getFederationService(remoteRegistryUrl) - .isFederated())) { - statusHandler - .warn("Registry at [" - + remoteRegistryUrl - + "] is currently not participating in the federation. Skipping subscription verification"); - continue; - } - int resubmissions = 0; - QueryManager remoteQueryManager = registrySoapServices - .getQueryServiceForHost(remoteRegistryUrl); - for (String objectType : objectTypes) { - String subId = String.format( - SUBSCRIPTION_DETAIL_FORMAT, objectType); - SubscriptionType subscription = null; - try { - QueryType query = new QueryType( - CanonicalQueryTypes.GET_OBJECT_BY_ID); - query.getSlot() - .add(new SlotType( - QueryConstants.ID, - new StringValueType(subId))); - QueryRequest queryRequest = new QueryRequest( - "Subscription verification [" - + subId + "]", - query, - new ResponseOptionType( - QueryReturnTypes.OBJECT_REF, - true)); - List queryResult = remoteQueryManager - .executeQuery(queryRequest) - .getObjectRefs(); - boolean found = false; - for (ObjectRefType ref : queryResult) { - if (ref.getId().equals(subId)) { - found = true; - break; - } - } - if (!found) { - statusHandler - .warn("Subscription [" - + subId - + "] not found on remote server [" - + remoteRegistryUrl - + "]. Resubmitting subscription..."); - try { - subscription = createSubscription( - remoteRegistryUrl, - objectType, - config.isReciprocate()); - SubmitObjectsRequest request = new SubmitObjectsRequest( - "Resubmission of subscription [" - + subId + "]", - "Resubmission of subscription [" - + subId + "]", - null, - new RegistryObjectListType( - subscription), - false, - Mode.CREATE_OR_REPLACE); - registrySoapServices - .sendSubmitObjectsRequest( - request, - remoteRegistryUrl); - resubmissions++; - - } catch (Exception e1) { - statusHandler - .error("Error creating subscription for resubmission!", - e1); - } - } - } catch (MsgRegistryException e) { - statusHandler.error( - "Error verifying subscription!", e); - } - } - if (resubmissions == 0) { - statusHandler - .info("Successfully verified replication subscriptions for registry at [" - + remoteRegistryUrl + "]"); - } else { - statusHandler.warn("Resubmitted " - + resubmissions - + " subscriptions to registry at [" - + remoteRegistryUrl + "]."); - } - - } - } - }; - scheduler.scheduleAtFixedRate(subscriptionMonitor, 5, 10, - TimeUnit.MINUTES); - statusHandler.info("Registry subscription monitor started."); - } else { - statusHandler - .warn("Unable to join federation. Retrying in 10 seconds..."); - scheduler.schedule(this, 10, TimeUnit.SECONDS); - } - } - } - - public boolean joinFederation() { - try { - try { - if (!centralRegistry) { - if (dataDeliveryRestClient.isRegistryAvailable(ncfAddress)) { - statusHandler - .info("NCF Registry is available. Attempting to join federation..."); - } else { - statusHandler - .error("Unable to join federation. NCF is currently unreachable."); - return false; - } - } - List objects = new ArrayList( - 5); - final RegistryType registry = federationProperties - .createRegistryObject(); - final OrganizationType org = federationProperties - .createOrganization(); - final PersonType primaryContact = federationProperties - .createPrimaryContactPerson(); - FederationType federation = getFederation(); - - if (federation != null) { - final AssociationType federationAssociation = getFederationAssociation( - registry, federation); - - if (centralRegistry) { - objects.add(federation); - } - objects.add(registry); - objects.add(org); - objects.add(primaryContact); - objects.add(federationAssociation); - submitObjects(objects); - try { - checkDownTime(); - } catch (NoReplicationServersAvailableException e) { - statusHandler - .warn("No replication servers have been specified!"); - } - - Runtime.getRuntime().addShutdownHook(new Thread() { - - public void run() { - txTemplate - .execute(new TransactionCallbackWithoutResult() { - - @Override - protected void doInTransactionWithoutResult( - TransactionStatus status) { - leaveFederation(); - - } - }); - - } - }); - } - return true; - } catch (EbxmlRegistryException e) { - statusHandler.error("Error registering with federation", e); - return false; - } - } catch (Throwable e) { - statusHandler.error("Error initializing EBXML database!", e); - return false; - } - } - - public boolean leaveFederation() { - try { - final RegistryType registry = federationProperties - .createRegistryObject(); - final OrganizationType org = federationProperties - .createOrganization(); - final PersonType primaryContact = federationProperties - .createPrimaryContactPerson(); - FederationType federation = getFederation(); - - if (federation != null) { - final AssociationType federationAssociation = getFederationAssociation( - registry, federation); - ObjectRefListType refList = new ObjectRefListType(); - refList.getObjectRef().add(new ObjectRefType(registry.getId())); - refList.getObjectRef().add(new ObjectRefType(org.getId())); - refList.getObjectRef().add( - new ObjectRefType(primaryContact.getId())); - refList.getObjectRef().add( - new ObjectRefType(federationAssociation.getId())); - RemoveObjectsRequest req = new RemoveObjectsRequest(); - req.setId("Removing [" + registry.getId() - + "] from the federation..."); - req.setComment("Remove request to remove federation related objects"); - req.setDeleteChildren(true); - req.setObjectRefList(refList); - statusHandler.info("Disconnecting from federation..."); - try { - if (RegistryFederationManager.centralRegistry) { - lcm.removeObjects(req); - } else { - registrySoapServices.getLifecycleManagerServiceForHost( - ncfAddress).removeObjects(req); - } - statusHandler - .info("Registry disconnected from federation."); - } catch (MsgRegistryException e) { - statusHandler.error( - "Error while disconnecting from federation!", e); - } - } - } catch (Throwable e) { - statusHandler.error("Error leaving federation", e); - return false; - } - return true; - - } - - public static Set getObjectTypes() { - return objectTypes; - } - - public NotificationServers getServers() { - return servers; - } - - public void setRegistryObjectDao(RegistryObjectDao registryObjectDao) { - this.registryObjectDao = registryObjectDao; + public void setReplicationEventDao(ReplicationEventDao replicationEventDao) { + this.replicationEventDao = replicationEventDao; } public void setRegistryDao(RegistryDao registryDao) { this.registryDao = registryDao; } - public void setRegistrySoapServices( - RegistrySOAPServices registrySoapServices) { - this.registrySoapServices = registrySoapServices; + public void setTxTemplate(TransactionTemplate txTemplate) { + this.txTemplate = txTemplate; + } + + public void setSoapService(RegistrySOAPServices soapService) { + this.soapService = soapService; + } + + public void setLocalLifecycleManager(LifecycleManager localLifecycleManager) { + this.localLifecycleManager = localLifecycleManager; } public void setDataDeliveryRestClient( @@ -1511,8 +1137,25 @@ public class RegistryFederationManager implements RegistryInitializedListener { this.dataDeliveryRestClient = dataDeliveryRestClient; } - public static FederationProperties getFederationProperties() { - return federationProperties; + public void setRegistryObjectDao(RegistryObjectDao registryObjectDao) { + this.registryObjectDao = registryObjectDao; + } + + public void setFederatedRegistryMonitor( + FederatedRegistryMonitor federatedRegistryMonitor) { + this.federatedRegistryMonitor = federatedRegistryMonitor; + } + + public void setFederationDbInit(FederationDbInit federationDbInit) { + this.federationDbInit = federationDbInit; + } + + public static Set getReplicatedObjectTypes() { + return replicatedObjectTypes; + } + + public NotificationServers getServers() { + return servers; } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryNotFoundException.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryNotFoundException.java new file mode 100644 index 0000000000..de44fae17f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryNotFoundException.java @@ -0,0 +1,77 @@ +/** + * 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 com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; + +/** + * + * Exception class used by the registry federation manager for when a registry + * is not found in the federation + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 2/24/2014    2769        bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class RegistryNotFoundException extends EbxmlRegistryException { + + private static final long serialVersionUID = -8058778534952899091L; + + /** + * Creates a new exception with the given message + * + * @param message + * The message to attach to the exception + */ + public RegistryNotFoundException(String message) { + super(message); + } + + /** + * Creates a new exception with the given message and cause + * + * @param message + * The message to attach to the exception + * @param cause + * The underlying cause of the exception + */ + public RegistryNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new exception with the given cause + * + * @param cause + * The underlying cause of the exception + */ + public RegistryNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/ReplicationEvent.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/ReplicationEvent.java new file mode 100644 index 0000000000..1c45003298 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/ReplicationEvent.java @@ -0,0 +1,154 @@ +/** + * 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 javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.raytheon.uf.common.dataplugin.persist.IPersistableDataObject; + +/** + *
+ * 
+ * Class encapsulating a registry event
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 2/19/2014    2769        bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +@Entity +@Table(name = "registryreplicationevents") +public class ReplicationEvent implements IPersistableDataObject { + + @Id + @GeneratedValue + private Long id; + + @Column + private String source; + + @Column + private String eventType; + + @Column + private long eventTime; + + @Column + private String objectId; + + @Column + private String objectType; + + @Column + private String replicatedTo; + + public ReplicationEvent() { + super(); + } + + public ReplicationEvent(String eventType, long eventTime, String objectId, + String objectType, String source) { + super(); + this.eventType = eventType; + this.eventTime = eventTime; + this.objectId = objectId; + this.objectType = objectType; + this.source = source; + } + + @Override + public Long getIdentifier() { + return getId(); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public void setSource(String source) { + this.source = source; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public long getEventTime() { + return eventTime; + } + + public void setEventTime(long eventTime) { + this.eventTime = eventTime; + } + + public String getObjectId() { + return objectId; + } + + public void setObjectId(String objectId) { + this.objectId = objectId; + } + + public String getObjectType() { + return objectType; + } + + public void setObjectType(String objectType) { + this.objectType = objectType; + } + + public String getReplicatedTo() { + return replicatedTo; + } + + public void setReplicatedTo(String replicatedTo) { + this.replicatedTo = replicatedTo; + } + + public void addReplicatedTo(String recipient) { + if (this.replicatedTo == null) { + this.replicatedTo = ":" + recipient + ":"; + } else if (!this.replicatedTo.contains(recipient)) { + this.replicatedTo += ":" + recipient + ":"; + } + } + + public String getSource() { + return source; + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationHostConfiguration.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationHostConfiguration.java deleted file mode 100644 index b267f6cd64..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationHostConfiguration.java +++ /dev/null @@ -1,105 +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 javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -/** - * - * Host configuration information - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#     Engineer    Description
- * ------------ ----------  ----------- --------------------------
- * 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
- * 
- * - * @author bphillip - * @version 1 - */ -@XmlAccessorType(XmlAccessType.NONE) -public class NotificationHostConfiguration { - - /** The site that this registry is running at */ - @XmlElement - private String registrySiteName; - - /** Descripion of the host */ - @XmlElement - private String registryDescription; - - /** The name of the host */ - @XmlElement - private String registryBaseURL; - - /** True if subscriptions should be reciprocated */ - @XmlElement - private boolean reciprocate = false; - - public NotificationHostConfiguration() { - - } - - public NotificationHostConfiguration(String registrySiteName, - String registryDescription, String registryBaseURL) { - this.registrySiteName = registrySiteName; - this.registryDescription = registryDescription; - this.registryBaseURL = registryBaseURL; - } - - public String getRegistrySiteName() { - return registrySiteName; - } - - public void setRegistrySiteName(String registrySiteName) { - this.registrySiteName = registrySiteName; - } - - public String getRegistryDescription() { - return registryDescription; - } - - public void setRegistryDescription(String registryDescription) { - this.registryDescription = registryDescription; - } - - public String getRegistryBaseURL() { - return registryBaseURL; - } - - public void setRegistryBaseURL(String registryBaseURL) { - this.registryBaseURL = registryBaseURL; - } - - public boolean isReciprocate() { - return reciprocate; - } - - public void setReciprocate(boolean reciprocate) { - this.reciprocate = reciprocate; - } -} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationServers.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationServers.java index ae07b39d02..84d60b220b 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationServers.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/replication/NotificationServers.java @@ -19,8 +19,8 @@ **/ package com.raytheon.uf.edex.datadelivery.registry.replication; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -43,6 +43,7 @@ import javax.xml.bind.annotation.XmlRootElement; * 5/21/2013 1707 bphillip Removed unused fields * 6/4/2013 1707 bphillip Renamed and changed fields for clarity * 10/30/2013 1538 bphillip getRegistryReplicationServers returns empty list if no servers are specified + * 2/27/2014 2769 bphillip Changed replicationservers variable to set of strings * * * @author bphillip @@ -53,19 +54,27 @@ import javax.xml.bind.annotation.XmlRootElement; public class NotificationServers { /** The server located upstream from this server */ - @XmlElements({ @XmlElement(name = "registry", type = NotificationHostConfiguration.class) }) - private CopyOnWriteArrayList registryReplicationServers; + @XmlElements({ @XmlElement(name = "registry") }) + private CopyOnWriteArraySet registryReplicationServers; - public List getRegistryReplicationServers() { + public Set getRegistryReplicationServers() { if (registryReplicationServers == null) { - registryReplicationServers = new CopyOnWriteArrayList(); + registryReplicationServers = new CopyOnWriteArraySet(); } return registryReplicationServers; } public void setRegistryReplicationServers( - List registryReplicationServers) { - this.registryReplicationServers = new CopyOnWriteArrayList( + Set registryReplicationServers) { + this.registryReplicationServers = new CopyOnWriteArraySet( registryReplicationServers); } + + public void addReplicationServer(String registryId) { + this.getRegistryReplicationServers().add(registryId); + } + + public void removeReplicationServer(String registryId) { + this.getRegistryReplicationServers().remove(registryId); + } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/DataDeliveryRESTServices.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/DataDeliveryRESTServices.java index 2670226519..d845d63ad8 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/DataDeliveryRESTServices.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/DataDeliveryRESTServices.java @@ -25,7 +25,7 @@ import org.apache.commons.lang.exception.ExceptionUtils; 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.datadelivery.registry.web.IRegistryFederationManager; import com.raytheon.uf.common.registry.constants.RegistryAvailability; import com.raytheon.uf.common.registry.services.RegistryRESTServices; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -42,6 +42,7 @@ import com.raytheon.uf.common.status.UFStatus; * ------------ ---------- ----------- -------------------------- * 10/30/2013 1538 bphillip Initial Creation * 11/20/2013 2534 bphillip Eliminated service caching + * 2/27/2014 2769 bphillip Add RegistryFederationManager to exposed REST services * * * @author bphillip @@ -62,9 +63,10 @@ public class DataDeliveryRESTServices extends RegistryRESTServices { super(); } - public IRegistryFederationService getFederationService(String baseURL) { - return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH, - IRegistryFederationService.class); + public IRegistryFederationManager getRegistryFederationManager( + String baseURL) { + return createService(baseURL + DATA_DELIVERY_REST_SERVICE_PATH, + IRegistryFederationManager.class); } /** @@ -76,7 +78,7 @@ public class DataDeliveryRESTServices extends RegistryRESTServices { */ public IRegistryAvailableRestService getRegistryAvailableService( String baseURL) { - return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH, + return createService(baseURL + DATA_DELIVERY_REST_SERVICE_PATH, IRegistryAvailableRestService.class); } @@ -118,7 +120,7 @@ public class DataDeliveryRESTServices extends RegistryRESTServices { */ public IRegistryDataAccessService getRegistryDataAccessService( String baseURL) { - return getPort(baseURL + DATA_DELIVERY_REST_SERVICE_PATH, + return createService(baseURL + DATA_DELIVERY_REST_SERVICE_PATH, IRegistryDataAccessService.class); } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java index a6f0674c2d..53fb3bff8b 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java @@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.datadelivery.registry.web.IRegistryAvailableRestService; import com.raytheon.uf.common.registry.constants.RegistryAvailability; +import com.raytheon.uf.edex.datadelivery.registry.federation.RegistryFederationManager; import com.raytheon.uf.edex.registry.ebxml.dao.DbInit; /** @@ -64,7 +65,8 @@ public class RegistryAvailableRestService implements @GET @Produces("text/plain") public String isRegistryAvailable() { - if (DbInit.isDbInitialized()) { + if (DbInit.isDbInitialized() + && RegistryFederationManager.initialized.get()) { return RegistryAvailability.AVAILABLE; } else { return RegistryAvailability.DB_NOT_INITIALIZED; diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryFederationStatus.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryFederationStatus.java deleted file mode 100644 index 3ee5a42ccf..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryFederationStatus.java +++ /dev/null @@ -1,349 +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.web; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -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; - -import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException; -import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest; -import oasis.names.tc.ebxml.regrep.xsd.query.v4.ResponseOptionType; -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.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 org.springframework.transaction.annotation.Transactional; -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; -import com.raytheon.uf.common.registry.constants.DeliveryMethodTypes; -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.registry.ebxml.dao.RegistryDao; -import com.raytheon.uf.edex.registry.ebxml.dao.SubscriptionDao; -import com.raytheon.uf.edex.registry.ebxml.services.notification.RegistrySubscriptionManager; -import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; - -/** - *
- * Set of services used by the federation status web interface to modify federation associations
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#     Engineer    Description
- * ------------ ----------  ----------- --------------------------
- * 10/30/2013    1538       bphillip    Initial Creation
- * 11/20/2013   2534        bphillip    Added interface
- * 12/2/2013    1829        bphillip    Changed to use modified call to getRegistryObject
- * 12/9/2013    2613        bphillip    Changed getRegistriesSubscribedTo to not execute remote queries
- * 
- * - * @author bphillip - * @version 1 - **/ -@Path(IRegistryFederationService.REGISTRY_FEDERATION_STATUS_PATH) -@Transactional -public class RegistryFederationStatus implements IRegistryFederationService { - - /** The logger instance */ - private static final IUFStatusHandler statusHandler = UFStatus - .getHandler(RegistryFederationStatus.class); - - /** Comparator to sort registry instances */ - private static final Comparator REGISTRY_COMPARATOR = new Comparator() { - @Override - public int compare(RegistryObjectType o1, RegistryObjectType o2) { - return o1.getId().compareTo(o2.getId()); - } - }; - - /** Data Access object for registry objects */ - private RegistryDao registryDao; - - /** Data Access object for registry subscription objects */ - private SubscriptionDao subscriptionDao; - - /** The registry replication manager */ - private RegistryFederationManager federationManager; - - /** Data Delivery rest services client */ - private DataDeliveryRESTServices dataDeliveryRestClient; - - /** Registry soap services client */ - private RegistrySOAPServices registrySoapServices; - - /** - * The address to the NCF registry loaded from the NCF_ADDRESS item in - * setup.env - */ - private String ncfAddress = System.getenv("NCF_ADDRESS"); - - @GET - @Path("isFederated") - public String isFederated() { - return System.getenv("EBXML_REGISTRY_FEDERATION_ENABLED"); - } - - @GET - @Path("getMyRegistryInfo") - public String getMyRegistryInfo() { - StringBuilder builder = new StringBuilder(); - RegistryType myRegistry = registryDao - .getRegistryByBaseURL(RegistryUtil.LOCAL_REGISTRY_ADDRESS); - appendRegistryInfo(myRegistry, builder); - return builder.toString(); - - } - - @GET - @Path("getFederationMembers") - public String getFederationMembers() throws MsgRegistryException { - StringBuilder builder = new StringBuilder(); - QueryType query = new QueryType( - CanonicalQueryTypes.FIND_ASSOCIATED_OBJECTS); - query.getSlot().add( - new SlotType(QueryConstants.ASSOCIATION_TYPE, - new StringValueType( - AssociationTypes.HAS_FEDERATION_MEMBER))); - query.getSlot().add( - new SlotType(QueryConstants.SOURCE_OBJECT_ID, - new StringValueType( - RegistryFederationManager.FEDERATION_ID))); - - QueryRequest queryRequest = new QueryRequest("Get Federation Members", - query, new ResponseOptionType(QueryReturnTypes.REGISTRY_OBJECT, - true)); - List federationMembers = registrySoapServices - .getQueryServiceForHost(ncfAddress).executeQuery(queryRequest) - .getRegistryObjects(); - Collections.sort(federationMembers, REGISTRY_COMPARATOR); - for (RegistryObjectType obj : federationMembers) { - if (obj instanceof RegistryType) { - RegistryType registry = (RegistryType) obj; - appendRegistryInfo(registry, builder); - } - } - - return builder.toString(); - } - - @GET - @Path("getRegistriesSubscribedTo") - public String getRegistriesSubscribedTo() { - StringBuilder builder = new StringBuilder(); - if (this.federationManager.getServers() != null - && !CollectionUtil.isNullOrEmpty(this.federationManager - .getServers().getRegistryReplicationServers())) { - List registries = new ArrayList(); - for (NotificationHostConfiguration hostConfig : this.federationManager - .getServers().getRegistryReplicationServers()) { - RegistryType reg = registryDao.getRegistryByBaseURL(hostConfig - .getRegistryBaseURL()); - if (reg != null) { - registries.add(reg); - } - } - Collections.sort(registries, REGISTRY_COMPARATOR); - for (RegistryObjectType reg : registries) { - appendRegistryInfo((RegistryType) reg, builder); - } - } - return builder.toString(); - } - - @GET - @Path("getRegistrySubscribing") - public String getRegistrySubscribing() { - StringBuilder builder = new StringBuilder(); - List registries = new ArrayList(); - for (SubscriptionType sub : subscriptionDao.getAll()) { - DeliveryInfoType deliveryInfo = sub.getDeliveryInfo().get(0); - 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(); - if (endpointType.equals(DeliveryMethodTypes.SOAP)) { - RegistryType registry = registryDao - .getRegistryByBaseURL(serviceAddress.replace( - "/notificationListener", "")); - if (registry != null && !registries.contains(registry)) { - registries.add(registry); - } - - } - } - Collections.sort(registries, REGISTRY_COMPARATOR); - for (RegistryObjectType reg : registries) { - appendRegistryInfo((RegistryType) reg, builder); - } - return builder.toString(); - } - - @GET - @Path("getObjectTypesReplicated") - public String getObjectTypesReplicated() { - StringBuilder builder = new StringBuilder(); - for (String objectType : RegistryFederationManager.getObjectTypes()) { - builder.append(objectType).append(StringUtil.NEWLINE); - } - return builder.toString(); - } - - @GET - @Path("syncWithRegistry/{registryId}") - public String syncWithRegistry(@PathParam("registryId") String registryId) { - StringBuilder builder = new StringBuilder(); - RegistryType registry = registryDao.getById(registryId); - if (registry == null) { - builder.append("Registry [" + registryId - + "] not in federation. Unable to synchronize."); - } else { - try { - federationManager.synchronizeRegistryWithFederation(registry - .getBaseURL()); - } catch (Exception e) { - statusHandler.error("Error synchronizing registry!", e); - builder.append("Error synchronizing registry [" + registryId - + "]: " + e.getLocalizedMessage()); - } - } - return builder.toString(); - } - - @GET - @Path("subscribeToRegistry/{registryId}") - public String subscribeToRegistry(@PathParam("registryId") String registryId) - throws RegistryServiceException, JAXBException { - StringBuilder builder = new StringBuilder(); - RegistryType registry = dataDeliveryRestClient.getRegistryObject( - ncfAddress, registryId); - if (registry == null) { - builder.append("Registry [") - .append(registryId) - .append("] not in federation. Unable to submit subscriptions."); - } else { - 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(); - } - - @GET - @Path("unsubscribeFromRegistry/{registryId}") - public String unsubscribeFromRegistry( - @PathParam("registryId") String registryId) { - StringBuilder builder = new StringBuilder(); - RegistryType registry = registryDao.getById(registryId); - if (registry == null) { - builder.append("Registry [" + registryId - + "] not in federation. Unable to unsubscribe."); - } else { - RegistryType localRegistry = registryDao - .getRegistryByBaseURL(RegistryUtil.LOCAL_REGISTRY_ADDRESS); - dataDeliveryRestClient.getRegistryDataAccessService( - registry.getBaseURL()).removeSubscriptionsForSite( - localRegistry.getOwner()); - builder.append("Successfully unsubscribed from registry [" - + registryId + "]"); - federationManager.removeNotificationServer(registry.getBaseURL()); - federationManager.saveNotificationServers(); - } - return builder.toString(); - } - - /** - * Appends registry information to the stringbuilder - * - * @param registry - * The registry to get information for - * @param builder - * The string builder to append to - */ - private void appendRegistryInfo(RegistryType registry, StringBuilder builder) { - builder.append(registry.getId()).append(","); - builder.append(registry.getBaseURL()).append(","); - builder.append(registry.getConformanceProfile()).append(","); - builder.append(registry.getSpecificationVersion()); - builder.append(StringUtil.NEWLINE); - } - - public void setFederationManager(RegistryFederationManager federationManager) { - this.federationManager = federationManager; - } - - public void setRegistryDao(RegistryDao registryDao) { - this.registryDao = registryDao; - } - - public void setSubscriptionDao(SubscriptionDao subscriptionDao) { - this.subscriptionDao = subscriptionDao; - } - - public void setDataDeliveryRestClient( - DataDeliveryRESTServices dataDeliveryRestClient) { - this.dataDeliveryRestClient = dataDeliveryRestClient; - } - - public void setRegistrySoapServices( - RegistrySOAPServices registrySoapServices) { - this.registrySoapServices = registrySoapServices; - } -} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/utility/edex_static/base/datadelivery/registry/notificationServers.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/utility/edex_static/base/datadelivery/registry/notificationServers.xml index 27f453a80c..6e3b8076b3 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/utility/edex_static/base/datadelivery/registry/notificationServers.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/utility/edex_static/base/datadelivery/registry/notificationServers.xml @@ -1,19 +1,10 @@ - - - - - - - - + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml index 1acdf4212b..22d6eb897f 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml @@ -5,6 +5,10 @@ + + + + diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml index 1754dd11f0..b33b9ff8b1 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml @@ -36,7 +36,6 @@ - diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-subscription-edex-impl.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-subscription-edex-impl.xml deleted file mode 100644 index aa0566cecc..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-subscription-edex-impl.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties index ffa3087f62..99492c50ac 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties @@ -1,7 +1,7 @@ -# The period which registry subscriptions are processed -ebxml-subscription-process.cron=0/20+*+*+*+*+? +# The period which registry replication occurs +ebxml-replication-process.cron=0/10+*+*+*+*+? # The period which the registry runs the garbage collection -ebxml-garbage-collect-process.cron=0+0/5+*+*+*+? +ebxml-garbage-collect-process.cron=0+0+0/1+*+*+? # When a federation synchonization is necessary, this is the number of threads # that will be used for synchronization ebxml-federation-sync-threads=3 diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AssociationDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AssociationDao.java index 3cd58a678e..82005f622a 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AssociationDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AssociationDao.java @@ -24,6 +24,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; /** @@ -38,6 +41,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 7/30/2012 724 bphillip Initial creation * 3/18/2013 1802 bphillip Modified to use transaction boundaries and spring injection * 4/9/2013 1802 bphillip Removed exception catching + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -57,6 +61,7 @@ public class AssociationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByTargetAndType(String target, String type) { return executeHQLQuery("from AssociationType obj where obj.targetObject='" + target + "' and obj.type='" + type + "'"); @@ -73,6 +78,7 @@ public class AssociationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getBySourceAndType(String source, String type) { return executeHQLQuery("from AssociationType obj where obj.sourceObject='" + source + "' and obj.type='" + type + "'"); @@ -91,6 +97,7 @@ public class AssociationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getBySourceTargetAndType(String source, String target, String type) { return executeHQLQuery("from AssociationType obj where obj.sourceObject='" @@ -109,6 +116,7 @@ public class AssociationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAllAssociations(String objReferenced) { return executeHQLQuery("from AssociationType obj where obj.sourceObject='" + objReferenced @@ -126,6 +134,7 @@ public class AssociationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAssociationsTo(String objReferenced) { return executeHQLQuery("from AssociationType obj where obj.targetObject='" + objReferenced + "'"); @@ -140,6 +149,7 @@ public class AssociationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAssociationsFrom(String objReferenced) { return executeHQLQuery("from AssociationType obj where obj.sourceObject='" + objReferenced + "'"); diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java index ac9a5dac20..a84d01348d 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java @@ -107,7 +107,7 @@ public class AuditableEventTypeDao extends private static final String ORDER_CLAUSE = " order by event.timestamp asc"; /** The number of hours to retain auditable events */ - private static final int AUDITABLE_EVENT_RETENTION_TIME = 48; + public static final int AUDITABLE_EVENT_RETENTION_TIME = 48; /** Cutoff parameter for the query to get the expired events */ private static final String GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER = "cutoff"; @@ -146,7 +146,7 @@ public class AuditableEventTypeDao extends * @throws EbxmlRegistryException * If errors occur purging auditable events */ - @Transactional(propagation = Propagation.REQUIRED) + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public List getExpiredEvents(int limit) throws EbxmlRegistryException { Calendar cutoffTime = TimeUtil.newGmtCalendar(); @@ -174,6 +174,7 @@ public class AuditableEventTypeDao extends * @throws EbxmlRegistryException * @throws MsgRegistryException */ + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public List getEventsOfInterest( SubscriptionType subscription, String serviceAddress, XMLGregorianCalendar startTime, XMLGregorianCalendar endTime, @@ -336,6 +337,7 @@ public class AuditableEventTypeDao extends * The delivery address to check * @return The last sent date in millis */ + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public Long getSendTime(AuditableEventType auditableEvent, String subscriptionId, String deliveryAddress) { SlotType slot = auditableEvent.getSlotByName(subscriptionId diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/ClassificationNodeDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/ClassificationNodeDao.java index 01a4e1bb01..2b242ae974 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/ClassificationNodeDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/ClassificationNodeDao.java @@ -23,6 +23,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationNodeType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + /** * Data access object for retrieving ClassificationNodeTypes * @@ -36,6 +39,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationNodeType; * 8/3/2012 724 bphillip Added more methods for getting classification nodes * 3/18/2013 1802 bphillip Modified to use transaction boundaries and spring injection * 4/9/2013 1802 bphillip Removed exception catching + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -45,19 +49,23 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationNodeType; public class ClassificationNodeDao extends RegistryObjectTypeDao { - /** Regex to use when querying for telephone types */ - public static final String TELEPHONE_TYPE_REGEX = "urn:oasis:names:tc:ebxml-regrep:PhoneType:%"; + private static final String GET_BY_PATH_QUERY = "select obj from ClassificationNodeType obj where obj.path=:path"; - /** Regex to use when querying for postal address types */ - public static final String ADDRESS_TYPE_REGEX = "urn:oasis:names:tc:ebxml-regrep:PostalAddressType%"; + private static final String GET_NODE_FROM_CODE_QUERY = "select obj.id from ClassificationNodeType obj where obj.code=:code"; - /** Regex to use when querying for email types */ - public static final String EMAIL_TYPE_REGEX = "urn:oasis:names:tc:ebxml-regrep:EmailType:%"; + private static final String GET_CODE_FROM_NODE_QUERY = "select obj.code from ClassificationNodeType obj where obj.id=:id"; + + private static final String GET_TELEPHONE_TYPES_QUERY = "select obj.code from ClassificationNodeType obj where obj.lid like 'urn:oasis:names:tc:ebxml-regrep:PhoneType:%'"; + + private static final String GET_ADDRESS_TYPES_QUERY = "select obj.code from ClassificationNodeType obj where obj.lid like 'urn:oasis:names:tc:ebxml-regrep:PostalAddressType%'"; + + private static final String GET_EMAIL_TYPES_QUERY = "select obj.code from ClassificationNodeType obj where obj.lid like 'urn:oasis:names:tc:ebxml-regrep:EmailType:%'"; public ClassificationNodeDao() { } + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public boolean isValidNode(String id) { return getById(id) != null; } @@ -69,10 +77,10 @@ public class ClassificationNodeDao extends * The path to get the classification node type for * @return The ClassificationNode object with the specified path */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public ClassificationNodeType getByPath(String path) { - List result = this - .executeHQLQuery("select obj from ClassificationNodeType obj where obj.path='" - + path + "'"); + List result = this.executeHQLQuery( + GET_BY_PATH_QUERY, "path", path); if (result.isEmpty()) { return null; } else { @@ -87,10 +95,10 @@ public class ClassificationNodeDao extends * The code of the classification node * @return The ID of the classification node with the given code */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public String getNodeFromCode(String code) { - List results = this - .executeHQLQuery("select obj.id from ClassificationNodeType obj where obj.code='" - + code + "'"); + List results = this.executeHQLQuery(GET_NODE_FROM_CODE_QUERY, + "code", code); if (results.isEmpty()) { return null; @@ -106,10 +114,10 @@ public class ClassificationNodeDao extends * The object ID of the classification node * @return The code of the classification node with the given ID */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public String getCodeFromNode(String id) { - List results = this - .executeHQLQuery("select obj.code from ClassificationNodeType obj where obj.id='" - + id + "'"); + List results = this.executeHQLQuery(GET_CODE_FROM_NODE_QUERY, + "id", id); if (results.isEmpty()) { return null; @@ -123,11 +131,10 @@ public class ClassificationNodeDao extends * * @return The codes of the telephone types in the registry */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getTelephoneTypes() { - return this - .executeHQLQuery("select obj.code from ClassificationNodeType obj where obj.lid like '" - + TELEPHONE_TYPE_REGEX + "'"); + return this.executeHQLQuery(GET_TELEPHONE_TYPES_QUERY); } @@ -136,11 +143,10 @@ public class ClassificationNodeDao extends * * @return The codes of the address types in the registry */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAddressTypes() { - return this - .executeHQLQuery("select obj.code from ClassificationNodeType obj where obj.lid like '" - + ADDRESS_TYPE_REGEX + "'"); + return this.executeHQLQuery(GET_ADDRESS_TYPES_QUERY); } @@ -149,10 +155,9 @@ public class ClassificationNodeDao extends * * @return The codes dmail types in the registry */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getEmailTypes() { - return this - .executeHQLQuery("select obj.code from ClassificationNodeType obj where obj.lid like '" - + EMAIL_TYPE_REGEX + "'"); + return this.executeHQLQuery(GET_EMAIL_TYPES_QUERY); } @Override diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/FederationDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/FederationDao.java index d9fce7001b..f5ee020bb8 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/FederationDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/FederationDao.java @@ -21,6 +21,9 @@ package com.raytheon.uf.edex.registry.ebxml.dao; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.FederationType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + /** * Data access object for FederationType objects * @@ -32,6 +35,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.FederationType; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 5/21/2013 2022 bphillip Initial implementation + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @author bphillip @@ -46,10 +50,12 @@ public class FederationDao extends RegistryObjectTypeDao { return FederationType.class; } + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public long getFederationCount() { return (Long) this.executeHQLQuery(COUNT_QUERY).get(0); } + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public boolean federationsExist() { return getFederationCount() > 0; } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/IdentifiableTypeDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/IdentifiableTypeDao.java index 323ae7b2f3..8108b76b0d 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/IdentifiableTypeDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/IdentifiableTypeDao.java @@ -27,6 +27,8 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.IdentifiableType; import org.hibernate.criterion.Property; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -44,6 +46,7 @@ import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; * 4/9/2013 1802 bphillip Removed exception catching * 10/08/2013 1682 bphillip Added the id like query * 12/2/2013 1829 bphillip Now extends ExtensibleObjectTypeDao + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -68,6 +71,7 @@ public class IdentifiableTypeDao extends * @throws EbxmlRegistryException * If the query encounters errors */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getById(String... ids) throws EbxmlRegistryException { return getById(Arrays.asList(ids)); } @@ -84,6 +88,7 @@ public class IdentifiableTypeDao extends * If the query encounters errors */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getById(List ids) throws EbxmlRegistryException { return createCriteria() .add(Property.forName(QueryConstants.ID).in(ids)).list(); @@ -97,6 +102,7 @@ public class IdentifiableTypeDao extends * @return All IdentifiableType objects matching the given id */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByIdUsingLike(String id) { return createCriteria().add( Property.forName(QueryConstants.ID).like(id)).list(); diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/OrganizationDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/OrganizationDao.java index 19dd5881c1..05b66e5331 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/OrganizationDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/OrganizationDao.java @@ -25,6 +25,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.OrganizationType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.constants.AssociationTypes; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; @@ -40,6 +43,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 7/30/2012 724 bphillip Initial creation * 3/13/2013 1082 bphillip Modified to use spring injection and transaction boundaries * 4/9/2013 1802 bphillip Removed exception catching + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -48,6 +52,8 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; */ public class OrganizationDao extends RegistryObjectTypeDao { + private static final String GET_ORGANIZATION_BY_NAME_QUERY = "select obj from OrganizationType obj inner join obj.name.localizedString as theName where lower(obj.id) like :name1 or lower(theName.value) like :name2 order by obj.id asc"; + /** The Association data access object */ private AssociationDao associationDao; @@ -65,6 +71,7 @@ public class OrganizationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAllOrganizations() { return getAll(); } @@ -79,11 +86,12 @@ public class OrganizationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getOrganizationByName(String name) { - List orgs = executeHQLQuery("select obj from OrganizationType obj inner join obj.name.localizedString as theName where lower(obj.id) like '%" - + name.toLowerCase() - + "%' or lower(theName.value) like '%" - + name.toLowerCase() + "%' order by obj.id asc"); + List orgs = executeHQLQuery( + GET_ORGANIZATION_BY_NAME_QUERY, "name1", + "%" + name.toLowerCase() + "%", "name2", + "%" + name.toLowerCase() + "%"); return orgs; } @@ -96,6 +104,7 @@ public class OrganizationDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public OrganizationType getOrganizationForUser(String user) throws EbxmlRegistryException { List associations = associationDao.getBySourceAndType( diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/PersonDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/PersonDao.java index 168fa75164..c63b92dcc4 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/PersonDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/PersonDao.java @@ -26,6 +26,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.PersonType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.constants.AssociationTypes; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; @@ -41,6 +44,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 7/30/2012 724 bphillip Initial creation * 3/13/2013 1082 bphillip Modified to use spring injection and transaction boundaries * 4/9/2013 1802 bphillip Removed exception catching + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -49,6 +53,15 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; */ public class PersonDao extends RegistryObjectTypeDao { + private static final String GET_BY_FIRST_NAME_QUERY = "select obj from PersonType obj where lower(obj.personName.firstName) like :firstName order by obj.personName.lastName asc, obj.personName.firstName asc"; + + private static final String GET_BY_LAST_NAME_QUERY = "select obj from PersonType obj where lower(obj.personName.lastName) like :lastName order by obj.personName.lastName asc, obj.personName.firstName asc"; + + private static final String GET_BY_FIRST_AND_LAST_NAME_QUERY = "select obj from PersonType obj where lower(obj.personName.firstName) like :firstname and lower(obj.personName.lastName) like :lastName order by obj.personName.lastName asc, obj.personName.firstName asc"; + + private static final String GET_ALL_USER_NAMES_QUERY = "select obj.id, obj.personName.firstName, obj.personName.lastName from PersonType obj " + + "order by obj.personName.lastName asc, obj.personName.firstName asc"; + private AssociationDao associationDao; /** @@ -65,14 +78,13 @@ public class PersonDao extends RegistryObjectTypeDao { * The first name * @return The matching users */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByFirstName(String firstName) { if (firstName == null || firstName.trim().isEmpty()) { return Collections.emptyList(); } - return this - .executeHQLQuery("select obj from PersonType obj where lower(obj.personName.firstName) like '%" - + firstName.toLowerCase() - + "%' order by obj.personName.lastName asc, obj.personName.firstName asc"); + return this.executeHQLQuery(GET_BY_FIRST_NAME_QUERY, ":firstName", "%" + + firstName.toLowerCase() + "%"); } @@ -84,14 +96,13 @@ public class PersonDao extends RegistryObjectTypeDao { * The last name * @return The matching users */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByLastName(String lastName) { if (lastName == null || lastName.trim().isEmpty()) { return Collections.emptyList(); } - return this - .executeHQLQuery("select obj from PersonType obj where lower(obj.personName.lastName) like '%" - + lastName.toLowerCase() - + "%' order by obj.personName.lastName asc, obj.personName.firstName asc"); + return this.executeHQLQuery(GET_BY_LAST_NAME_QUERY, "lastName", "%" + + lastName.toLowerCase() + "%"); } @@ -105,6 +116,7 @@ public class PersonDao extends RegistryObjectTypeDao { * The last name * @return The matching users */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByFirstAndLastName(String firstName, String lastName) { if (firstName.trim().isEmpty() && lastName.trim().isEmpty()) { @@ -115,12 +127,9 @@ public class PersonDao extends RegistryObjectTypeDao { } else if (lastName == null || lastName.trim().isEmpty()) { return getByFirstName(firstName); } - return this - .executeHQLQuery("select obj from PersonType obj where lower(obj.personName.firstName) like '%" - + firstName.toLowerCase() - + "%' and lower(obj.personName.lastName) like '%" - + lastName.toLowerCase() - + "%' order by obj.personName.lastName asc, obj.personName.firstName asc"); + return this.executeHQLQuery(GET_BY_FIRST_AND_LAST_NAME_QUERY, + "firstName", "%" + firstName.toLowerCase() + "%", "lastName", + "%" + lastName.toLowerCase() + "%"); } @@ -131,6 +140,7 @@ public class PersonDao extends RegistryObjectTypeDao { * The organization ID * @return The users associated with the organization */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getEmployeesOfOrganization(String orgId) { List employees = new ArrayList(); List associations = associationDao.getByTargetAndType( @@ -149,10 +159,9 @@ public class PersonDao extends RegistryObjectTypeDao { * the id, first name, and last name for each PersonType object in * the registry */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public Object getAllUserNames() throws EbxmlRegistryException { - return this - .executeHQLQuery("select obj.id, obj.personName.firstName, obj.personName.lastName from PersonType obj " - + "order by obj.personName.lastName asc, obj.personName.firstName asc"); + return this.executeHQLQuery(GET_ALL_USER_NAMES_QUERY); } @@ -161,6 +170,7 @@ public class PersonDao extends RegistryObjectTypeDao { * * @return All personType objects in the registry */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAllUsers() throws EbxmlRegistryException { return getByFirstAndLastName("", ""); } @@ -172,6 +182,7 @@ public class PersonDao extends RegistryObjectTypeDao { * The ID of the person * @return The person with the given ID */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public PersonType getByUserId(String userId) { return this.getById(userId); } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/QueryDefinitionDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/QueryDefinitionDao.java index 235adfdc58..19fbd5dcf9 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/QueryDefinitionDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/QueryDefinitionDao.java @@ -24,6 +24,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ParameterType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryDefinitionType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + /** * * Data access object for QueryDefinitionType objects @@ -36,6 +39,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryDefinitionType; * ------------ ---------- ----------- -------------------------- * 10/8/2013 1682 bphillip Initial implementation * 12/2/2013 1829 bphillip Changed get parameters for query method + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @author bphillip @@ -55,6 +59,7 @@ public class QueryDefinitionDao extends * * @return The ids of the query definitions in the registry */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getQueryIds() { return executeHQLQuery(GET_QUERY_IDS_QUERY); } @@ -66,6 +71,7 @@ public class QueryDefinitionDao extends * The query id to get the parameters for * @return The parameters for the specified query */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getParametersForQuery(String queryId) { return this.getById(queryId).getParameter(); } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryDao.java index 51114a6d90..b20d05f41b 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryDao.java @@ -21,6 +21,9 @@ package com.raytheon.uf.edex.registry.ebxml.dao; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + /** * * Data access object for RegistryType objects @@ -41,6 +44,7 @@ public class RegistryDao extends RegistryObjectTypeDao { private static final String QUERY_BY_BASE_URL = "FROM RegistryType reg where reg.baseURL=:baseURL"; + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public RegistryType getRegistryByBaseURL(String baseURL) { return this.uniqueResult(QUERY_BY_BASE_URL, "baseURL", baseURL); } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java index ba6700e03e..6c72955304 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java @@ -24,6 +24,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.edex.database.DataAccessLayerException; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; @@ -41,6 +44,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 6/4/2013 2022 bphillip Added delete objects of type method * 7/29/2013 2191 bphillip Added new methods to support registry synchronization * 8/1/2013 1693 bphillip Added methods to facilitate implementation of the lifecyclemanager according to the 4.0 spec + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -96,6 +100,7 @@ public class RegistryObjectDao extends * The object to get the next version number for * @return The next version number */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public String getNextVersion(RegistryObjectType objectToVersion) { String lid = objectToVersion.getLid(); String version = objectToVersion.getVersionInfo().getVersionName(); @@ -126,6 +131,7 @@ public class RegistryObjectDao extends * The id to check * @return True if the id exists, else false */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public boolean idExists(String id) { return ((Long) this.executeHQLQuery(ID_EXISTS_QUERY, "id", id).get(0)) != 0; } @@ -137,6 +143,7 @@ public class RegistryObjectDao extends * The lid to check * @return Treu if the lid exists, else false */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public boolean lidExists(String lid) { return ((Long) this.executeHQLQuery(LID_EXISTS_QUERY, "lid", lid) .get(0)) != 0; @@ -149,6 +156,7 @@ public class RegistryObjectDao extends * The object type to get the ids for * @return The list of object ids of objects of the given type */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getRegistryObjectIdsOfType(String objectType) { return this.executeHQLQuery(GET_IDS_BY_OBJECT_TYPE, "objectType", objectType); @@ -180,6 +188,7 @@ public class RegistryObjectDao extends * @throws EbxmlRegistryException * If the HQL query fails */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getAllRegistryObjects() { return getAll(); } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectTypeDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectTypeDao.java index 9598c062ef..366ef1ced1 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectTypeDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectTypeDao.java @@ -27,6 +27,8 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; import org.hibernate.SessionFactory; import org.hibernate.criterion.Property; import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -44,6 +46,7 @@ import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; * 4/9/2013 1802 bphillip Removed exception catching. Added merge method. * 8/1/2013 1693 bphillip Moved the merge method down to RegistryObjectDao * 10/8/2013 1682 bphillip Added like lid method, changed to use criteria queries for simple operations + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -70,6 +73,7 @@ public abstract class RegistryObjectTypeDao * @return The list of registry objects; */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByLid(List lids) { return createCriteria().add( Property.forName(QueryConstants.LID).in(lids)).list(); @@ -84,6 +88,7 @@ public abstract class RegistryObjectTypeDao * The list of lids to query for * @return The list of registry objects; */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByLid(String... lids) { return getByLid(Arrays.asList(lids)); } @@ -96,6 +101,7 @@ public abstract class RegistryObjectTypeDao * @return All IdentifiableType objects matching the given lid */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByLidUsingLike(String lid) { return createCriteria().add( Property.forName(QueryConstants.LID).like(lid)).list(); @@ -111,6 +117,7 @@ public abstract class RegistryObjectTypeDao * @return The list of registry objects; */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByObjectType(List objTypes) { return createCriteria().add( Property.forName(QueryConstants.OBJECT_TYPE).in(objTypes)) @@ -127,6 +134,7 @@ public abstract class RegistryObjectTypeDao * @return The list of registry objects; */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByStatus(List status) { return createCriteria().add( Property.forName(QueryConstants.STATUS).in(status)).list(); @@ -142,6 +150,7 @@ public abstract class RegistryObjectTypeDao * @return The list of registry objects; */ @SuppressWarnings("unchecked") + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByOwner(List owner) { return createCriteria().add( Property.forName(QueryConstants.OWNER).in(owner)).list(); @@ -156,6 +165,7 @@ public abstract class RegistryObjectTypeDao * The list of owners to query for * @return The list of registry objects; */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByOwner(String... owner) { return getByOwner(Arrays.asList(owner)); } @@ -169,6 +179,7 @@ public abstract class RegistryObjectTypeDao * The list of names to query for * @return The list of registry objects; */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByName(List names) { StringBuilder str = new StringBuilder( "select obj from RegistryObjectType obj inner join obj.name.localizedString as Strings where Strings.value in "); @@ -185,6 +196,7 @@ public abstract class RegistryObjectTypeDao * The list of descriptions to query for * @return The list of registry objects; */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByDescription(List descriptions) { StringBuilder str = new StringBuilder( "select obj from RegistryObjectType obj inner join obj.description.localizedString as Strings where Strings.value in "); @@ -201,6 +213,7 @@ public abstract class RegistryObjectTypeDao * The list of classificationNodes to query for * @return The list of registry objects; */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getByClassification(List classifications) { StringBuilder str = new StringBuilder( "select obj from RegistryObjectType obj inner join obj.classification as Classifications where "); @@ -236,6 +249,7 @@ public abstract class RegistryObjectTypeDao } @Override + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public ENTITY getById(String id) { return super.getById(id); } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RoleDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RoleDao.java index bb14f45c8c..7584f31932 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RoleDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RoleDao.java @@ -24,6 +24,9 @@ import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RoleType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.constants.AssociationTypes; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; @@ -39,6 +42,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 7/30/2012 724 bphillip Initial creation * 3/13/2013 1082 bphillip Modified to use spring injection and transaction boundaries * 4/9/2013 1802 bphillip Removed exception catching + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -65,6 +69,7 @@ public class RoleDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur during interaction with the database */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public RoleType getUserRole(String user) throws EbxmlRegistryException { List associations = associationDao.getBySourceAndType( user, AssociationTypes.HAS_ROLE); diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/SubscriptionDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/SubscriptionDao.java index 45353cfe37..8651fb25b5 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/SubscriptionDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/SubscriptionDao.java @@ -25,6 +25,9 @@ import javax.xml.bind.JAXBException; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.serialization.JAXBManager; import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; @@ -40,6 +43,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * ------------ ---------- ----------- -------------------------- * 3/13/2013 1082 bphillip Initial creation * 9/5/2013 1538 bphillip Added eagerLoadAll method + * 2/13/2014 2769 bphillip Added read only flags to query methods * * * @@ -72,6 +76,7 @@ public class SubscriptionDao extends RegistryObjectTypeDao { * @throws EbxmlRegistryException * If errors occur while querying */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List eagerLoadAll() throws EbxmlRegistryException { List subs = this.template .loadAll(SubscriptionType.class); @@ -103,6 +108,7 @@ public class SubscriptionDao extends RegistryObjectTypeDao { * If errors occur while eagerly fetching all attributes using * jaxb */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public SubscriptionType eagerGetById(String subscriptionId) throws EbxmlRegistryException { List result = this.query(EAGER_LOAD_QUERY, "id", diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java index 59d4bbef74..1c800d5ecd 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java @@ -20,21 +20,15 @@ package com.raytheon.uf.edex.registry.ebxml.services; import java.util.List; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AuditableEventType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionTemplate; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.edex.database.RunnableWithTransaction; import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; @@ -54,6 +48,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 7/29/2013 2191 bphillip Added executors to remove orphaned slots and expired events * 1/15/2014 2613 bphillip Added Hibernate flush() call * 2/4/2014 2769 bphillip Removed flush and clear call + * 2/13/2014 2769 bphillip Refactored to no longer use executor threads * * * @author bphillip @@ -70,23 +65,16 @@ public class RegistryGarbageCollector { /** Sentinel to denote if the garbage collection is currently running */ private AtomicBoolean running = new AtomicBoolean(false); - /** The executor service to remove expired events */ - private ThreadPoolExecutor expiredEventExecutor; - - /** The transaction template to use for asynchronous tasks */ - private TransactionTemplate txTemplate; - /** Data access object for AuditableEventType */ private AuditableEventTypeDao eventDao; - private static final int QUEUE_MAX_SIZE = 500; + /** The number of events to delete per batch */ + private static final int DELETE_BATCH_SIZE = 100; /** * Creates a new GarbageCollector object */ public RegistryGarbageCollector() { - expiredEventExecutor = new ThreadPoolExecutor(1, 3, 1L, - TimeUnit.MINUTES, new LinkedBlockingQueue(250)); } /** @@ -97,11 +85,9 @@ public class RegistryGarbageCollector { * @param eventDao * The auditable event dao to use */ - public RegistryGarbageCollector(AuditableEventTypeDao eventDao, - TransactionTemplate txTemplate) { + public RegistryGarbageCollector(AuditableEventTypeDao eventDao) { this(); this.eventDao = eventDao; - this.txTemplate = txTemplate; } @@ -129,41 +115,15 @@ public class RegistryGarbageCollector { * If errors occur while enqueuing events to be deleted */ private void purgeExpiredEvents() throws EbxmlRegistryException { - int limit = expiredEventExecutor.getQueue().remainingCapacity(); - if (limit > QUEUE_MAX_SIZE * .25) { - List expiredEvents = eventDao - .getExpiredEvents(limit); - for (AuditableEventType event : expiredEvents) { - try { - expiredEventExecutor.submit(new RemoveExpiredEvent( - txTemplate, event)); - } catch (RejectedExecutionException e) { - // Could not add more to the queue since it is full - } + + List expiredEvents = null; + do { + expiredEvents = eventDao.getExpiredEvents(DELETE_BATCH_SIZE); + if (!expiredEvents.isEmpty()) { + statusHandler.info("Deleting " + expiredEvents.size() + + " expired Auditable Events"); + eventDao.deleteAll(expiredEvents); } - } - } - - /** - * Task to remove expired auditable eventss - * - * @author bphillip - * - */ - private class RemoveExpiredEvent extends RunnableWithTransaction { - - /** The event to be removed */ - private AuditableEventType event; - - public RemoveExpiredEvent(TransactionTemplate txTemplate, - AuditableEventType event) { - super(txTemplate); - this.event = event; - } - - @Override - public void runWithTransaction() { - eventDao.delete(event); - } + } while (!expiredEvents.isEmpty()); } } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryServiceInInterceptor.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryServiceInInterceptor.java index 74c802fb11..277b8aeb68 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryServiceInInterceptor.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryServiceInInterceptor.java @@ -33,6 +33,7 @@ import org.apache.cxf.transport.http.AbstractHTTPDestination; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; 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.util.CollectionUtil; /** @@ -46,6 +47,7 @@ import com.raytheon.uf.common.util.CollectionUtil; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 9/5/2013 1538 bphillip Initial implementation + * 2/27/2014 2769 bphillip Changed verbose output to debug level * * * @author bphillip @@ -64,28 +66,31 @@ public class RegistryServiceInInterceptor extends @SuppressWarnings("unchecked") @Override public void handleMessage(Message message) throws Fault { - StringBuilder logMessage = new StringBuilder(); - HttpServletRequest request = (HttpServletRequest) message - .get(AbstractHTTPDestination.HTTP_REQUEST); - Map> headers = (Map>) message - .get(Message.PROTOCOL_HEADERS); - List callingRegistryList = headers - .get(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME); - if (request.getRequestURI().startsWith("/rest")) { - logMessage.append("REST: "); - } else { - logMessage.append("WS: "); + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { + StringBuilder logMessage = new StringBuilder(); + HttpServletRequest request = (HttpServletRequest) message + .get(AbstractHTTPDestination.HTTP_REQUEST); + Map> headers = (Map>) message + .get(Message.PROTOCOL_HEADERS); + List callingRegistryList = headers + .get(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME); + if (request.getRequestURI().startsWith("/rest")) { + logMessage.append("REST: "); + } else { + logMessage.append("WS: "); + } + logMessage.append("Request from ["); + if (CollectionUtil.isNullOrEmpty(callingRegistryList)) { + logMessage.append(request.getRemoteAddr()).append("]: ") + .append(request.getMethod()).append(" ") + .append(request.getRequestURI()); + } else { + logMessage.append(callingRegistryList.get(0)).append("]: ") + .append(request.getMethod()).append(" ") + .append(request.getRequestURI()); + } + + statusHandler.debug(logMessage.toString()); } - logMessage.append("Request from ["); - if (CollectionUtil.isNullOrEmpty(callingRegistryList)) { - logMessage.append(request.getRemoteAddr()).append("]: ") - .append(request.getMethod()).append(" ") - .append(request.getRequestURI()); - } else { - logMessage.append(callingRegistryList.get(0)).append("]: ") - .append(request.getMethod()).append(" ") - .append(request.getRequestURI()); - } - statusHandler.info(logMessage.toString()); } } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java index 823260a8a8..c5fe63d687 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java @@ -108,6 +108,7 @@ import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent; * Separate update from create notifications. * 12/2/2013 1829 bphillip Auditable events are not genereted via messages on the event bus * 01/21/2014 2613 bphillip Removed verbose log message from removeObjects + * 2/19/2014 2769 bphillip Added current time to audit trail events * * * @@ -302,7 +303,8 @@ public class LifecycleManagerImpl implements LifecycleManager { } EventBus.publish(new CreateAuditTrailEvent(request.getId(), request, - ActionTypes.delete, objectsToRemove)); + ActionTypes.delete, objectsToRemove, TimeUtil + .currentTimeMillis())); return response; } @@ -463,6 +465,7 @@ public class LifecycleManagerImpl implements LifecycleManager { // gives a close estimate to amount taken on each object // individually, this will be millis in most cases, hopefully long avTimePerRecord = objs.isEmpty() ? 0 : totalTime / objs.size(); + long currentTime = TimeUtil.currentTimeMillis(); if (!objsCreated.isEmpty()) { for (RegistryObjectType obj : objsCreated) { EventBus.publish(new InsertRegistryEvent(obj.getId(), obj @@ -472,7 +475,7 @@ public class LifecycleManagerImpl implements LifecycleManager { avTimePerRecord)); } EventBus.publish(new CreateAuditTrailEvent(request.getId(), - request, ActionTypes.create, objsCreated)); + request, ActionTypes.create, objsCreated, currentTime)); } if (!objsUpdated.isEmpty()) { for (RegistryObjectType obj : objsUpdated) { @@ -483,7 +486,7 @@ public class LifecycleManagerImpl implements LifecycleManager { avTimePerRecord)); } EventBus.publish(new CreateAuditTrailEvent(request.getId(), - request, ActionTypes.update, objsUpdated)); + request, ActionTypes.update, objsUpdated, currentTime)); } return response; @@ -738,7 +741,8 @@ public class LifecycleManagerImpl implements LifecycleManager { } if (!objectsToUpdate.isEmpty()) { EventBus.publish(new CreateAuditTrailEvent(request.getId(), - request, ActionTypes.update, objectsToUpdate)); + request, ActionTypes.update, objectsToUpdate, TimeUtil + .currentTimeMillis())); } long totalTime = System.currentTimeMillis() - startTime; diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java index 8c7cf1e95f..ea4c4dc2f7 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java @@ -20,6 +20,7 @@ package com.raytheon.uf.edex.registry.ebxml.services.notification; +import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -35,6 +36,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.dataplugin.persist.IPersistableDataObject; @@ -75,6 +77,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * AuditableEvents instead of integer * 12/9/2013 2613 bphillip Changed start time boundary of get auditable events to be the last run time of the subscription * 01/21/2014 2613 bphillip Changed start time boundary again and also a few minor cleanup items + * 2/13/2014 2769 bphillip Optimized sendNotifications method * * * @author bphillip @@ -117,13 +120,14 @@ public class RegistryNotificationManager { public List getObjectsOfInterest( SubscriptionType subscription) throws MsgRegistryException { // Get objects that match selector query - return queryManager - .executeQuery( - new QueryRequest("Objects of Interest Query for [" - + subscription.getId() + "]", subscription - .getSelector(), new ResponseOptionType( - QueryReturnTypes.OBJECT_REF, false))) - .getObjectRefList().getObjectRef(); + QueryRequest queryRequest = new QueryRequest( + "Objects of Interest Query for [" + subscription.getId() + "]", + subscription.getSelector(), new ResponseOptionType( + QueryReturnTypes.OBJECT_REF, false)); + queryRequest.setMaxResults(new BigInteger(System + .getProperty("ebxml-notification-batch-size"))); + return queryManager.executeQuery(queryRequest).getObjectRefList() + .getObjectRef(); } /** @@ -140,6 +144,7 @@ public class RegistryNotificationManager { * @throws MsgRegistryException * @throws EbxmlRegistryException */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public List getEventsOfInterest( SubscriptionType subscription, String serviceAddress, XMLGregorianCalendar startTime, XMLGregorianCalendar endTime, @@ -164,6 +169,7 @@ public class RegistryNotificationManager { * @throws EbxmlRegistryException * If errors occur while creating or checking the notification */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = true) public NotificationType getNotification(SubscriptionType subscription, String address, List objectsOfInterest, List eventsOfInterest) @@ -226,53 +232,35 @@ public class RegistryNotificationManager { * If errors occur while sending the notifications * @throws MsgRegistryException */ - protected XMLGregorianCalendar sendNotifications( + protected void sendNotifications( SubscriptionNotificationListeners notificationListeners, - XMLGregorianCalendar startTime) throws EbxmlRegistryException, - MsgRegistryException { + XMLGregorianCalendar startTime, XMLGregorianCalendar endTime) + throws EbxmlRegistryException, MsgRegistryException { - // Object to hold the last timestampe of the latest event in order to - // update the subscription last run time correctly - XMLGregorianCalendar lastTime = null; final List listeners = notificationListeners.listeners; final SubscriptionType subscription = notificationListeners.subscription; List objectsOfInterest = getObjectsOfInterest(subscription); for (NotificationListenerWrapper listener : listeners) { - List eventsOfInterest = getEventsOfInterest( - subscription, listener.address, startTime, - subscription.getEndTime(), objectsOfInterest); - if (!eventsOfInterest.isEmpty()) { - lastTime = eventsOfInterest.get(eventsOfInterest.size() - 1) - .getTimestamp(); - int subListCount = eventsOfInterest.size() - / notificationBatchSize; - int lastListSize = eventsOfInterest.size() - % notificationBatchSize; - try { - for (int i = 0; i < subListCount; i++) { - NotificationType notification = getNotification( - subscription, - listener.address, - objectsOfInterest, - eventsOfInterest.subList(notificationBatchSize - * i, notificationBatchSize * i - + notificationBatchSize)); - if (!notification.getEvent().isEmpty()) { - sendNotification(listener, notification, - listener.address); + List eventsOfInterest = getEventsOfInterest( + subscription, listener.address, startTime, endTime, + objectsOfInterest); + + if (!eventsOfInterest.isEmpty()) { + try { + int totalEvents = eventsOfInterest.size(); + int endIndex = 0; + for (int startIndex = 0; startIndex < totalEvents; startIndex += notificationBatchSize) { + endIndex = startIndex + notificationBatchSize; + if (endIndex >= totalEvents) { + endIndex = totalEvents; } - } - if (lastListSize > 0) { NotificationType notification = getNotification( - subscription, - listener.address, + subscription, listener.address, objectsOfInterest, - eventsOfInterest.subList(notificationBatchSize - * subListCount, notificationBatchSize - * subListCount + lastListSize)); + eventsOfInterest.subList(startIndex, endIndex)); if (!notification.getEvent().isEmpty()) { sendNotification(listener, notification, listener.address); @@ -284,7 +272,6 @@ public class RegistryNotificationManager { } } - return lastTime; } /** diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java index 19e5f059dd..aa1fdb1080 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java @@ -20,10 +20,7 @@ package com.raytheon.uf.edex.registry.ebxml.services.notification; import java.util.Calendar; -import java.util.Collection; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import javax.xml.datatype.Duration; @@ -43,17 +40,12 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.google.common.collect.Lists; -import com.google.common.eventbus.Subscribe; -import com.raytheon.uf.common.registry.constants.RegistryObjectTypes; -import com.raytheon.uf.common.registry.event.InsertRegistryEvent; -import com.raytheon.uf.common.registry.event.RemoveRegistryEvent; 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.edex.registry.ebxml.dao.DbInit; import com.raytheon.uf.edex.registry.ebxml.dao.SubscriptionDao; 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.IRegistrySubscriptionManager; import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; @@ -83,16 +75,15 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * 1/15/2014 2613 bphillip Added Hibernate flush and clear after subscription processing * 01/21/2014 2613 bphillip Changed how last run time is updated for replication subscriptions * 2/4/2014 2769 bphillip Removed flush and clear call + * 2/13/2014 2769 bphillip Removed caching of subscriptions * * * @author bphillip * @version 1 */ -@Transactional @Component public class RegistrySubscriptionManager implements - IRegistrySubscriptionManager, ApplicationContextAware, - RegistryInitializedListener { + IRegistrySubscriptionManager, ApplicationContextAware { /** The logger instance */ private static final IUFStatusHandler statusHandler = UFStatus @@ -153,63 +144,12 @@ public class RegistrySubscriptionManager implements private INotificationListenerFactory notificationListenerFactory; - private final ConcurrentMap listeners = new ConcurrentHashMap(); - private ApplicationContext applicationContext; public RegistrySubscriptionManager() { } - @Override - public void executeAfterRegistryInit() throws EbxmlRegistryException { - for (SubscriptionType subscription : subscriptionDao.eagerLoadAll()) { - statusHandler.info("Adding Subscription: " + subscription.getId()); - addSubscriptionListener(subscription); - } - } - - private void addSubscriptionListener(SubscriptionType subscription) - throws EbxmlRegistryException { - final List subscriptionListeners = getNotificationListenersForSubscription(subscription); - listeners.put(subscription.getId(), - new SubscriptionNotificationListeners(subscription, - subscriptionListeners)); - } - - /** - * Adds subscription notification listeners for any subscriptions. - */ - @Subscribe - public void addSubscriptionNotificationListeners(InsertRegistryEvent re) { - final String objectType = re.getObjectType(); - - if (RegistryObjectTypes.SUBSCRIPTION.equals(objectType)) { - final String id = re.getId(); - try { - final SubscriptionType subscription = subscriptionDao - .eagerGetById(id); - addSubscriptionListener(subscription); - - } catch (EbxmlRegistryException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - } - } - - /** - * Removes subscription notification listeners for any subscriptions. - */ - @Subscribe - public void removeSubscriptionNotificationListeners(RemoveRegistryEvent re) { - final String objectType = re.getObjectType(); - - if (RegistryObjectTypes.SUBSCRIPTION.equals(objectType)) { - listeners.remove(re.getId()); - } - } - /** * Get the notification listeners for a subscription. * @@ -249,29 +189,22 @@ public class RegistrySubscriptionManager implements * {@inheritDoc} */ @Override + @Transactional public void processSubscriptions() { - if (!running.compareAndSet(false, true)) { + + if (DbInit.isDbInitialized() && !running.compareAndSet(false, true)) { return; } try { + statusHandler.info("Processing registry subscriptions..."); long start = TimeUtil.currentTimeMillis(); - Collection subs = listeners - .values(); + List subs = subscriptionDao.loadAll(); - for (SubscriptionNotificationListeners subNotificationListener : subs) { - if (subscriptionDao - .getById(subNotificationListener.subscription.getId()) == null) { - statusHandler - .info("Registry subscription removed. Cancelling processing of subscription: " - + subNotificationListener.subscription - .getId()); - continue; - } + for (SubscriptionType subscription : subs) { RegistrySubscriptionManager myself = (RegistrySubscriptionManager) applicationContext .getBean("RegistrySubscriptionManager"); - myself.processSubscription(subNotificationListener.subscription - .getId()); + myself.processSubscription(subscription.getId()); } if (!subs.isEmpty()) { @@ -373,14 +306,10 @@ public class RegistrySubscriptionManager implements @Transactional(propagation = Propagation.REQUIRES_NEW) public void processSubscription(final String subscriptionName) { try { + XMLGregorianCalendar currentTime = EbxmlObjectUtil + .getTimeAsXMLGregorianCalendar(TimeUtil.currentTimeMillis()); SubscriptionType subscription = subscriptionDao - .getById(subscriptionName); - if (subscription == null) { - statusHandler - .info("Registry subscription removed. Cancelling processing of subscription: " - + subscriptionName); - return; - } + .load(subscriptionName); if (!subscriptionShouldRun(subscription)) { statusHandler .info("Skipping subscription [" @@ -388,21 +317,28 @@ public class RegistrySubscriptionManager implements + "]. Required notification frequency interval has not elapsed."); return; } - statusHandler.info("Processing subscription [" + subscriptionName - + "]..."); + XMLGregorianCalendar startTime = subscription .getSlotValue(EbxmlObjectUtil.SUBSCRIPTION_LAST_RUN_TIME_SLOT_NAME); + XMLGregorianCalendar endTime = subscription.getEndTime(); if (startTime == null) { startTime = subscription.getStartTime(); } - XMLGregorianCalendar lastEventTime = notificationManager - .sendNotifications(listeners.get(subscriptionName), - startTime); - if (lastEventTime != null) { - updateLastRunTime(subscription, lastEventTime - .toGregorianCalendar().getTimeInMillis()); + + if (endTime == null) { + endTime = currentTime; } + + notificationManager + .sendNotifications( + new SubscriptionNotificationListeners( + subscription, + getNotificationListenersForSubscription(subscription)), + startTime, endTime); + updateLastRunTime(subscription, currentTime.toGregorianCalendar() + .getTimeInMillis()); + } catch (Throwable e) { statusHandler.error( "Errors occurred while processing subscription [" diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImpl.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImpl.java index 4af077512e..9ad36ab434 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImpl.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImpl.java @@ -123,13 +123,13 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * 10/2013 1682 bphillip Fixed federated query invocation * 10/23/2013 1538 bphillip Remove extra executeQuery method * 10/30/2013 1538 bphillip Changed to use non-static soap service client + * 2/19/2014 2769 bphillip Moved Transactional Annotation, fixed plugin cache usage * * * * @author bphillip * @version 1.0 */ -@Transactional(propagation = Propagation.MANDATORY) public class QueryManagerImpl implements QueryManager, ApplicationContextAware { /** The logger */ @@ -223,6 +223,7 @@ public class QueryManagerImpl implements QueryManager, ApplicationContextAware { * The QueryResponse contains a set of objects that match the query. */ @Override + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery(QueryRequest queryRequest) throws MsgRegistryException { String client = EbxmlObjectUtil.getClientHost(wsContext); @@ -518,7 +519,7 @@ public class QueryManagerImpl implements QueryManager, ApplicationContextAware { String queryDefinition = query.getQueryDefinition(); RegistryQueryPlugin plugin = queryPlugins.get(queryDefinition); if (plugin == null) { - QueryDefinitionType queryDef = queryDefinitionDao.getById(query + QueryDefinitionType queryDef = queryDefinitionDao.loadById(query .getQueryDefinition()); if (queryDef == null) { throw EbxmlExceptionUtil.createQueryExceptionType( @@ -551,7 +552,6 @@ public class QueryManagerImpl implements QueryManager, ApplicationContextAware { .executeHQLQuery(queryString, queryParameters); queryResponse.addRegistryObjects(results); } else { - queryPlugins.put(queryDefinition, plugin); checkQueryParameters(queryRequest.getQuery()); QueryResponse response = plugin.executeQuery(queryRequest); consolidateQueryResponse(queryResponse, response); diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImplWrapper.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImplWrapper.java index e37d95c8ec..c7102fdb6a 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImplWrapper.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/QueryManagerImplWrapper.java @@ -28,6 +28,7 @@ import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.QueryManager; import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest; import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.registry.EbxmlNamespaces; @@ -43,12 +44,13 @@ import com.raytheon.uf.common.registry.EbxmlNamespaces; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 7/11/2013 1707 bphillip Initial implementation + * 2/19/2014 2769 bphillip Added readOnly flag to Transactional annotation * * * @author bphillip * @version 1 */ -@Transactional +@Transactional(propagation = Propagation.REQUIRED, readOnly = true) public class QueryManagerImplWrapper implements QueryManager { private QueryManagerImpl queryManager; diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/AdhocQuery.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/AdhocQuery.java index d7964af8f6..b2fbc6fa69 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/AdhocQuery.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/AdhocQuery.java @@ -30,6 +30,9 @@ 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.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -78,6 +81,7 @@ public class AdhocQuery extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/BasicQuery.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/BasicQuery.java index 5da0dcffa8..1282ffd4b1 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/BasicQuery.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/BasicQuery.java @@ -34,6 +34,9 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; @@ -114,6 +117,7 @@ public class BasicQuery extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/ClassificationSchemeSelector.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/ClassificationSchemeSelector.java index 916a69d382..bf9b284009 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/ClassificationSchemeSelector.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/ClassificationSchemeSelector.java @@ -36,6 +36,9 @@ 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.TaxonomyElementType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectTypeDao; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -85,6 +88,7 @@ public class ClassificationSchemeSelector extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociatedObjects.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociatedObjects.java index c89842b9e8..66125f9cb0 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociatedObjects.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociatedObjects.java @@ -33,6 +33,9 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; @@ -108,6 +111,7 @@ public class FindAssociatedObjects extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociations.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociations.java index 5c451380e7..8cce95e1aa 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociations.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/FindAssociations.java @@ -32,6 +32,9 @@ import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.dao.AssociationDao; @@ -99,6 +102,7 @@ public class FindAssociations extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GarbageCollectorQueryPlugin.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GarbageCollectorQueryPlugin.java index 1a7beb0919..15988d2bc8 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GarbageCollectorQueryPlugin.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GarbageCollectorQueryPlugin.java @@ -32,6 +32,9 @@ import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; @@ -73,6 +76,7 @@ public class GarbageCollectorQueryPlugin extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailById.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailById.java index 841e1a24f7..0d53b117bb 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailById.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailById.java @@ -32,6 +32,9 @@ 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.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -93,6 +96,7 @@ public class GetAuditTrailById extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByLid.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByLid.java index c8d6403d7b..8a1c1fdc35 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByLid.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByLid.java @@ -39,6 +39,9 @@ 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 org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; @@ -73,7 +76,6 @@ import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; * @author bphillip * @version 1.0 */ - public class GetAuditTrailByLid extends RegistryQueryPlugin { /** Data access object for accessing registry objects */ @@ -85,6 +87,7 @@ public class GetAuditTrailByLid extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByTimeInterval.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByTimeInterval.java index a53c0d2d14..29a4a03e7b 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByTimeInterval.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetAuditTrailByTimeInterval.java @@ -31,6 +31,9 @@ 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.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -98,6 +101,7 @@ public class GetAuditTrailByTimeInterval extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetChildrenByParentId.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetChildrenByParentId.java index 45abfe3d48..819d39c517 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetChildrenByParentId.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetChildrenByParentId.java @@ -36,6 +36,9 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryPackageType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.TaxonomyElementType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes; import com.raytheon.uf.common.util.CollectionUtil; @@ -158,6 +161,7 @@ public class GetChildrenByParentId extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetClassificationSchemesById.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetClassificationSchemesById.java index 21316b2137..d1ef08a483 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetClassificationSchemesById.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetClassificationSchemesById.java @@ -30,6 +30,9 @@ 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.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -69,6 +72,7 @@ public class GetClassificationSchemesById extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetNotification.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetNotification.java index 743004d5e5..5cdbabe324 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetNotification.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetNotification.java @@ -36,6 +36,9 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes; import com.raytheon.uf.edex.registry.ebxml.dao.SubscriptionDao; @@ -85,6 +88,7 @@ public class GetNotification extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectById.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectById.java index 0498a106cc..08e93106d1 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectById.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectById.java @@ -19,7 +19,9 @@ **/ package com.raytheon.uf.edex.registry.ebxml.services.query.plugins; +import javax.jws.WebMethod; import javax.jws.WebParam; +import javax.jws.WebResult; import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException; import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest; @@ -56,12 +58,14 @@ import com.raytheon.uf.edex.registry.ebxml.services.query.RegistryQueryUtil; * @author bphillip * @version 1.0 */ -@Transactional(propagation = Propagation.REQUIRED) public class GetObjectById extends RegistryQueryPlugin { private RegistryObjectDao registryObjectDao; @Override + @WebMethod(action = EXECUTE_QUERY_ACTION) + @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectsByLid.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectsByLid.java index 66953edb30..cb047c9a3b 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectsByLid.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetObjectsByLid.java @@ -30,6 +30,9 @@ 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.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; @@ -64,6 +67,7 @@ public class GetObjectsByLid extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetReferencedObject.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetReferencedObject.java index 60ba241641..55169d35c4 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetReferencedObject.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetReferencedObject.java @@ -36,6 +36,9 @@ 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 org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes; import com.raytheon.uf.common.registry.constants.QueryReturnTypes; @@ -74,6 +77,7 @@ public class GetReferencedObject extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetRegistryPackagesByMemberId.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetRegistryPackagesByMemberId.java index 42661fbde6..81ac460bc6 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetRegistryPackagesByMemberId.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/GetRegistryPackagesByMemberId.java @@ -30,6 +30,9 @@ 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.rim.v4.QueryType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -76,6 +79,7 @@ public class GetRegistryPackagesByMemberId extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/KeywordSearch.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/KeywordSearch.java index fe51df243d..dfd0d596e7 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/KeywordSearch.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/KeywordSearch.java @@ -37,6 +37,9 @@ import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.QueryType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -204,6 +207,7 @@ public class KeywordSearch extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryPackageSelector.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryPackageSelector.java index 5cfa4ede50..b2d8f54962 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryPackageSelector.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryPackageSelector.java @@ -34,6 +34,9 @@ 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.RegistryPackageType; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.raytheon.uf.common.registry.EbxmlNamespaces; import com.raytheon.uf.common.registry.constants.AssociationTypes; import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes; @@ -78,6 +81,7 @@ public class RegistryPackageSelector extends RegistryQueryPlugin { @Override @WebMethod(action = EXECUTE_QUERY_ACTION) @WebResult(name = "QueryResponse", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryResponse") + @Transactional(propagation = Propagation.MANDATORY, readOnly = true) public QueryResponse executeQuery( @WebParam(name = "QueryRequest", targetNamespace = EbxmlNamespaces.QUERY_URI, partName = "partQueryRequest") QueryRequest queryRequest) throws MsgRegistryException { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryQueryPlugin.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryQueryPlugin.java index 071e688275..4a8546f9eb 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryQueryPlugin.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/query/plugins/RegistryQueryPlugin.java @@ -9,13 +9,9 @@ import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationNodeType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.dao.ClassificationNodeDao; -@Transactional(propagation = Propagation.REQUIRED) public abstract class RegistryQueryPlugin implements QueryManager { protected String queryDefinition; diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/EbxmlObjectUtil.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/EbxmlObjectUtil.java index 76de03ecae..81d0a3c0b2 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/EbxmlObjectUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/EbxmlObjectUtil.java @@ -93,6 +93,8 @@ public class EbxmlObjectUtil { */ public static final String HOME_SLOT_NAME = "urn:oasis:names:tc:ebxml-regrep:rim:RegistryObject:home"; + public static final String EVENT_SOURCE_SLOT = "EventSource"; + /** The name of the slot designated to hold the email notification formatter */ public static final String EMAIL_NOTIFICATION_FORMATTER_SLOT = "urn:oasis:names:tc:ebxml-regrep:rim:DeliveryInfo:emailNotificationFormatter"; diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/CreateAuditTrailEvent.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/CreateAuditTrailEvent.java index 990f5964d6..ecd2af48d9 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/CreateAuditTrailEvent.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/CreateAuditTrailEvent.java @@ -49,12 +49,16 @@ public class CreateAuditTrailEvent extends Event { private List objectsAffected; + private long eventTime; + public CreateAuditTrailEvent(String id, RegistryRequestType request, - String actionType, List objectsAffected) { + String actionType, List objectsAffected, + long eventTime) { super(id); this.request = request; this.actionType = actionType; this.objectsAffected = objectsAffected; + this.eventTime = eventTime; } public RegistryRequestType getRequest() { @@ -69,4 +73,8 @@ public class CreateAuditTrailEvent extends Event { return objectsAffected; } + public long getEventTime() { + return eventTime; + } + } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/federation/status.html b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/federation/status.html index 6d9b7540bc..1408e221c7 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/federation/status.html +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/federation/status.html @@ -62,61 +62,55 @@ Date Ticket# Engineer Description - - + + + + + + + + + + + + + +
My Registry ID:[Unknown]Data Delivery ID:[Unknown]
Site ID:[Unknown]
Federated: [Unknown]
Replicating To:Retrieving Registry List...
Replicating From:Retrieving Registry List...


- - - - - - + - + - +
Resubmit Subscriptions To:
Synchronize with Registry:Synchronize With:
Subscribe To Registry:Subscribe To:
Unsubscribe From Registry:Unsubscribe From:

-My Registry is Subscribed To: -Retrieving Registry List... - -
-
- - - -Registries Subscribing to My Registry: -Retrieving Registry List... -
-
- Federation Members:

-Object Types Currently Replicated: +Object Types Replicated: Retrieving Object List...

@@ -127,38 +121,45 @@ Date Ticket# Engineer Description function subscribe(){ var registryId = getComboValue("subscribeToRegistrySelect") - callRestService("dataDelivery/status/subscribeToRegistry",registryId); + callRestService("dataDelivery/federation/subscribeToRegistry",registryId); location.reload(false) } function resubmitSubs(){ var registryId = getComboValue("resubmitSubsToRegistrySelect") - callRestService("dataDelivery/status/subscribeToRegistry",registryId); + callRestService("dataDelivery/federation/subscribeToRegistry",registryId); } function unsubscribe(){ var registryId = getComboValue("unsubscribeFromRegistrySelect") - callRestService("dataDelivery/status/unsubscribeFromRegistry",registryId); - location.reload(false) + callRestService("dataDelivery/federation/unsubscribeFromRegistry",registryId); + location.reload(false) } function sync(){ var registryId = getComboValue("syncWithRegistrySelect") - callRestService("dataDelivery/status/syncWithRegistry",registryId); + callRestService("dataDelivery/federation/synchronizeWithRegistry",registryId); } function populate(){ - var isFederated = callRestService("dataDelivery/status/isFederated") + var isFederated = callRestService("dataDelivery/federation/isFederated") + var dataDeliveryId=callRestService("dataDelivery/federation/dataDeliveryId"); + var siteId=callRestService("dataDelivery/federation/siteId"); + var objectTypes = callRestService("dataDelivery/federation/getObjectTypesReplicated").split(",") + var federationMembers = new Array() + document.getElementById("federatedSpan").innerHTML=isFederated + document.getElementById("dataDeliveryIdSpan").innerHTML=dataDeliveryId + document.getElementById("registrySiteIdSpan").innerHTML=siteId + if(isFederated == "true"){ - var myRegistryId=callRestService("dataDelivery/status/getMyRegistryInfo").split("\n")[0].split(",")[0] - document.getElementById("myRegistryIdSpan").innerHTML=myRegistryId - var subscriptionCandidates = new Array(); + var replicatingToString = callRestService("dataDelivery/federation/getReplicatingTo") + var replicatingTo = replicatingToString.split(",") + var replicatingFromString = callRestService("dataDelivery/federation/getReplicatingFrom") + var replicatingFrom = replicatingFromString.split(",") + + var registries = callRestService("dataDelivery/federation/getFederationMembers").split("\n") var memberHTML = "" - var registries = callRestService("dataDelivery/status/getFederationMembers").split("\n") - var federationMembers = new Array() - var subscribedTo=new Array() - var subscribedFrom=new Array() for(var i = 0; i < registries.length-1;i++){ var tokens = registries[i].split(",") memberHTML+="" @@ -170,39 +171,7 @@ Date Ticket# Engineer Description federationMembers[i]=tokens[0] } memberHTML+="
SiteBase URLConformance ProfileSpecification Version
" - document.getElementById("federationMembersSpan").innerHTML=memberHTML - - memberHTML = "" - registries = callRestService("dataDelivery/status/getRegistriesSubscribedTo").split("\n") - for(var i = 0; i < registries.length-1;i++){ - var tokens = registries[i].split(",") - memberHTML+="" - memberHTML+="" - memberHTML+="" - memberHTML+="" - memberHTML+="" - memberHTML+="" - subscribedTo[i] = tokens[0] - } - memberHTML+="
SiteBase URLConformance ProfileSpecification Version
"+tokens[0]+""+tokens[1]+""+tokens[2]+""+tokens[3]+"
" - document.getElementById("subscribedToRegistriesSpan").innerHTML=memberHTML - - memberHTML = "" - registries = callRestService("dataDelivery/status/getRegistrySubscribing").split("\n") - for(var i = 0; i < registries.length-1;i++){ - var tokens = registries[i].split(",") - memberHTML+="" - memberHTML+="" - memberHTML+="" - memberHTML+="" - memberHTML+="" - memberHTML+="" - subscribedFrom[i]=tokens[0] - } - memberHTML+="
SiteBase URLConformance ProfileSpecification Version
"+tokens[0]+""+tokens[1]+""+tokens[2]+""+tokens[3]+"
" - document.getElementById("subscribedToRegistries").innerHTML=memberHTML - - var objectTypes = callRestService("dataDelivery/status/getObjectTypesReplicated").split("\n") + var objectTypeHTML = "" for(var i = 0; i < objectTypes.length-1;i++){ objectTypeHTML+="" @@ -210,27 +179,28 @@ Date Ticket# Engineer Description objectTypeHTML+="" objectTypeHTML+="" } - + objectTypeHTML+="
Object Type
"+objectTypes[i]+"
"; + for(var i = 0; i < federationMembers.length;i++){ var member=federationMembers[i] - if(subscribedTo.indexOf(member)== -1 && member!=myRegistryId){ + if(replicatingFrom.indexOf(member)== -1 && member!=dataDeliveryId){ addOptionToList("subscribeToRegistrySelect",member,member) } - if(member!=myRegistryId){ + if(member!=dataDeliveryId){ addOptionToList("syncWithRegistrySelect",member,member) } - if(subscribedTo.indexOf(member) != -1){ + if(replicatingFrom.indexOf(member) != -1){ addOptionToList("unsubscribeFromRegistrySelect",member,member) - addOptionToList("resubmitSubsToRegistrySelect",member,member) } } - objectTypeHTML+=""; + document.getElementById("replicatedObjectListSpan").innerHTML=objectTypeHTML - + document.getElementById("replicatingToSpan").innerHTML=replicatingToString + document.getElementById("replicatingFromSpan").innerHTML=replicatingFromString + document.getElementById("federationMembersSpan").innerHTML=memberHTML } } - \ No newline at end of file