Merge "Issue #2191 Registry federation synchronization and garbage collection" into development
Former-commit-id: 4e3f429e5aebec59e5c15c8bea062cc62e599cc6
This commit is contained in:
commit
e692cc245b
29 changed files with 1289 additions and 180 deletions
|
@ -13,7 +13,8 @@ Export-Package: com.raytheon.uf.common.registry,
|
||||||
com.raytheon.uf.common.registry.ebxml.slots,
|
com.raytheon.uf.common.registry.ebxml.slots,
|
||||||
com.raytheon.uf.common.registry.handler,
|
com.raytheon.uf.common.registry.handler,
|
||||||
com.raytheon.uf.common.registry.services,
|
com.raytheon.uf.common.registry.services,
|
||||||
com.raytheon.uf.common.registry.services.rest
|
com.raytheon.uf.common.registry.services.rest,
|
||||||
|
com.raytheon.uf.common.registry.services.rest.response
|
||||||
Require-Bundle: org.apache.commons.codec;bundle-version="1.4.0",
|
Require-Bundle: org.apache.commons.codec;bundle-version="1.4.0",
|
||||||
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
|
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.common.util;bundle-version="1.12.1174",
|
com.raytheon.uf.common.util;bundle-version="1.12.1174",
|
||||||
|
|
|
@ -33,6 +33,7 @@ import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.raytheon.uf.common.registry.constants.RegistryAvailability;
|
import com.raytheon.uf.common.registry.constants.RegistryAvailability;
|
||||||
import com.raytheon.uf.common.registry.services.rest.IRegistryAvailableRestService;
|
import com.raytheon.uf.common.registry.services.rest.IRegistryAvailableRestService;
|
||||||
|
import com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService;
|
||||||
import com.raytheon.uf.common.registry.services.rest.IRegistryObjectsRestService;
|
import com.raytheon.uf.common.registry.services.rest.IRegistryObjectsRestService;
|
||||||
import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService;
|
import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService;
|
||||||
import com.raytheon.uf.common.serialization.SerializationUtil;
|
import com.raytheon.uf.common.serialization.SerializationUtil;
|
||||||
|
@ -50,6 +51,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 5/21/2013 2022 bphillip Initial implementation
|
* 5/21/2013 2022 bphillip Initial implementation
|
||||||
|
* 7/29/2013 2191 bphillip Implemented registry data access service
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -87,6 +89,16 @@ public class RegistryRESTServices {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** Map of known registry data access services */
|
||||||
|
private static LoadingCache<String, IRegistryDataAccessService> registryDataAccessServiceMap = CacheBuilder
|
||||||
|
.newBuilder().expireAfterAccess(1, TimeUnit.HOURS)
|
||||||
|
.build(new CacheLoader<String, IRegistryDataAccessService>() {
|
||||||
|
public IRegistryDataAccessService load(String key) {
|
||||||
|
return JAXRSClientFactory.create(key,
|
||||||
|
IRegistryDataAccessService.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger
|
* The logger
|
||||||
*/
|
*/
|
||||||
|
@ -99,11 +111,9 @@ public class RegistryRESTServices {
|
||||||
* @param baseURL
|
* @param baseURL
|
||||||
* The base URL of the registry
|
* The base URL of the registry
|
||||||
* @return The service implementation
|
* @return The service implementation
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If an invalid URL is provided
|
|
||||||
*/
|
*/
|
||||||
public static IRegistryObjectsRestService getRegistryObjectService(
|
public static IRegistryObjectsRestService getRegistryObjectService(
|
||||||
String baseURL) throws RegistryServiceException {
|
String baseURL) {
|
||||||
try {
|
try {
|
||||||
return registryObjectServiceMap.get(baseURL);
|
return registryObjectServiceMap.get(baseURL);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -124,8 +134,6 @@ public class RegistryRESTServices {
|
||||||
* @return The object
|
* @return The object
|
||||||
* @throws JAXBException
|
* @throws JAXBException
|
||||||
* If errors occur while serializing the object
|
* If errors occur while serializing the object
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If an invalid URL is provided
|
|
||||||
*/
|
*/
|
||||||
public static <T extends RegistryObjectType> T getRegistryObject(
|
public static <T extends RegistryObjectType> T getRegistryObject(
|
||||||
Class<T> expectedType, String baseURL, String objectId)
|
Class<T> expectedType, String baseURL, String objectId)
|
||||||
|
@ -140,11 +148,9 @@ public class RegistryRESTServices {
|
||||||
* @param baseURL
|
* @param baseURL
|
||||||
* The base URL of the registry
|
* The base URL of the registry
|
||||||
* @return The service implementation
|
* @return The service implementation
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If an invalid URL is provided
|
|
||||||
*/
|
*/
|
||||||
public static IRepositoryItemsRestService getRepositoryItemService(
|
public static IRepositoryItemsRestService getRepositoryItemService(
|
||||||
String baseURL) throws RegistryServiceException {
|
String baseURL) {
|
||||||
try {
|
try {
|
||||||
return repositoryItemServiceMap.get(baseURL);
|
return repositoryItemServiceMap.get(baseURL);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -161,11 +167,9 @@ public class RegistryRESTServices {
|
||||||
* @param repositoryItemId
|
* @param repositoryItemId
|
||||||
* The id of the object
|
* The id of the object
|
||||||
* @return The repository item
|
* @return The repository item
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If an invalid URL is provided
|
|
||||||
*/
|
*/
|
||||||
public static byte[] getRepositoryItem(String baseURL,
|
public static byte[] getRepositoryItem(String baseURL,
|
||||||
String repositoryItemId) throws RegistryServiceException {
|
String repositoryItemId) {
|
||||||
return getRepositoryItemService(baseURL).getRepositoryItem(
|
return getRepositoryItemService(baseURL).getRepositoryItem(
|
||||||
repositoryItemId);
|
repositoryItemId);
|
||||||
}
|
}
|
||||||
|
@ -176,11 +180,9 @@ public class RegistryRESTServices {
|
||||||
* @param baseURL
|
* @param baseURL
|
||||||
* The base URL of the registry
|
* The base URL of the registry
|
||||||
* @return THe registry available service implementation
|
* @return THe registry available service implementation
|
||||||
* @throws RegistryServiceException
|
|
||||||
* If an invalid URL is provided
|
|
||||||
*/
|
*/
|
||||||
public static IRegistryAvailableRestService getRegistryAvailableService(
|
public static IRegistryAvailableRestService getRegistryAvailableService(
|
||||||
String baseURL) throws RegistryServiceException {
|
String baseURL) {
|
||||||
try {
|
try {
|
||||||
return registryAvailabilityServiceMap.get(baseURL);
|
return registryAvailabilityServiceMap.get(baseURL);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -204,8 +206,25 @@ public class RegistryRESTServices {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
statusHandler.error(
|
statusHandler.error(
|
||||||
"Registry at [" + baseURL + "] not available: ",
|
"Registry at [" + baseURL + "] not available: ",
|
||||||
t.getLocalizedMessage());
|
t.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the data access service for the specified registry URL
|
||||||
|
*
|
||||||
|
* @param baseURL
|
||||||
|
* The baseURL of the registry
|
||||||
|
* @return The data access service for the specified registry URL
|
||||||
|
*/
|
||||||
|
public static IRegistryDataAccessService getRegistryDataAccessService(
|
||||||
|
String baseURL) {
|
||||||
|
try {
|
||||||
|
return registryDataAccessServiceMap.get(baseURL);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new RegistryServiceException(
|
||||||
|
"Error getting Registry Availability Rest Service", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* 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.registry.services.rest;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.registry.RegistryException;
|
||||||
|
import com.raytheon.uf.common.registry.services.rest.response.RestCollectionResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* REST service interface for various registry data access methods
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
public interface IRegistryDataAccessService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ids of registry objects of the given object type
|
||||||
|
*
|
||||||
|
* @param objectType
|
||||||
|
* The object type to get ids for
|
||||||
|
* @return List of ids for registry objects of the given type
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/rest/dataAccess/getRegistryObjectIds/{objectType}")
|
||||||
|
public RestCollectionResponse<String> getRegistryObjectIdsOfType(
|
||||||
|
@PathParam("objectType") String objectType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes any subscriptions for the given site
|
||||||
|
*
|
||||||
|
* @param siteId
|
||||||
|
* The site to remove the subscriptions for
|
||||||
|
* @throws RegistryException
|
||||||
|
* If errors occur while removing the subscriptions
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/rest/dataAccess/removeSubscriptionsFor/{siteId}")
|
||||||
|
public void removeSubscriptionsForSite(@PathParam("siteId") String siteId)
|
||||||
|
throws RegistryException;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* 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.registry.services.rest.response;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A response from a registry REST service call
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
@XmlRootElement
|
||||||
|
public interface IRestResponse<OBJECT_TYPE extends Object> extends
|
||||||
|
ISerializableObject {
|
||||||
|
|
||||||
|
public OBJECT_TYPE getPayload();
|
||||||
|
|
||||||
|
public void setPayload(OBJECT_TYPE payload);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* 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.registry.services.rest.response;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElements;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Response object for returning a collection from a REST service
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
@XmlRootElement
|
||||||
|
public class RestCollectionResponse<COLLECTION_TYPE extends Object> implements
|
||||||
|
IRestResponse<Collection<COLLECTION_TYPE>> {
|
||||||
|
|
||||||
|
@XmlElements({ @XmlElement(name = "item") })
|
||||||
|
private Collection<COLLECTION_TYPE> set;
|
||||||
|
|
||||||
|
public RestCollectionResponse() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@XmlTransient
|
||||||
|
public Collection<COLLECTION_TYPE> getPayload() {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPayload(Collection<COLLECTION_TYPE> payload) {
|
||||||
|
this.set = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -46,6 +46,7 @@ import org.hibernate.usertype.UserType;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 21, 2012 #184 bphillip Initial creation
|
* Feb 21, 2012 #184 bphillip Initial creation
|
||||||
* 4/9/2013 1802 bphillip Added null check
|
* 4/9/2013 1802 bphillip Added null check
|
||||||
|
* 7/29/2013 2191 bphillip Fixed equals method
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -77,7 +78,11 @@ public class XMLGregorianCalendarType implements UserType {
|
||||||
public boolean equals(Object x, Object y) throws HibernateException {
|
public boolean equals(Object x, Object y) throws HibernateException {
|
||||||
if (x instanceof XMLGregorianCalendar
|
if (x instanceof XMLGregorianCalendar
|
||||||
&& y instanceof XMLGregorianCalendar) {
|
&& y instanceof XMLGregorianCalendar) {
|
||||||
return x.equals(y);
|
try {
|
||||||
|
return x.equals(y);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return y.equals(x);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* 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.database;
|
||||||
|
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Implementation of a runnable who's run method is encapsulated in a Hibernate
|
||||||
|
* transaction. This class is used for executing asynchronous actions that
|
||||||
|
* require a Hibernate transaction.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
public abstract class RunnableWithTransaction implements Runnable {
|
||||||
|
|
||||||
|
/** The Hibernate transaction template used to get a transaction */
|
||||||
|
private TransactionTemplate txTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new RunnableWithTransaction object
|
||||||
|
*/
|
||||||
|
public RunnableWithTransaction() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new RunnableWithTransaction object
|
||||||
|
*
|
||||||
|
* @param txTemplate
|
||||||
|
* The transaction template to use
|
||||||
|
*/
|
||||||
|
public RunnableWithTransaction(TransactionTemplate txTemplate) {
|
||||||
|
this.txTemplate = txTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||||
|
runWithTransaction();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is executed transactionally
|
||||||
|
*/
|
||||||
|
public abstract void runWithTransaction();
|
||||||
|
|
||||||
|
public void setTxTemplate(TransactionTemplate txTemplate) {
|
||||||
|
this.txTemplate = txTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,4 +16,5 @@ Require-Bundle: com.raytheon.uf.common.registry.schemas.ebxml;bundle-version="1.
|
||||||
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
|
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
|
||||||
org.springframework;bundle-version="2.5.6",
|
org.springframework;bundle-version="2.5.6",
|
||||||
com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.edex.core;bundle-version="1.12.1174"
|
com.raytheon.uf.edex.core;bundle-version="1.12.1174",
|
||||||
|
com.google.guava;bundle-version="1.0.0"
|
||||||
|
|
|
@ -3,9 +3,17 @@
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||||
|
|
||||||
|
<bean id="FederatedRegistryMonitor" class="com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor">
|
||||||
|
<constructor-arg ref="metadataTxTemplate"/>
|
||||||
|
<constructor-arg ref="registryObjectDao"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="RegistryReplicationManager" class="com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager">
|
<bean id="RegistryReplicationManager" class="com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager">
|
||||||
<constructor-arg ref="ebxmlSubscriptionsEnabled"/>
|
<constructor-arg ref="ebxmlSubscriptionsEnabled"/>
|
||||||
<constructor-arg ref="replicationConfigFileName"/>
|
<constructor-arg ref="replicationConfigFileName"/>
|
||||||
|
<constructor-arg ref="registryObjectDao"/>
|
||||||
|
<constructor-arg ref="FederatedRegistryMonitor"/>
|
||||||
|
<constructor-arg ref="metadataTxTemplate"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/**
|
||||||
|
* 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.availability;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DateTimeValueType;
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Periodically writes a record to the database as long as this registry is
|
||||||
|
* connected to the federation. This class is primarily used to determine if,
|
||||||
|
* upon startup, this registry must synchronize with the federation to get the
|
||||||
|
* state of the registry up to date
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
public class FederatedRegistryMonitor extends RunnableWithTransaction {
|
||||||
|
|
||||||
|
/** The logger instance */
|
||||||
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(FederatedRegistryMonitor.class);
|
||||||
|
|
||||||
|
/** ID of the object to write to the registry */
|
||||||
|
private static final String REGISTRY_AVAILABLE_ID = "RegistryAvailability";
|
||||||
|
|
||||||
|
/** Data access object for registry objects */
|
||||||
|
private RegistryObjectDao registryObjectDao;
|
||||||
|
|
||||||
|
public FederatedRegistryMonitor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FederatedRegistryMonitor(TransactionTemplate txTemplate,
|
||||||
|
RegistryObjectDao registryObjectDao) {
|
||||||
|
super(txTemplate);
|
||||||
|
this.registryObjectDao = registryObjectDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastKnownUptime() {
|
||||||
|
RegistryObjectType regObj = registryObjectDao
|
||||||
|
.getById(REGISTRY_AVAILABLE_ID);
|
||||||
|
Calendar cal = null;
|
||||||
|
if (regObj == null) {
|
||||||
|
cal = TimeUtil.newCalendar();
|
||||||
|
cal.setTimeInMillis(0);
|
||||||
|
} else {
|
||||||
|
DateTimeValueType value = (DateTimeValueType) regObj.getSlotByName(
|
||||||
|
REGISTRY_AVAILABLE_ID).getSlotValue();
|
||||||
|
cal = value.getValue().toGregorianCalendar();
|
||||||
|
}
|
||||||
|
return cal.getTimeInMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithTransaction() {
|
||||||
|
try {
|
||||||
|
RegistryObjectType regObj = registryObjectDao
|
||||||
|
.getById(REGISTRY_AVAILABLE_ID);
|
||||||
|
if (regObj == null) {
|
||||||
|
statusHandler
|
||||||
|
.info("Availability object not found in registry. Creating new entry.");
|
||||||
|
SlotType slot = new SlotType();
|
||||||
|
slot.setName(REGISTRY_AVAILABLE_ID);
|
||||||
|
DateTimeValueType value = new DateTimeValueType();
|
||||||
|
value.setDateTimeValue(EbxmlObjectUtil
|
||||||
|
.getCurrentTimeAsXMLGregorianCalendar());
|
||||||
|
slot.setSlotValue(value);
|
||||||
|
regObj = new RegistryObjectType();
|
||||||
|
regObj.setId(REGISTRY_AVAILABLE_ID);
|
||||||
|
regObj.setLid(REGISTRY_AVAILABLE_ID);
|
||||||
|
regObj.setOwner(RegistryUtil.DEFAULT_OWNER);
|
||||||
|
regObj.setVersionInfo(new VersionInfoType());
|
||||||
|
regObj.setStatus(StatusTypes.APPROVED);
|
||||||
|
regObj.getSlot().add(slot);
|
||||||
|
} else {
|
||||||
|
DateTimeValueType dateTime = (DateTimeValueType) regObj
|
||||||
|
.getSlotByName(REGISTRY_AVAILABLE_ID).getSlotValue();
|
||||||
|
dateTime.setDateTimeValue(EbxmlObjectUtil
|
||||||
|
.getCurrentTimeAsXMLGregorianCalendar());
|
||||||
|
}
|
||||||
|
|
||||||
|
registryObjectDao.createOrUpdate(regObj);
|
||||||
|
} catch (EbxmlRegistryException e) {
|
||||||
|
statusHandler.error("Error updating federated time!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import java.util.List;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager;
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager;
|
||||||
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType;
|
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.FederationType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.OrganizationType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.OrganizationType;
|
||||||
|
@ -38,6 +39,7 @@ import com.raytheon.uf.common.registry.constants.StatusTypes;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
import com.raytheon.uf.common.serialization.SerializationException;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -50,12 +52,14 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 5/22/2013 1707 bphillip Initial implementation
|
* 5/22/2013 1707 bphillip Initial implementation
|
||||||
|
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
public class NcfRegistryFederationManager extends RegistryFederationManager {
|
public class NcfRegistryFederationManager extends RegistryFederationManager
|
||||||
|
implements RegistryInitializedListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new NcfRegistryFederationManager
|
* Creates a new NcfRegistryFederationManager
|
||||||
|
@ -103,7 +107,12 @@ public class NcfRegistryFederationManager extends RegistryFederationManager {
|
||||||
objects.add(primaryContact);
|
objects.add(primaryContact);
|
||||||
objects.add(federationAssociation);
|
objects.add(federationAssociation);
|
||||||
submitObjects(objects);
|
submitObjects(objects);
|
||||||
replicationManager.submitRemoteSubscriptions(registry.getBaseURL());
|
replicationManager.submitRemoteSubscriptions(registry);
|
||||||
|
try {
|
||||||
|
replicationManager.checkDownTime();
|
||||||
|
} catch (MsgRegistryException e) {
|
||||||
|
throw new EbxmlRegistryException("Error checkint down time!", e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
statusHandler.info("Federation is disabled for this registry.");
|
statusHandler.info("Federation is disabled for this registry.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package com.raytheon.uf.edex.datadelivery.registry.federation;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
@ -50,7 +51,6 @@ import com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicatio
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao;
|
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
|
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.EbxmlRegistryException;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -64,6 +64,7 @@ import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 5/22/2013 1707 bphillip Initial implementation
|
* 5/22/2013 1707 bphillip Initial implementation
|
||||||
|
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -71,13 +72,18 @@ import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
public abstract class RegistryFederationManager implements
|
public abstract class RegistryFederationManager {
|
||||||
RegistryInitializedListener {
|
|
||||||
|
|
||||||
/** The logger instance */
|
/** The logger instance */
|
||||||
protected static final IUFStatusHandler statusHandler = UFStatus
|
protected static final IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(RegistryFederationManager.class);
|
.getHandler(RegistryFederationManager.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scheduler service used for registering this registry with the
|
||||||
|
* federation
|
||||||
|
*/
|
||||||
|
protected ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
/** The federation identifier */
|
/** The federation identifier */
|
||||||
public static final String FEDERATION_ID = "Registry Federation";
|
public static final String FEDERATION_ID = "Registry Federation";
|
||||||
|
|
||||||
|
@ -174,6 +180,7 @@ public abstract class RegistryFederationManager implements
|
||||||
+ " Federation Membership Association");
|
+ " Federation Membership Association");
|
||||||
association.setLid(association.getId());
|
association.setLid(association.getId());
|
||||||
association.setObjectType(RegistryObjectTypes.ASSOCIATION);
|
association.setObjectType(RegistryObjectTypes.ASSOCIATION);
|
||||||
|
association.setOwner(federationProperties.getSiteIdentifier());
|
||||||
association.setType(AssociationTypes.HAS_FEDERATION_MEMBER);
|
association.setType(AssociationTypes.HAS_FEDERATION_MEMBER);
|
||||||
association.setStatus(StatusTypes.APPROVED);
|
association.setStatus(StatusTypes.APPROVED);
|
||||||
association.setName(RegistryUtil.getInternationalString(registry
|
association.setName(RegistryUtil.getInternationalString(registry
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -44,9 +43,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
||||||
|
@ -56,7 +53,9 @@ import com.raytheon.uf.common.registry.constants.QueryReturnTypes;
|
||||||
import com.raytheon.uf.common.registry.services.RegistryRESTServices;
|
import com.raytheon.uf.common.registry.services.RegistryRESTServices;
|
||||||
import com.raytheon.uf.common.registry.services.RegistrySOAPServices;
|
import com.raytheon.uf.common.registry.services.RegistrySOAPServices;
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
import com.raytheon.uf.common.serialization.SerializationException;
|
||||||
|
import com.raytheon.uf.edex.database.RunnableWithTransaction;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -69,6 +68,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 5/22/2013 1707 bphillip Initial implementation
|
* 5/22/2013 1707 bphillip Initial implementation
|
||||||
|
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -76,17 +76,12 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
public class WfoRegistryFederationManager extends RegistryFederationManager {
|
public class WfoRegistryFederationManager extends RegistryFederationManager
|
||||||
|
implements RegistryInitializedListener {
|
||||||
|
|
||||||
/** The address of the NCF */
|
/** The address of the NCF */
|
||||||
private String ncfAddress;
|
private String ncfAddress;
|
||||||
|
|
||||||
/**
|
|
||||||
* The scheduler service used for registering this registry with the
|
|
||||||
* federation
|
|
||||||
*/
|
|
||||||
private ScheduledExecutorService scheduler;
|
|
||||||
|
|
||||||
/** The transaction template used to manually handle transactions */
|
/** The transaction template used to manually handle transactions */
|
||||||
private TransactionTemplate txTemplate;
|
private TransactionTemplate txTemplate;
|
||||||
|
|
||||||
|
@ -173,7 +168,7 @@ public class WfoRegistryFederationManager extends RegistryFederationManager {
|
||||||
objects.add(federationAssociation);
|
objects.add(federationAssociation);
|
||||||
submitObjects(objects);
|
submitObjects(objects);
|
||||||
replicationManager.setSubscriptionProcessingEnabled(true);
|
replicationManager.setSubscriptionProcessingEnabled(true);
|
||||||
replicationManager.submitRemoteSubscriptions(registry.getBaseURL());
|
replicationManager.submitRemoteSubscriptions(registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FederationType getFederation() throws EbxmlRegistryException {
|
protected FederationType getFederation() throws EbxmlRegistryException {
|
||||||
|
@ -222,7 +217,7 @@ public class WfoRegistryFederationManager extends RegistryFederationManager {
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
private class RegisterWithFederationTask implements Runnable {
|
private class RegisterWithFederationTask extends RunnableWithTransaction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denotes if this task has successfully registered this registry with
|
* Denotes if this task has successfully registered this registry with
|
||||||
|
@ -234,44 +229,39 @@ public class WfoRegistryFederationManager extends RegistryFederationManager {
|
||||||
* Creates a new RegisterwithFederationTask
|
* Creates a new RegisterwithFederationTask
|
||||||
*/
|
*/
|
||||||
public RegisterWithFederationTask() {
|
public RegisterWithFederationTask() {
|
||||||
|
super(txTemplate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void runWithTransaction() {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
try {
|
||||||
@Override
|
try {
|
||||||
protected void doInTransactionWithoutResult(
|
if (RegistryRESTServices
|
||||||
TransactionStatus status) {
|
.isRegistryAvailable(ncfAddress)) {
|
||||||
try {
|
statusHandler
|
||||||
try {
|
.info("NCF Registry is available. Attempting to join federation...");
|
||||||
if (RegistryRESTServices
|
} else {
|
||||||
.isRegistryAvailable(ncfAddress)) {
|
statusHandler
|
||||||
statusHandler
|
.error("NCF is currently unreachable. Local registry is unable to join the federation at this time. Retrying in 10 seconds...");
|
||||||
.info("NCF Registry is available. Attempting to join federation...");
|
replicationManager
|
||||||
} else {
|
.setSubscriptionProcessingEnabled(false);
|
||||||
statusHandler
|
success = false;
|
||||||
.error("NCF is currently unreachable. Local registry is unable to join the federation at this time. Retrying in 10 seconds...");
|
return;
|
||||||
replicationManager
|
|
||||||
.setSubscriptionProcessingEnabled(false);
|
|
||||||
success = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
registerWithFederation();
|
|
||||||
success = true;
|
|
||||||
} catch (EbxmlRegistryException e) {
|
|
||||||
statusHandler.error(
|
|
||||||
"Error registering with federation", e);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Error initializing EBXML database!", e);
|
|
||||||
}
|
}
|
||||||
|
registerWithFederation();
|
||||||
|
replicationManager.checkDownTime();
|
||||||
|
success = true;
|
||||||
|
} catch (EbxmlRegistryException e) {
|
||||||
|
statusHandler.error(
|
||||||
|
"Error registering with federation", e);
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
});
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Error initializing EBXML database!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* 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 org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
import com.raytheon.uf.edex.database.RunnableWithTransaction;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A task to remove an object from the registry asynchonously
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
public class RegistryRemoveTask extends RunnableWithTransaction {
|
||||||
|
|
||||||
|
/** Data Access object for registry objects */
|
||||||
|
private RegistryObjectDao dao;
|
||||||
|
|
||||||
|
/** The id of the registry object this task is removing */
|
||||||
|
private String idToRemove;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new AsyncRemove object
|
||||||
|
*
|
||||||
|
* @param txTemplate
|
||||||
|
* The Hibernate transaction template
|
||||||
|
* @param lcm
|
||||||
|
* The lifecycle manager
|
||||||
|
* @param idToRemove
|
||||||
|
* The ide of the registry object to remove
|
||||||
|
*/
|
||||||
|
public RegistryRemoveTask(TransactionTemplate txTemplate,
|
||||||
|
RegistryObjectDao dao, String idToRemove) {
|
||||||
|
super(txTemplate);
|
||||||
|
this.dao = dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithTransaction() {
|
||||||
|
dao.delete(dao.getById(idToRemove));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,12 @@ package com.raytheon.uf.edex.datadelivery.registry.replication;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
@ -35,17 +40,23 @@ import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||||
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
|
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
|
||||||
|
|
||||||
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode;
|
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
|
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.DeliveryInfoType;
|
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.QueryType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.VersionInfoType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.VersionInfoType;
|
||||||
|
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
import org.w3c.dom.Attr;
|
import org.w3c.dom.Attr;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -57,6 +68,7 @@ import com.raytheon.uf.common.registry.constants.CanonicalQueryTypes;
|
||||||
import com.raytheon.uf.common.registry.constants.DeliveryMethodTypes;
|
import com.raytheon.uf.common.registry.constants.DeliveryMethodTypes;
|
||||||
import com.raytheon.uf.common.registry.constants.Namespaces;
|
import com.raytheon.uf.common.registry.constants.Namespaces;
|
||||||
import com.raytheon.uf.common.registry.constants.NotificationOptionTypes;
|
import com.raytheon.uf.common.registry.constants.NotificationOptionTypes;
|
||||||
|
import com.raytheon.uf.common.registry.constants.QueryReturnTypes;
|
||||||
import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
|
import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
|
||||||
import com.raytheon.uf.common.registry.constants.StatusTypes;
|
import com.raytheon.uf.common.registry.constants.StatusTypes;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
|
@ -66,7 +78,12 @@ import com.raytheon.uf.common.serialization.JAXBManager;
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
import com.raytheon.uf.common.serialization.SerializationException;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.common.util.CollectionUtil;
|
import com.raytheon.uf.common.util.CollectionUtil;
|
||||||
|
import com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor;
|
||||||
|
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.services.query.QueryConstants;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,6 +98,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 4/24/2013 1675 bphillip Initial implementation
|
* 4/24/2013 1675 bphillip Initial implementation
|
||||||
* 6/4/2013 1707 bphillip Changed to use new NotificationServer objects
|
* 6/4/2013 1707 bphillip Changed to use new NotificationServer objects
|
||||||
|
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -92,12 +110,21 @@ public class RegistryReplicationManager {
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(RegistryReplicationManager.class);
|
.getHandler(RegistryReplicationManager.class);
|
||||||
|
|
||||||
|
private FederatedRegistryMonitor federatedRegistryMonitor;
|
||||||
|
|
||||||
|
private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_DAY
|
||||||
|
* 2 - TimeUtil.MILLIS_PER_HOUR;
|
||||||
|
|
||||||
/** Scheduler service for monitoring subscription submission tasks */
|
/** Scheduler service for monitoring subscription submission tasks */
|
||||||
private ScheduledExecutorService scheduler;
|
private ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
/** The servers that we are subscribing to */
|
/** The servers that we are subscribing to */
|
||||||
private NotificationServers servers;
|
private NotificationServers servers;
|
||||||
|
|
||||||
|
private RegistryObjectDao dao;
|
||||||
|
|
||||||
|
private TransactionTemplate txTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JAXBManager instance for marshalling/unmarshalling objects
|
* The JAXBManager instance for marshalling/unmarshalling objects
|
||||||
*/
|
*/
|
||||||
|
@ -127,10 +154,15 @@ public class RegistryReplicationManager {
|
||||||
* @throws SerializationException
|
* @throws SerializationException
|
||||||
*/
|
*/
|
||||||
public RegistryReplicationManager(boolean subscriptionProcessingEnabled,
|
public RegistryReplicationManager(boolean subscriptionProcessingEnabled,
|
||||||
String notificationServerConfigFileName) throws JAXBException,
|
String notificationServerConfigFileName, RegistryObjectDao dao,
|
||||||
|
FederatedRegistryMonitor availabilityMonitor,
|
||||||
|
TransactionTemplate txTemplate) throws JAXBException,
|
||||||
SerializationException {
|
SerializationException {
|
||||||
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
|
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
|
||||||
this.replicationConfigFileName = notificationServerConfigFileName;
|
this.replicationConfigFileName = notificationServerConfigFileName;
|
||||||
|
this.dao = dao;
|
||||||
|
this.txTemplate = txTemplate;
|
||||||
|
this.federatedRegistryMonitor = availabilityMonitor;
|
||||||
jaxbManager = new JAXBManager(NotificationServers.class,
|
jaxbManager = new JAXBManager(NotificationServers.class,
|
||||||
SubscriptionType.class);
|
SubscriptionType.class);
|
||||||
File notificationServerConfigFile = PathManagerFactory.getPathManager()
|
File notificationServerConfigFile = PathManagerFactory.getPathManager()
|
||||||
|
@ -147,6 +179,201 @@ public class RegistryReplicationManager {
|
||||||
scheduler = Executors.newSingleThreadScheduledExecutor();
|
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 MsgRegistryException
|
||||||
|
* If errors occur during registry synchronization
|
||||||
|
* @throws EbxmlRegistryException
|
||||||
|
* If errors occur during registry synchronization
|
||||||
|
*/
|
||||||
|
public void checkDownTime() throws MsgRegistryException,
|
||||||
|
EbxmlRegistryException {
|
||||||
|
long currentTime = TimeUtil.currentTimeMillis();
|
||||||
|
long lastKnownUp = federatedRegistryMonitor.getLasKnownUptime();
|
||||||
|
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) {
|
||||||
|
statusHandler
|
||||||
|
.warn("Registry has been down for ~2 days. Initiating federated data synchronization....");
|
||||||
|
List<NotificationHostConfiguration> notificationServers = servers
|
||||||
|
.getRegistryReplicationServers();
|
||||||
|
if (servers == null
|
||||||
|
|| CollectionUtil.isNullOrEmpty(servers
|
||||||
|
.getRegistryReplicationServers())) {
|
||||||
|
statusHandler
|
||||||
|
.warn("No servers configured for replication. Unable to synchronize data with federation!");
|
||||||
|
} else {
|
||||||
|
NotificationHostConfiguration registryToSyncFrom = null;
|
||||||
|
for (NotificationHostConfiguration config : notificationServers) {
|
||||||
|
statusHandler.info("Checking availability of registry at: "
|
||||||
|
+ config.getRegistryBaseURL());
|
||||||
|
if (RegistryRESTServices.isRegistryAvailable(config
|
||||||
|
.getRegistryBaseURL())) {
|
||||||
|
registryToSyncFrom = config;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusHandler.info("Registry at "
|
||||||
|
+ config.getRegistryBaseURL()
|
||||||
|
+ " is not available...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// No available registry was found!
|
||||||
|
if (registryToSyncFrom == null) {
|
||||||
|
statusHandler
|
||||||
|
.warn("No available registries found! Registry data will not be synchronized with the federation!");
|
||||||
|
} else {
|
||||||
|
synchronizeRegistryWithFederation(registryToSyncFrom
|
||||||
|
.getRegistryBaseURL());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
statusHandler.info("Starting federated uptime monitor...");
|
||||||
|
scheduler.scheduleAtFixedRate(federatedRegistryMonitor, 0, 1,
|
||||||
|
TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void synchronizeRegistryWithFederation(String remoteRegistryUrl)
|
||||||
|
throws MsgRegistryException, EbxmlRegistryException {
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(25);
|
||||||
|
for (String objectType : objectTypes) {
|
||||||
|
Set<String> localIds = new HashSet<String>();
|
||||||
|
Set<String> remoteIds = new HashSet<String>();
|
||||||
|
statusHandler
|
||||||
|
.info("Getting registry object Ids from local registry...");
|
||||||
|
Collection<String> response = RegistryRESTServices
|
||||||
|
.getRegistryDataAccessService(
|
||||||
|
RegistryUtil.LOCAL_REGISTRY_ADDRESS)
|
||||||
|
.getRegistryObjectIdsOfType(objectType).getPayload();
|
||||||
|
if (response != null) {
|
||||||
|
localIds.addAll(response);
|
||||||
|
}
|
||||||
|
statusHandler.info(localIds.size() + " objects of type "
|
||||||
|
+ objectType + " present in local registry.");
|
||||||
|
statusHandler.info("Getting registry object Ids from "
|
||||||
|
+ remoteRegistryUrl + "...");
|
||||||
|
response = RegistryRESTServices
|
||||||
|
.getRegistryDataAccessService(remoteRegistryUrl)
|
||||||
|
.getRegistryObjectIdsOfType(objectType).getPayload();
|
||||||
|
if (response != null) {
|
||||||
|
remoteIds.addAll(response);
|
||||||
|
}
|
||||||
|
statusHandler.info(remoteIds.size() + " objects of type "
|
||||||
|
+ objectType + " present on registry at "
|
||||||
|
+ remoteRegistryUrl);
|
||||||
|
statusHandler.info("Synchronizing objects of type " + objectType
|
||||||
|
+ "...");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate through local objects and compare them with the remote
|
||||||
|
* object inventory to determine if they need to be updated or
|
||||||
|
* deleted locally
|
||||||
|
*/
|
||||||
|
for (String localId : localIds) {
|
||||||
|
if (remoteIds.contains(localId)) {
|
||||||
|
RegistryObjectType objectToSubmit;
|
||||||
|
try {
|
||||||
|
objectToSubmit = getRemoteObject(remoteRegistryUrl,
|
||||||
|
localId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler.error("Error getting remote object: "
|
||||||
|
+ localId, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
objectToSubmit.addSlot(EbxmlObjectUtil.HOME_SLOT_NAME,
|
||||||
|
remoteRegistryUrl);
|
||||||
|
RegistrySubmitTask submitTask = new RegistrySubmitTask(
|
||||||
|
txTemplate, dao, objectToSubmit, remoteRegistryUrl);
|
||||||
|
executor.submit(submitTask);
|
||||||
|
} else {
|
||||||
|
RegistryRemoveTask removeTask = new RegistryRemoveTask(
|
||||||
|
txTemplate, dao, localId);
|
||||||
|
executor.submit(removeTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate through the remote objects to see if there are any
|
||||||
|
* objects on the remote registry that do not exist local. If found,
|
||||||
|
* retrieve them and add them to the local registry
|
||||||
|
*/
|
||||||
|
for (String remoteId : remoteIds) {
|
||||||
|
if (!localIds.contains(remoteId)) {
|
||||||
|
RegistryObjectType objectToSubmit;
|
||||||
|
try {
|
||||||
|
objectToSubmit = getRemoteObject(remoteRegistryUrl,
|
||||||
|
remoteId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler.error("Error getting remote object: "
|
||||||
|
+ remoteId, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
objectToSubmit.addSlot(EbxmlObjectUtil.HOME_SLOT_NAME,
|
||||||
|
remoteRegistryUrl);
|
||||||
|
RegistrySubmitTask submitTask = new RegistrySubmitTask(
|
||||||
|
txTemplate, dao, objectToSubmit, remoteRegistryUrl);
|
||||||
|
executor.submit(submitTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegistryObjectType getRemoteObject(String remoteRegistryUrl,
|
||||||
|
String objectId) throws Exception {
|
||||||
|
final QueryType queryType = new QueryType();
|
||||||
|
queryType.setQueryDefinition(CanonicalQueryTypes.GET_OBJECT_BY_ID);
|
||||||
|
Set<SlotType> slots = new HashSet<SlotType>();
|
||||||
|
final SlotType slot = new SlotType();
|
||||||
|
slot.setName(QueryConstants.ID);
|
||||||
|
final StringValueType slotValue = new StringValueType();
|
||||||
|
slotValue.setStringValue(objectId);
|
||||||
|
slot.setSlotValue(slotValue);
|
||||||
|
slots.add(slot);
|
||||||
|
queryType.setSlot(slots);
|
||||||
|
|
||||||
|
QueryRequest queryRequest = new QueryRequest();
|
||||||
|
queryRequest.setResponseOption(new ResponseOptionType(
|
||||||
|
QueryReturnTypes.REGISTRY_OBJECT, true));
|
||||||
|
queryRequest.setFederated(false);
|
||||||
|
queryRequest.setQuery(queryType);
|
||||||
|
QueryResponse response = RegistrySOAPServices.getQueryServiceForHost(
|
||||||
|
remoteRegistryUrl).executeQuery(queryRequest);
|
||||||
|
if (!CollectionUtil.isNullOrEmpty(response.getRegistryObjects())) {
|
||||||
|
return response.getRegistryObjects().get(0);
|
||||||
|
} else {
|
||||||
|
throw new EbxmlRegistryException("Object " + objectId
|
||||||
|
+ " not found on remote server!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static method only used during the Spring container to inject the object
|
* Static method only used during the Spring container to inject the object
|
||||||
* types to subscribe to for registry replication
|
* types to subscribe to for registry replication
|
||||||
|
@ -166,7 +393,7 @@ public class RegistryReplicationManager {
|
||||||
* @param baseURL
|
* @param baseURL
|
||||||
* The url of the registry to send the subscriptions to
|
* The url of the registry to send the subscriptions to
|
||||||
*/
|
*/
|
||||||
public void submitRemoteSubscriptions(String baseURL) {
|
public void submitRemoteSubscriptions(RegistryType registry) {
|
||||||
|
|
||||||
if (subscriptionProcessingEnabled) {
|
if (subscriptionProcessingEnabled) {
|
||||||
statusHandler.info("Registry Replication is enabled.");
|
statusHandler.info("Registry Replication is enabled.");
|
||||||
|
@ -187,7 +414,7 @@ public class RegistryReplicationManager {
|
||||||
statusHandler
|
statusHandler
|
||||||
.info("Submitting subscriptions to registry replication servers...");
|
.info("Submitting subscriptions to registry replication servers...");
|
||||||
for (NotificationHostConfiguration config : replicationRegistries) {
|
for (NotificationHostConfiguration config : replicationRegistries) {
|
||||||
scheduleSubscriptionSubmission(config, baseURL);
|
scheduleSubscriptionSubmission(config, registry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,9 +428,9 @@ public class RegistryReplicationManager {
|
||||||
* The url of the registry to submit the subscriptions to
|
* The url of the registry to submit the subscriptions to
|
||||||
*/
|
*/
|
||||||
private void scheduleSubscriptionSubmission(
|
private void scheduleSubscriptionSubmission(
|
||||||
NotificationHostConfiguration config, String baseURL) {
|
NotificationHostConfiguration config, RegistryType registry) {
|
||||||
final SubmitSubscriptionTask submitSubscriptionTask = new SubmitSubscriptionTask(
|
final SubmitSubscriptionTask submitSubscriptionTask = new SubmitSubscriptionTask(
|
||||||
config, baseURL);
|
config, registry);
|
||||||
final ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
|
final ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
|
||||||
submitSubscriptionTask, 0, 10, TimeUnit.SECONDS);
|
submitSubscriptionTask, 0, 10, TimeUnit.SECONDS);
|
||||||
scheduler.schedule(new Runnable() {
|
scheduler.schedule(new Runnable() {
|
||||||
|
@ -227,7 +454,7 @@ public class RegistryReplicationManager {
|
||||||
* replication subscriptions to
|
* replication subscriptions to
|
||||||
*/
|
*/
|
||||||
private void submitSubscriptionsToHost(
|
private void submitSubscriptionsToHost(
|
||||||
NotificationHostConfiguration config, String localRegistryBaseURL) {
|
NotificationHostConfiguration config, RegistryType localRegistry) {
|
||||||
statusHandler
|
statusHandler
|
||||||
.info("Generating registry replication subscriptions for registry at ["
|
.info("Generating registry replication subscriptions for registry at ["
|
||||||
+ config.getRegistrySiteName()
|
+ config.getRegistrySiteName()
|
||||||
|
@ -239,7 +466,7 @@ public class RegistryReplicationManager {
|
||||||
SubscriptionType subscription;
|
SubscriptionType subscription;
|
||||||
try {
|
try {
|
||||||
subscription = createSubscription(config.getRegistryBaseURL(),
|
subscription = createSubscription(config.getRegistryBaseURL(),
|
||||||
objectType, localRegistryBaseURL);
|
objectType, localRegistry);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RegistryException("Error creating subscription", e);
|
throw new RegistryException("Error creating subscription", e);
|
||||||
}
|
}
|
||||||
|
@ -267,10 +494,10 @@ public class RegistryReplicationManager {
|
||||||
* If errors occur while creating the subscription object
|
* If errors occur while creating the subscription object
|
||||||
*/
|
*/
|
||||||
private SubscriptionType createSubscription(String host, String objectType,
|
private SubscriptionType createSubscription(String host, String objectType,
|
||||||
String localRegistryBaseURL) throws Exception {
|
RegistryType registry) throws Exception {
|
||||||
// Set normal registry object fields
|
// Set normal registry object fields
|
||||||
String subscriptionDetail = "Replication Subscription for ["
|
String subscriptionDetail = "Replication Subscription for ["
|
||||||
+ objectType + "] objects for server [" + localRegistryBaseURL
|
+ objectType + "] objects for server [" + registry.getBaseURL()
|
||||||
+ "]";
|
+ "]";
|
||||||
SubscriptionType sub = new SubscriptionType();
|
SubscriptionType sub = new SubscriptionType();
|
||||||
sub.setId(subscriptionDetail);
|
sub.setId(subscriptionDetail);
|
||||||
|
@ -283,7 +510,7 @@ public class RegistryReplicationManager {
|
||||||
version.setVersionName("1");
|
version.setVersionName("1");
|
||||||
version.setUserVersionName("1");
|
version.setUserVersionName("1");
|
||||||
sub.setVersionInfo(version);
|
sub.setVersionInfo(version);
|
||||||
sub.setOwner("Subscription Owner");
|
sub.setOwner(registry.getOwner());
|
||||||
sub.setStatus(StatusTypes.APPROVED);
|
sub.setStatus(StatusTypes.APPROVED);
|
||||||
|
|
||||||
sub.setStartTime(EbxmlObjectUtil.getTimeAsXMLGregorianCalendar(0));
|
sub.setStartTime(EbxmlObjectUtil.getTimeAsXMLGregorianCalendar(0));
|
||||||
|
@ -304,7 +531,7 @@ public class RegistryReplicationManager {
|
||||||
String endpointType = DeliveryMethodTypes.SOAP;
|
String endpointType = DeliveryMethodTypes.SOAP;
|
||||||
W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
|
W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
|
||||||
builder.address(RegistrySOAPServices.getNotificationListenerServiceUrl(
|
builder.address(RegistrySOAPServices.getNotificationListenerServiceUrl(
|
||||||
localRegistryBaseURL).toString());
|
registry.getBaseURL()).toString());
|
||||||
W3CEndpointReference ref = builder.build();
|
W3CEndpointReference ref = builder.build();
|
||||||
DOMResult dom = new DOMResult();
|
DOMResult dom = new DOMResult();
|
||||||
ref.writeTo(dom);
|
ref.writeTo(dom);
|
||||||
|
@ -355,8 +582,8 @@ public class RegistryReplicationManager {
|
||||||
/** The server configuration */
|
/** The server configuration */
|
||||||
private NotificationHostConfiguration config;
|
private NotificationHostConfiguration config;
|
||||||
|
|
||||||
/** The base URL of the remote registry */
|
/** The remote registry */
|
||||||
private String baseURL;
|
private RegistryType registry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SubmitSubscriptionTask
|
* Creates a new SubmitSubscriptionTask
|
||||||
|
@ -367,15 +594,16 @@ public class RegistryReplicationManager {
|
||||||
* The base URL of the remote registry
|
* The base URL of the remote registry
|
||||||
*/
|
*/
|
||||||
public SubmitSubscriptionTask(NotificationHostConfiguration config,
|
public SubmitSubscriptionTask(NotificationHostConfiguration config,
|
||||||
String baseURL) {
|
RegistryType registry) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.baseURL = baseURL;
|
this.registry = registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
String remoteRegistryBaseURL = config.getRegistryBaseURL();
|
final String remoteRegistryBaseURL = config
|
||||||
|
.getRegistryBaseURL();
|
||||||
statusHandler.info("Checking if remote registry at ["
|
statusHandler.info("Checking if remote registry at ["
|
||||||
+ remoteRegistryBaseURL + "] is available...");
|
+ remoteRegistryBaseURL + "] is available...");
|
||||||
|
|
||||||
|
@ -390,7 +618,25 @@ public class RegistryReplicationManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
submitSubscriptionsToHost(config, baseURL);
|
statusHandler
|
||||||
|
.info("Removing remote subscriptions prior to submission of new subscriptions");
|
||||||
|
RegistryRESTServices.getRegistryDataAccessService(
|
||||||
|
config.getRegistryBaseURL())
|
||||||
|
.removeSubscriptionsForSite(registry.getOwner());
|
||||||
|
submitSubscriptionsToHost(config, registry);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds a hook to remove the subscriptions from the remote
|
||||||
|
* server when this server shuts down
|
||||||
|
*/
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||||
|
public void run() {
|
||||||
|
RegistryRESTServices.getRegistryDataAccessService(
|
||||||
|
remoteRegistryBaseURL)
|
||||||
|
.removeSubscriptionsForSite(
|
||||||
|
registry.getOwner());
|
||||||
|
}
|
||||||
|
});
|
||||||
success = true;
|
success = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler
|
statusHandler
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* 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 oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||||
|
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
import com.raytheon.uf.edex.database.RunnableWithTransaction;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A task to submit an object to the registry asynchonously
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
public class RegistrySubmitTask extends RunnableWithTransaction {
|
||||||
|
|
||||||
|
/** The Registry Object data access object */
|
||||||
|
private RegistryObjectDao dao;
|
||||||
|
|
||||||
|
/** The id of the registry object this task is submitting */
|
||||||
|
private RegistryObjectType objectToSubmit;
|
||||||
|
|
||||||
|
public RegistrySubmitTask(TransactionTemplate txTemplate,
|
||||||
|
RegistryObjectDao dao, RegistryObjectType objectToSubmit,
|
||||||
|
String retrievedFrom) {
|
||||||
|
super(txTemplate);
|
||||||
|
this.dao = dao;
|
||||||
|
this.objectToSubmit = objectToSubmit;
|
||||||
|
if (this.objectToSubmit.getSlotByName(EbxmlObjectUtil.HOME_SLOT_NAME) == null) {
|
||||||
|
this.objectToSubmit.addSlot(EbxmlObjectUtil.HOME_SLOT_NAME,
|
||||||
|
retrievedFrom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithTransaction() {
|
||||||
|
RegistryObjectType existingObject = dao.getById(objectToSubmit.getId());
|
||||||
|
if (existingObject == null) {
|
||||||
|
dao.create(objectToSubmit);
|
||||||
|
} else {
|
||||||
|
dao.merge(objectToSubmit, existingObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
com.raytheon.uf.edex.registry.ebxml.services.query.adhoc.AdhocQueryExpression
|
com.raytheon.uf.edex.registry.ebxml.services.query.adhoc.AdhocQueryExpression
|
||||||
|
com.raytheon.uf.edex.registry.ebxml.services.rest.RestResponse
|
|
@ -37,6 +37,7 @@
|
||||||
class="com.raytheon.uf.edex.registry.ebxml.services.RegistryGarbageCollector">
|
class="com.raytheon.uf.edex.registry.ebxml.services.RegistryGarbageCollector">
|
||||||
<constructor-arg ref="slotTypeDao" />
|
<constructor-arg ref="slotTypeDao" />
|
||||||
<constructor-arg ref="AuditableEventTypeDao" />
|
<constructor-arg ref="AuditableEventTypeDao" />
|
||||||
|
<constructor-arg ref="metadataTxTemplate"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
@ -70,6 +70,11 @@
|
||||||
<property name="webUtil" ref="RegistryWebUtil" />
|
<property name="webUtil" ref="RegistryWebUtil" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="registryDataAccessService" class="com.raytheon.uf.edex.registry.ebxml.services.rest.RegistryDataAccessService">
|
||||||
|
<property name="registryObjectDao" ref="registryObjectDao"/>
|
||||||
|
<property name="lcm" ref="lcmServiceImpl"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="registryAvailabilityService"
|
<bean id="registryAvailabilityService"
|
||||||
class="com.raytheon.uf.edex.registry.ebxml.services.rest.RegistryAvailableRestService" />
|
class="com.raytheon.uf.edex.registry.ebxml.services.rest.RegistryAvailableRestService" />
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# The period which registry subscriptions are processed
|
# The period which registry subscriptions are processed
|
||||||
ebxml-subscription-process.cron=0+0/1+*+*+*+?
|
ebxml-subscription-process.cron=0+0/1+*+*+*+?
|
||||||
ebxml-garbage-collect-process.cron=0/30+*+*+*+*+?
|
ebxml-garbage-collect-process.cron=0/1+*+*+*+*+?
|
||||||
# Master switch enabling email transmission
|
# Master switch enabling email transmission
|
||||||
ebxml-email.enabled=false
|
ebxml-email.enabled=false
|
|
@ -61,6 +61,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||||
* 4/9/2013 1802 bphillip Removed exception catching
|
* 4/9/2013 1802 bphillip Removed exception catching
|
||||||
* Apr 17, 2013 1914 djohnson Use strategy for subscription processing.
|
* Apr 17, 2013 1914 djohnson Use strategy for subscription processing.
|
||||||
* May 02, 2013 1910 djohnson Broke out registry subscription notification to a service class.
|
* May 02, 2013 1910 djohnson Broke out registry subscription notification to a service class.
|
||||||
|
* 7/29/2013 2191 bphillip Changed method to get expired events
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -94,9 +95,6 @@ public class AuditableEventTypeDao extends
|
||||||
/** Cutoff parameter for the query to get the expired events */
|
/** Cutoff parameter for the query to get the expired events */
|
||||||
private static final String GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER = "cutoff";
|
private static final String GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER = "cutoff";
|
||||||
|
|
||||||
/** Batch size for the query to get expired events */
|
|
||||||
private static final int GET_EXPIRED_EVENTS_QUERY_BATCH_SIZE = 2500;
|
|
||||||
|
|
||||||
/** Query to get Expired AuditableEvents */
|
/** Query to get Expired AuditableEvents */
|
||||||
private static final String GET_EXPIRED_EVENTS_QUERY = "FROM AuditableEventType event where event.timestamp < :"
|
private static final String GET_EXPIRED_EVENTS_QUERY = "FROM AuditableEventType event where event.timestamp < :"
|
||||||
+ GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER;
|
+ GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER;
|
||||||
|
@ -115,25 +113,20 @@ public class AuditableEventTypeDao extends
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes auditable events older than 48 hrs old
|
* Gets auditable events older than 48 hrs old
|
||||||
*
|
*
|
||||||
* @throws EbxmlRegistryException
|
* @throws EbxmlRegistryException
|
||||||
* If errors occur purging auditable events
|
* If errors occur purging auditable events
|
||||||
*/
|
*/
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
public void deleteExpiredEvents() throws EbxmlRegistryException {
|
public List<AuditableEventType> getExpiredEvents(int limit)
|
||||||
|
throws EbxmlRegistryException {
|
||||||
Calendar cutoffTime = TimeUtil.newGmtCalendar();
|
Calendar cutoffTime = TimeUtil.newGmtCalendar();
|
||||||
cutoffTime.add(Calendar.HOUR_OF_DAY, -AUDITABLE_EVENT_RETENTION_TIME);
|
cutoffTime.add(Calendar.HOUR_OF_DAY, -AUDITABLE_EVENT_RETENTION_TIME);
|
||||||
List<AuditableEventType> expiredEvents = this.executeHQLQuery(
|
return this.executeHQLQuery(GET_EXPIRED_EVENTS_QUERY, limit,
|
||||||
GET_EXPIRED_EVENTS_QUERY, GET_EXPIRED_EVENTS_QUERY_BATCH_SIZE,
|
|
||||||
GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER, EbxmlObjectUtil
|
GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER, EbxmlObjectUtil
|
||||||
.getTimeAsXMLGregorianCalendar(cutoffTime
|
.getTimeAsXMLGregorianCalendar(cutoffTime
|
||||||
.getTimeInMillis()));
|
.getTimeInMillis()));
|
||||||
if (!expiredEvents.isEmpty()) {
|
|
||||||
statusHandler.info("Deleting " + expiredEvents.size()
|
|
||||||
+ " Auditable Events prior to: " + cutoffTime.getTime());
|
|
||||||
this.template.deleteAll(expiredEvents);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.List;
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||||
|
|
||||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +37,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
* 3/13/2013 1082 bphillip Initial creation
|
* 3/13/2013 1082 bphillip Initial creation
|
||||||
* 4/9/2013 1802 bphillip Removed exception catching
|
* 4/9/2013 1802 bphillip Removed exception catching
|
||||||
* 6/4/2013 2022 bphillip Added delete objects of type method
|
* 6/4/2013 2022 bphillip Added delete objects of type method
|
||||||
|
* 7/29/2013 2191 bphillip Added new methods to support registry synchronization
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -48,25 +48,31 @@ public class RegistryObjectDao extends
|
||||||
RegistryObjectTypeDao<RegistryObjectType> {
|
RegistryObjectTypeDao<RegistryObjectType> {
|
||||||
|
|
||||||
/** Delete object type parameterized statement */
|
/** Delete object type parameterized statement */
|
||||||
private static final String DELETE_OBJECT_TYPE = "DELETE RegistryObjectType regObj where regObj.objectType=:objectType";
|
private static final String GET_IDS_BY_OBJECT_TYPE = "SELECT regObj.id FROM RegistryObjectType regObj WHERE regObj.objectType=:objectType";
|
||||||
|
|
||||||
public RegistryObjectDao() {
|
public RegistryObjectDao() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes objects of a specific type from the registry
|
* Gets the object ids of objects of the given object type
|
||||||
*
|
*
|
||||||
* @param objectType
|
* @param objectType
|
||||||
* The object type to delete
|
* The object type to get the ids for
|
||||||
* @throws DataAccessLayerException
|
* @return The list of object ids of objects of the given type
|
||||||
* If errors occur on the delete
|
|
||||||
*/
|
*/
|
||||||
public void deleteObjectsOfType(String objectType)
|
public List<String> getRegistryObjectIdsOfType(String objectType) {
|
||||||
throws DataAccessLayerException {
|
return this.executeHQLQuery(GET_IDS_BY_OBJECT_TYPE, "objectType",
|
||||||
int objectsDeleted = this.executeHQLStatement(DELETE_OBJECT_TYPE,
|
objectType);
|
||||||
"objectType", objectType);
|
}
|
||||||
statusHandler.info(objectsDeleted + " objects of type " + objectType
|
|
||||||
+ " deleted from registry");
|
/**
|
||||||
|
* Deletes a persistent object
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* The persistent object to delete
|
||||||
|
*/
|
||||||
|
public void deleteWithoutMerge(RegistryObjectType obj) {
|
||||||
|
this.template.delete(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,9 +23,6 @@ import java.util.List;
|
||||||
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
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.dao.SessionManagedDao;
|
import com.raytheon.uf.edex.database.dao.SessionManagedDao;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +36,7 @@ import com.raytheon.uf.edex.database.dao.SessionManagedDao;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 7/11/2013 1707 bphillip Initial implementation
|
* 7/11/2013 1707 bphillip Initial implementation
|
||||||
|
* 7/29/2013 2191 bphillip Modified method to get orphaned slots
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -71,35 +69,34 @@ public class SlotTypeDao extends SessionManagedDao<Integer, SlotType> {
|
||||||
+ "select child_slot_key from ebxml.emailaddress_slot "
|
+ "select child_slot_key from ebxml.emailaddress_slot "
|
||||||
+ "UNION "
|
+ "UNION "
|
||||||
+ "select child_slot_key from ebxml.postaladdress_slot "
|
+ "select child_slot_key from ebxml.postaladdress_slot "
|
||||||
+ ")";
|
+ ") limit %s";
|
||||||
|
|
||||||
/** Keys parameter for the query to get the orphaned slot objects */
|
|
||||||
private static final String GET_BY_ID_QUERY_KEYS_PARAMETER = "keys";
|
|
||||||
|
|
||||||
/** Result batch size for the query to get the orphaned slot objects */
|
|
||||||
private static final int GET_BY_ID_QUERY_BATCH_SIZE = 1000;
|
|
||||||
|
|
||||||
private static final String GET_BY_ID_QUERY = "FROM SlotType slot where slot.key in (:"
|
|
||||||
+ GET_BY_ID_QUERY_KEYS_PARAMETER + ")";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<SlotType> getEntityClass() {
|
protected Class<SlotType> getEntityClass() {
|
||||||
return SlotType.class;
|
return SlotType.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets orphaned slot ids
|
||||||
|
*
|
||||||
|
* @param limit
|
||||||
|
* The maximum number of results to return
|
||||||
|
* @return List of orphaned ids of size limit
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
public List<Integer> getOrphanedSlotIds(int limit) {
|
||||||
public void deleteOrphanedSlots() {
|
return this
|
||||||
List<Integer> orphanedSlotIds = this.getSessionFactory()
|
.getSessionFactory()
|
||||||
.getCurrentSession().createSQLQuery(ORPHANED_SLOT_QUERY).list();
|
.getCurrentSession()
|
||||||
if (!orphanedSlotIds.isEmpty()) {
|
.createSQLQuery(
|
||||||
|
String.format(ORPHANED_SLOT_QUERY,
|
||||||
|
String.valueOf(limit))).list();
|
||||||
|
}
|
||||||
|
|
||||||
List<SlotType> slots = this.executeHQLQuery(GET_BY_ID_QUERY,
|
public void deleteBySlotId(Integer id) {
|
||||||
GET_BY_ID_QUERY_BATCH_SIZE, GET_BY_ID_QUERY_KEYS_PARAMETER,
|
SlotType slot = this.getById(id);
|
||||||
orphanedSlotIds);
|
if (slot != null) {
|
||||||
statusHandler.info("Removing " + orphanedSlotIds.size()
|
this.template.delete(slot);
|
||||||
+ " orphaned slots...");
|
|
||||||
this.deleteAll(slots);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,22 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.edex.registry.ebxml.services;
|
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 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.dao.AuditableEventTypeDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.SlotTypeDao;
|
import com.raytheon.uf.edex.registry.ebxml.dao.SlotTypeDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
|
@ -38,27 +52,48 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 7/11/2013 1707 bphillip Initial implementation
|
* 7/11/2013 1707 bphillip Initial implementation
|
||||||
|
* 7/29/2013 2191 bphillip Added executors to remove orphaned slots and expired events
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
|
@Service
|
||||||
|
@Transactional
|
||||||
public class RegistryGarbageCollector {
|
public class RegistryGarbageCollector {
|
||||||
|
|
||||||
|
/** The logger instance */
|
||||||
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(RegistryGarbageCollector.class);
|
||||||
|
|
||||||
/** Sentinel to denote if the garbage collection is currently running */
|
/** Sentinel to denote if the garbage collection is currently running */
|
||||||
private AtomicBoolean running = new AtomicBoolean(false);
|
private AtomicBoolean running = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
/** The executor service to remove orphaned slots */
|
||||||
|
private ThreadPoolExecutor orphanedSlotExecutor;
|
||||||
|
|
||||||
|
/** 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 SlotType */
|
/** Data access object for SlotType */
|
||||||
private SlotTypeDao slotDao;
|
private SlotTypeDao slotDao;
|
||||||
|
|
||||||
/** Data access object for AuditableEventType */
|
/** Data access object for AuditableEventType */
|
||||||
private AuditableEventTypeDao eventDao;
|
private AuditableEventTypeDao eventDao;
|
||||||
|
|
||||||
|
private static final int QUEUE_MAX_SIZE = 500;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new GarbageCollector object
|
* Creates a new GarbageCollector object
|
||||||
*/
|
*/
|
||||||
public RegistryGarbageCollector() {
|
public RegistryGarbageCollector() {
|
||||||
|
orphanedSlotExecutor = new ThreadPoolExecutor(1, 3, 1L,
|
||||||
|
TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(250));
|
||||||
|
expiredEventExecutor = new ThreadPoolExecutor(1, 3, 1L,
|
||||||
|
TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(250));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,24 +105,119 @@ public class RegistryGarbageCollector {
|
||||||
* The auditable event dao to use
|
* The auditable event dao to use
|
||||||
*/
|
*/
|
||||||
public RegistryGarbageCollector(SlotTypeDao slotDao,
|
public RegistryGarbageCollector(SlotTypeDao slotDao,
|
||||||
AuditableEventTypeDao eventDao) {
|
AuditableEventTypeDao eventDao, TransactionTemplate txTemplate) {
|
||||||
|
this();
|
||||||
this.slotDao = slotDao;
|
this.slotDao = slotDao;
|
||||||
this.eventDao = eventDao;
|
this.eventDao = eventDao;
|
||||||
|
this.txTemplate = txTemplate;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans up the registry by removing unused and/or orphaned objects
|
* Cleans up the registry by removing unused and/or orphaned objects
|
||||||
*/
|
*/
|
||||||
public void gc() throws EbxmlRegistryException {
|
public void gc() {
|
||||||
|
|
||||||
if (!running.compareAndSet(false, true)) {
|
if (!running.compareAndSet(false, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
eventDao.deleteExpiredEvents();
|
purgeOrphanedSlots();
|
||||||
slotDao.deleteOrphanedSlots();
|
purgeExpiredEvents();
|
||||||
|
} catch (EbxmlRegistryException e) {
|
||||||
|
statusHandler.error("Error purging auditable events!", e);
|
||||||
} finally {
|
} finally {
|
||||||
running.set(false);
|
running.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purges orphaned slots in the registry
|
||||||
|
*/
|
||||||
|
private void purgeOrphanedSlots() {
|
||||||
|
/*
|
||||||
|
* Determines how many more orphaned slots can be added to the queue
|
||||||
|
* based on the existing queue size
|
||||||
|
*/
|
||||||
|
int limit = QUEUE_MAX_SIZE - orphanedSlotExecutor.getQueue().size();
|
||||||
|
if (limit > QUEUE_MAX_SIZE * .25) {
|
||||||
|
List<Integer> orphanedSlotIds = slotDao.getOrphanedSlotIds(limit);
|
||||||
|
for (Integer slotId : orphanedSlotIds) {
|
||||||
|
try {
|
||||||
|
orphanedSlotExecutor.submit(new RemoveOrphanedSlot(
|
||||||
|
txTemplate, slotId));
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
// Could not add more to the queue since it is full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purges expired events older than 2 days
|
||||||
|
*
|
||||||
|
* @throws EbxmlRegistryException
|
||||||
|
* If errors occur while enqueuing events to be deleted
|
||||||
|
*/
|
||||||
|
private void purgeExpiredEvents() throws EbxmlRegistryException {
|
||||||
|
int limit = QUEUE_MAX_SIZE - expiredEventExecutor.getQueue().size();
|
||||||
|
if (limit > QUEUE_MAX_SIZE * .25) {
|
||||||
|
List<AuditableEventType> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task to remove orphaned slots that is run asynchronously
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class RemoveOrphanedSlot extends RunnableWithTransaction {
|
||||||
|
|
||||||
|
/** The id of the orphaned slot to be removed by this task */
|
||||||
|
private Integer slotId;
|
||||||
|
|
||||||
|
public RemoveOrphanedSlot(TransactionTemplate txTemplate, Integer slotId) {
|
||||||
|
super(txTemplate);
|
||||||
|
this.slotId = slotId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithTransaction() {
|
||||||
|
slotDao.deleteBySlotId(slotId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ 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.AssociationType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationNodeType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationNodeType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationSchemeType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ClassificationSchemeType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ExtensibleObjectType;
|
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType;
|
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.QueryType;
|
||||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||||
|
@ -329,7 +328,8 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
||||||
statusHandler
|
statusHandler
|
||||||
.info("Client has selected to check object references before submitting objects.");
|
.info("Client has selected to check object references before submitting objects.");
|
||||||
ValidateObjectsRequest validateObjectsRequest = new ValidateObjectsRequest();
|
ValidateObjectsRequest validateObjectsRequest = new ValidateObjectsRequest();
|
||||||
validateObjectsRequest.setOriginalObjects(request.getRegistryObjectList());
|
validateObjectsRequest.setOriginalObjects(request
|
||||||
|
.getRegistryObjectList());
|
||||||
|
|
||||||
// Uses the validation service directly, not going through the
|
// Uses the validation service directly, not going through the
|
||||||
// web-service client interface
|
// web-service client interface
|
||||||
|
@ -338,8 +338,10 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
||||||
EbxmlObjectUtil.spiObjectFactory
|
EbxmlObjectUtil.spiObjectFactory
|
||||||
.createValidateObjectsResponse());
|
.createValidateObjectsResponse());
|
||||||
|
|
||||||
final List<RegistryExceptionType> validationExceptions = validationResponse.getException();
|
final List<RegistryExceptionType> validationExceptions = validationResponse
|
||||||
final List<RegistryExceptionType> responseExceptions = response.getException();
|
.getException();
|
||||||
|
final List<RegistryExceptionType> responseExceptions = response
|
||||||
|
.getException();
|
||||||
|
|
||||||
if (!validationExceptions.isEmpty()) {
|
if (!validationExceptions.isEmpty()) {
|
||||||
// Only care about unresolved references
|
// Only care about unresolved references
|
||||||
|
@ -636,7 +638,7 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkReplica(SubmitObjectsRequest request,
|
private void checkReplica(SubmitObjectsRequest request,
|
||||||
ExtensibleObjectType object1, ExtensibleObjectType object2)
|
RegistryObjectType object1, RegistryObjectType object2)
|
||||||
throws MsgRegistryException {
|
throws MsgRegistryException {
|
||||||
boolean fromNotification = request
|
boolean fromNotification = request
|
||||||
.getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME) != null;
|
.getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME) != null;
|
||||||
|
@ -645,7 +647,11 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
||||||
String object2Home = object2
|
String object2Home = object2
|
||||||
.getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME);
|
.getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME);
|
||||||
|
|
||||||
|
if (object1.getOwner().equals(object2.getOwner())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (fromNotification) {
|
if (fromNotification) {
|
||||||
|
|
||||||
if (object1Home != null && object2Home == null) {
|
if (object1Home != null && object2Home == null) {
|
||||||
throw EbxmlExceptionUtil.createMsgRegistryException(
|
throw EbxmlExceptionUtil.createMsgRegistryException(
|
||||||
"Cannot overwrite local object with replica",
|
"Cannot overwrite local object with replica",
|
||||||
|
|
|
@ -44,7 +44,6 @@ import com.raytheon.uf.common.registry.constants.StatusTypes;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao;
|
import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.dao.NotificationTypeDao;
|
import com.raytheon.uf.edex.registry.ebxml.dao.NotificationTypeDao;
|
||||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
|
@ -164,39 +163,32 @@ public class RegistryNotificationManager {
|
||||||
subscription, objectsOfInterest);
|
subscription, objectsOfInterest);
|
||||||
|
|
||||||
if (!eventsOfInterest.isEmpty()) {
|
if (!eventsOfInterest.isEmpty()) {
|
||||||
try {
|
for (NotificationListenerWrapper listener : listeners) {
|
||||||
for (NotificationListenerWrapper listener : listeners) {
|
int subListCount = eventsOfInterest.size() / SIZE_LIMIT;
|
||||||
int subListCount = eventsOfInterest.size() / SIZE_LIMIT;
|
int lastListSize = eventsOfInterest.size() % SIZE_LIMIT;
|
||||||
int lastListSize = eventsOfInterest.size() % SIZE_LIMIT;
|
for (int i = 0; i < subListCount; i++) {
|
||||||
for (int i = 0; i < subListCount; i++) {
|
NotificationType notification = getNotification(
|
||||||
NotificationType notification = getNotification(
|
subscription,
|
||||||
subscription, listener.address,
|
listener.address,
|
||||||
objectsOfInterest, eventsOfInterest.subList(
|
objectsOfInterest,
|
||||||
SIZE_LIMIT * i, SIZE_LIMIT * i
|
eventsOfInterest.subList(SIZE_LIMIT * i, SIZE_LIMIT
|
||||||
+ SIZE_LIMIT));
|
* i + SIZE_LIMIT));
|
||||||
if (!notification.getEvent().isEmpty()) {
|
if (!notification.getEvent().isEmpty()) {
|
||||||
sendNotification(listener, notification,
|
sendNotification(listener, notification,
|
||||||
listener.address);
|
listener.address);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (lastListSize > 0) {
|
|
||||||
NotificationType notification = getNotification(
|
|
||||||
subscription,
|
|
||||||
listener.address,
|
|
||||||
objectsOfInterest,
|
|
||||||
eventsOfInterest.subList(SIZE_LIMIT
|
|
||||||
* subListCount, SIZE_LIMIT
|
|
||||||
* subListCount + lastListSize));
|
|
||||||
if (!notification.getEvent().isEmpty()) {
|
|
||||||
sendNotification(listener, notification,
|
|
||||||
listener.address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
if (lastListSize > 0) {
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
NotificationType notification = getNotification(
|
||||||
"Unable to determine notification destinations.", e);
|
subscription, listener.address, objectsOfInterest,
|
||||||
|
eventsOfInterest.subList(SIZE_LIMIT * subListCount,
|
||||||
|
SIZE_LIMIT * subListCount + lastListSize));
|
||||||
|
if (!notification.getEvent().isEmpty()) {
|
||||||
|
sendNotification(listener, notification,
|
||||||
|
listener.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,11 +310,7 @@ public class RegistrySubscriptionManager implements
|
||||||
if (subscriptionShouldRun(sub)) {
|
if (subscriptionShouldRun(sub)) {
|
||||||
try {
|
try {
|
||||||
processSubscription(subNotificationListener);
|
processSubscription(subNotificationListener);
|
||||||
} catch (EbxmlRegistryException e) {
|
} catch (Throwable e) {
|
||||||
statusHandler.error(
|
|
||||||
"Errors occurred while processing subscription ["
|
|
||||||
+ sub.getId() + "]", e);
|
|
||||||
} catch (MsgRegistryException e) {
|
|
||||||
statusHandler.error(
|
statusHandler.error(
|
||||||
"Errors occurred while processing subscription ["
|
"Errors occurred while processing subscription ["
|
||||||
+ sub.getId() + "]", e);
|
+ sub.getId() + "]", e);
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* 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.registry.ebxml.services.rest;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager;
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.RemoveObjectsRequest;
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DeliveryInfoType;
|
||||||
|
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.SubscriptionType;
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryResponseStatus;
|
||||||
|
import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryResponseType;
|
||||||
|
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.registry.RegistryException;
|
||||||
|
import com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService;
|
||||||
|
import com.raytheon.uf.common.registry.services.rest.response.RestCollectionResponse;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Implementation of the registry data access service interface
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 7/29/2013 2191 bphillip Initial implementation
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bphillip
|
||||||
|
* @version 1
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public class RegistryDataAccessService implements IRegistryDataAccessService {
|
||||||
|
|
||||||
|
/** The logger */
|
||||||
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(RegistryDataAccessService.class);
|
||||||
|
|
||||||
|
/** Data access object for registry objects */
|
||||||
|
private RegistryObjectDao registryObjectDao;
|
||||||
|
|
||||||
|
/** Lifecyclemanager */
|
||||||
|
private LifecycleManager lcm;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/rest/dataAccess/getRegistryObjectIds/{objectType}")
|
||||||
|
public RestCollectionResponse<String> getRegistryObjectIdsOfType(
|
||||||
|
@PathParam("objectType") String objectType) {
|
||||||
|
statusHandler.info("Getting registry object ids of type [" + objectType
|
||||||
|
+ "]...");
|
||||||
|
RestCollectionResponse<String> response = new RestCollectionResponse<String>();
|
||||||
|
response.setPayload(registryObjectDao
|
||||||
|
.getRegistryObjectIdsOfType(objectType));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/rest/dataAccess/removeSubscriptionsFor/{siteId}")
|
||||||
|
public void removeSubscriptionsForSite(@PathParam("siteId") String siteId) {
|
||||||
|
statusHandler.info("Removing subscriptions for: " + siteId);
|
||||||
|
List<SubscriptionType> subscriptions = registryObjectDao
|
||||||
|
.executeHQLQuery(
|
||||||
|
"from SubscriptionType sub where sub.owner=:siteId",
|
||||||
|
"siteId", siteId);
|
||||||
|
if (subscriptions.isEmpty()) {
|
||||||
|
statusHandler.info("No subscriptions present for site: " + siteId);
|
||||||
|
} else {
|
||||||
|
List<Integer> deliveryInfoKeys = new ArrayList<Integer>();
|
||||||
|
ObjectRefListType refList = new ObjectRefListType();
|
||||||
|
for (SubscriptionType sub : subscriptions) {
|
||||||
|
refList.getObjectRef().add(new ObjectRefType(sub.getId()));
|
||||||
|
for (DeliveryInfoType deliveryInfo : sub.getDeliveryInfo()) {
|
||||||
|
deliveryInfoKeys.add(deliveryInfo.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RemoveObjectsRequest removeRequest = new RemoveObjectsRequest();
|
||||||
|
removeRequest.setId("Remote subscription removal request for "
|
||||||
|
+ siteId);
|
||||||
|
removeRequest.setComment("Removal of remote subscriptions for "
|
||||||
|
+ siteId);
|
||||||
|
removeRequest.setObjectRefList(refList);
|
||||||
|
try {
|
||||||
|
RegistryResponseType response = lcm
|
||||||
|
.removeObjects(removeRequest);
|
||||||
|
if (response.getStatus().equals(RegistryResponseStatus.SUCCESS)) {
|
||||||
|
registryObjectDao
|
||||||
|
.executeHQLStatement(
|
||||||
|
"DELETE FROM DeliveryInfoType deliveryInfo where deliveryInfo.key in (:keys)",
|
||||||
|
"keys", deliveryInfoKeys);
|
||||||
|
statusHandler
|
||||||
|
.info("Successfully removed subscriptions for site "
|
||||||
|
+ siteId);
|
||||||
|
} else {
|
||||||
|
statusHandler
|
||||||
|
.info("Failed to remove subscriptions for site "
|
||||||
|
+ siteId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RegistryException(
|
||||||
|
"Error removing subscriptions for site " + siteId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegistryObjectDao(RegistryObjectDao registryObjectDao) {
|
||||||
|
this.registryObjectDao = registryObjectDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLcm(LifecycleManager lcm) {
|
||||||
|
this.lcm = lcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -88,6 +88,7 @@
|
||||||
<!-- REST Service Definitions -->
|
<!-- REST Service Definitions -->
|
||||||
<jaxrs:server id="registryRestServices" address="/">
|
<jaxrs:server id="registryRestServices" address="/">
|
||||||
<jaxrs:serviceBeans>
|
<jaxrs:serviceBeans>
|
||||||
|
<ref bean="registryDataAccessService"/>
|
||||||
<ref bean="registryAvailabilityService" />
|
<ref bean="registryAvailabilityService" />
|
||||||
<ref bean="registryObjectsRestService" />
|
<ref bean="registryObjectsRestService" />
|
||||||
<ref bean="repositoryObjectsRestService" />
|
<ref bean="repositoryObjectsRestService" />
|
||||||
|
|
Loading…
Add table
Reference in a new issue