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.handler,
|
||||
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",
|
||||
com.raytheon.uf.common.serialization.comm;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.raytheon.uf.common.registry.constants.RegistryAvailability;
|
||||
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.IRepositoryItemsRestService;
|
||||
import com.raytheon.uf.common.serialization.SerializationUtil;
|
||||
|
@ -50,6 +51,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 5/21/2013 2022 bphillip Initial implementation
|
||||
* 7/29/2013 2191 bphillip Implemented registry data access service
|
||||
* </pre>
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
@ -99,11 +111,9 @@ public class RegistryRESTServices {
|
|||
* @param baseURL
|
||||
* The base URL of the registry
|
||||
* @return The service implementation
|
||||
* @throws RegistryServiceException
|
||||
* If an invalid URL is provided
|
||||
*/
|
||||
public static IRegistryObjectsRestService getRegistryObjectService(
|
||||
String baseURL) throws RegistryServiceException {
|
||||
String baseURL) {
|
||||
try {
|
||||
return registryObjectServiceMap.get(baseURL);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -124,8 +134,6 @@ public class RegistryRESTServices {
|
|||
* @return The object
|
||||
* @throws JAXBException
|
||||
* If errors occur while serializing the object
|
||||
* @throws RegistryServiceException
|
||||
* If an invalid URL is provided
|
||||
*/
|
||||
public static <T extends RegistryObjectType> T getRegistryObject(
|
||||
Class<T> expectedType, String baseURL, String objectId)
|
||||
|
@ -140,11 +148,9 @@ public class RegistryRESTServices {
|
|||
* @param baseURL
|
||||
* The base URL of the registry
|
||||
* @return The service implementation
|
||||
* @throws RegistryServiceException
|
||||
* If an invalid URL is provided
|
||||
*/
|
||||
public static IRepositoryItemsRestService getRepositoryItemService(
|
||||
String baseURL) throws RegistryServiceException {
|
||||
String baseURL) {
|
||||
try {
|
||||
return repositoryItemServiceMap.get(baseURL);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -161,11 +167,9 @@ public class RegistryRESTServices {
|
|||
* @param repositoryItemId
|
||||
* The id of the object
|
||||
* @return The repository item
|
||||
* @throws RegistryServiceException
|
||||
* If an invalid URL is provided
|
||||
*/
|
||||
public static byte[] getRepositoryItem(String baseURL,
|
||||
String repositoryItemId) throws RegistryServiceException {
|
||||
String repositoryItemId) {
|
||||
return getRepositoryItemService(baseURL).getRepositoryItem(
|
||||
repositoryItemId);
|
||||
}
|
||||
|
@ -176,11 +180,9 @@ public class RegistryRESTServices {
|
|||
* @param baseURL
|
||||
* The base URL of the registry
|
||||
* @return THe registry available service implementation
|
||||
* @throws RegistryServiceException
|
||||
* If an invalid URL is provided
|
||||
*/
|
||||
public static IRegistryAvailableRestService getRegistryAvailableService(
|
||||
String baseURL) throws RegistryServiceException {
|
||||
String baseURL) {
|
||||
try {
|
||||
return registryAvailabilityServiceMap.get(baseURL);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -204,8 +206,25 @@ public class RegistryRESTServices {
|
|||
} catch (Throwable t) {
|
||||
statusHandler.error(
|
||||
"Registry at [" + baseURL + "] not available: ",
|
||||
t.getLocalizedMessage());
|
||||
t.getMessage());
|
||||
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
|
||||
* 4/9/2013 1802 bphillip Added null check
|
||||
* 7/29/2013 2191 bphillip Fixed equals method
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -77,7 +78,11 @@ public class XMLGregorianCalendarType implements UserType {
|
|||
public boolean equals(Object x, Object y) throws HibernateException {
|
||||
if (x instanceof XMLGregorianCalendar
|
||||
&& y instanceof XMLGregorianCalendar) {
|
||||
return x.equals(y);
|
||||
try {
|
||||
return x.equals(y);
|
||||
} catch (ClassCastException e) {
|
||||
return y.equals(x);
|
||||
}
|
||||
} else {
|
||||
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",
|
||||
org.springframework;bundle-version="2.5.6",
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean id="FederatedRegistryMonitor" class="com.raytheon.uf.edex.datadelivery.registry.availability.FederatedRegistryMonitor">
|
||||
<constructor-arg ref="metadataTxTemplate"/>
|
||||
<constructor-arg ref="registryObjectDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="RegistryReplicationManager" class="com.raytheon.uf.edex.datadelivery.registry.replication.RegistryReplicationManager">
|
||||
<constructor-arg ref="ebxmlSubscriptionsEnabled"/>
|
||||
<constructor-arg ref="replicationConfigFileName"/>
|
||||
<constructor-arg ref="registryObjectDao"/>
|
||||
<constructor-arg ref="FederatedRegistryMonitor"/>
|
||||
<constructor-arg ref="metadataTxTemplate"/>
|
||||
</bean>
|
||||
|
||||
<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 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.FederationType;
|
||||
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.serialization.SerializationException;
|
||||
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
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 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>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class NcfRegistryFederationManager extends RegistryFederationManager {
|
||||
public class NcfRegistryFederationManager extends RegistryFederationManager
|
||||
implements RegistryInitializedListener {
|
||||
|
||||
/**
|
||||
* Creates a new NcfRegistryFederationManager
|
||||
|
@ -103,7 +107,12 @@ public class NcfRegistryFederationManager extends RegistryFederationManager {
|
|||
objects.add(primaryContact);
|
||||
objects.add(federationAssociation);
|
||||
submitObjects(objects);
|
||||
replicationManager.submitRemoteSubscriptions(registry.getBaseURL());
|
||||
replicationManager.submitRemoteSubscriptions(registry);
|
||||
try {
|
||||
replicationManager.checkDownTime();
|
||||
} catch (MsgRegistryException e) {
|
||||
throw new EbxmlRegistryException("Error checkint down time!", e);
|
||||
}
|
||||
} else {
|
||||
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.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
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.RegistryObjectDao;
|
||||
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
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 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>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -71,13 +72,18 @@ import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
|||
*/
|
||||
@Service
|
||||
@Transactional
|
||||
public abstract class RegistryFederationManager implements
|
||||
RegistryInitializedListener {
|
||||
public abstract class RegistryFederationManager {
|
||||
|
||||
/** The logger instance */
|
||||
protected static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(RegistryFederationManager.class);
|
||||
|
||||
/**
|
||||
* The scheduler service used for registering this registry with the
|
||||
* federation
|
||||
*/
|
||||
protected ScheduledExecutorService scheduler;
|
||||
|
||||
/** The federation identifier */
|
||||
public static final String FEDERATION_ID = "Registry Federation";
|
||||
|
||||
|
@ -174,6 +180,7 @@ public abstract class RegistryFederationManager implements
|
|||
+ " Federation Membership Association");
|
||||
association.setLid(association.getId());
|
||||
association.setObjectType(RegistryObjectTypes.ASSOCIATION);
|
||||
association.setOwner(federationProperties.getSiteIdentifier());
|
||||
association.setType(AssociationTypes.HAS_FEDERATION_MEMBER);
|
||||
association.setStatus(StatusTypes.APPROVED);
|
||||
association.setName(RegistryUtil.getInternationalString(registry
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
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 org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
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.RegistrySOAPServices;
|
||||
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.init.RegistryInitializedListener;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -69,6 +68,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 5/22/2013 1707 bphillip Initial implementation
|
||||
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -76,17 +76,12 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|||
*/
|
||||
@Service
|
||||
@Transactional
|
||||
public class WfoRegistryFederationManager extends RegistryFederationManager {
|
||||
public class WfoRegistryFederationManager extends RegistryFederationManager
|
||||
implements RegistryInitializedListener {
|
||||
|
||||
/** The address of the NCF */
|
||||
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 */
|
||||
private TransactionTemplate txTemplate;
|
||||
|
||||
|
@ -173,7 +168,7 @@ public class WfoRegistryFederationManager extends RegistryFederationManager {
|
|||
objects.add(federationAssociation);
|
||||
submitObjects(objects);
|
||||
replicationManager.setSubscriptionProcessingEnabled(true);
|
||||
replicationManager.submitRemoteSubscriptions(registry.getBaseURL());
|
||||
replicationManager.submitRemoteSubscriptions(registry);
|
||||
}
|
||||
|
||||
protected FederationType getFederation() throws EbxmlRegistryException {
|
||||
|
@ -222,7 +217,7 @@ public class WfoRegistryFederationManager extends RegistryFederationManager {
|
|||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
private class RegisterWithFederationTask implements Runnable {
|
||||
private class RegisterWithFederationTask extends RunnableWithTransaction {
|
||||
|
||||
/**
|
||||
* Denotes if this task has successfully registered this registry with
|
||||
|
@ -234,44 +229,39 @@ public class WfoRegistryFederationManager extends RegistryFederationManager {
|
|||
* Creates a new RegisterwithFederationTask
|
||||
*/
|
||||
public RegisterWithFederationTask() {
|
||||
super(txTemplate);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void runWithTransaction() {
|
||||
if (!success) {
|
||||
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(
|
||||
TransactionStatus status) {
|
||||
try {
|
||||
try {
|
||||
if (RegistryRESTServices
|
||||
.isRegistryAvailable(ncfAddress)) {
|
||||
statusHandler
|
||||
.info("NCF Registry is available. Attempting to join federation...");
|
||||
} else {
|
||||
statusHandler
|
||||
.error("NCF is currently unreachable. Local registry is unable to join the federation at this time. Retrying in 10 seconds...");
|
||||
replicationManager
|
||||
.setSubscriptionProcessingEnabled(false);
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
registerWithFederation();
|
||||
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);
|
||||
try {
|
||||
try {
|
||||
if (RegistryRESTServices
|
||||
.isRegistryAvailable(ncfAddress)) {
|
||||
statusHandler
|
||||
.info("NCF Registry is available. Attempting to join federation...");
|
||||
} else {
|
||||
statusHandler
|
||||
.error("NCF is currently unreachable. Local registry is unable to join the federation at this time. Retrying in 10 seconds...");
|
||||
replicationManager
|
||||
.setSubscriptionProcessingEnabled(false);
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
registerWithFederation();
|
||||
replicationManager.checkDownTime();
|
||||
success = true;
|
||||
} catch (EbxmlRegistryException e) {
|
||||
statusHandler.error(
|
||||
"Error registering with federation", e);
|
||||
success = false;
|
||||
}
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(
|
||||
"Error initializing EBXML database!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
@ -35,17 +40,23 @@ import javax.xml.transform.dom.DOMSource;
|
|||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
|
||||
|
||||
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.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.QueryType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.StringValueType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.VersionInfoType;
|
||||
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -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.Namespaces;
|
||||
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.StatusTypes;
|
||||
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.status.IUFStatusHandler;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
|
@ -81,6 +98,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* 4/24/2013 1675 bphillip Initial implementation
|
||||
* 6/4/2013 1707 bphillip Changed to use new NotificationServer objects
|
||||
* 7/29/2013 2191 bphillip Implemented registry sync for registries that have been down for an extended period of time
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -92,12 +110,21 @@ public class RegistryReplicationManager {
|
|||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(RegistryReplicationManager.class);
|
||||
|
||||
private FederatedRegistryMonitor federatedRegistryMonitor;
|
||||
|
||||
private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_DAY
|
||||
* 2 - TimeUtil.MILLIS_PER_HOUR;
|
||||
|
||||
/** Scheduler service for monitoring subscription submission tasks */
|
||||
private ScheduledExecutorService scheduler;
|
||||
|
||||
/** The servers that we are subscribing to */
|
||||
private NotificationServers servers;
|
||||
|
||||
private RegistryObjectDao dao;
|
||||
|
||||
private TransactionTemplate txTemplate;
|
||||
|
||||
/**
|
||||
* The JAXBManager instance for marshalling/unmarshalling objects
|
||||
*/
|
||||
|
@ -127,10 +154,15 @@ public class RegistryReplicationManager {
|
|||
* @throws SerializationException
|
||||
*/
|
||||
public RegistryReplicationManager(boolean subscriptionProcessingEnabled,
|
||||
String notificationServerConfigFileName) throws JAXBException,
|
||||
String notificationServerConfigFileName, RegistryObjectDao dao,
|
||||
FederatedRegistryMonitor availabilityMonitor,
|
||||
TransactionTemplate txTemplate) throws JAXBException,
|
||||
SerializationException {
|
||||
this.subscriptionProcessingEnabled = subscriptionProcessingEnabled;
|
||||
this.replicationConfigFileName = notificationServerConfigFileName;
|
||||
this.dao = dao;
|
||||
this.txTemplate = txTemplate;
|
||||
this.federatedRegistryMonitor = availabilityMonitor;
|
||||
jaxbManager = new JAXBManager(NotificationServers.class,
|
||||
SubscriptionType.class);
|
||||
File notificationServerConfigFile = PathManagerFactory.getPathManager()
|
||||
|
@ -147,6 +179,201 @@ public class RegistryReplicationManager {
|
|||
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
|
||||
* types to subscribe to for registry replication
|
||||
|
@ -166,7 +393,7 @@ public class RegistryReplicationManager {
|
|||
* @param baseURL
|
||||
* The url of the registry to send the subscriptions to
|
||||
*/
|
||||
public void submitRemoteSubscriptions(String baseURL) {
|
||||
public void submitRemoteSubscriptions(RegistryType registry) {
|
||||
|
||||
if (subscriptionProcessingEnabled) {
|
||||
statusHandler.info("Registry Replication is enabled.");
|
||||
|
@ -187,7 +414,7 @@ public class RegistryReplicationManager {
|
|||
statusHandler
|
||||
.info("Submitting subscriptions to registry replication servers...");
|
||||
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
|
||||
*/
|
||||
private void scheduleSubscriptionSubmission(
|
||||
NotificationHostConfiguration config, String baseURL) {
|
||||
NotificationHostConfiguration config, RegistryType registry) {
|
||||
final SubmitSubscriptionTask submitSubscriptionTask = new SubmitSubscriptionTask(
|
||||
config, baseURL);
|
||||
config, registry);
|
||||
final ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
|
||||
submitSubscriptionTask, 0, 10, TimeUnit.SECONDS);
|
||||
scheduler.schedule(new Runnable() {
|
||||
|
@ -227,7 +454,7 @@ public class RegistryReplicationManager {
|
|||
* replication subscriptions to
|
||||
*/
|
||||
private void submitSubscriptionsToHost(
|
||||
NotificationHostConfiguration config, String localRegistryBaseURL) {
|
||||
NotificationHostConfiguration config, RegistryType localRegistry) {
|
||||
statusHandler
|
||||
.info("Generating registry replication subscriptions for registry at ["
|
||||
+ config.getRegistrySiteName()
|
||||
|
@ -239,7 +466,7 @@ public class RegistryReplicationManager {
|
|||
SubscriptionType subscription;
|
||||
try {
|
||||
subscription = createSubscription(config.getRegistryBaseURL(),
|
||||
objectType, localRegistryBaseURL);
|
||||
objectType, localRegistry);
|
||||
} catch (Exception e) {
|
||||
throw new RegistryException("Error creating subscription", e);
|
||||
}
|
||||
|
@ -267,10 +494,10 @@ public class RegistryReplicationManager {
|
|||
* If errors occur while creating the subscription object
|
||||
*/
|
||||
private SubscriptionType createSubscription(String host, String objectType,
|
||||
String localRegistryBaseURL) throws Exception {
|
||||
RegistryType registry) throws Exception {
|
||||
// Set normal registry object fields
|
||||
String subscriptionDetail = "Replication Subscription for ["
|
||||
+ objectType + "] objects for server [" + localRegistryBaseURL
|
||||
+ objectType + "] objects for server [" + registry.getBaseURL()
|
||||
+ "]";
|
||||
SubscriptionType sub = new SubscriptionType();
|
||||
sub.setId(subscriptionDetail);
|
||||
|
@ -283,7 +510,7 @@ public class RegistryReplicationManager {
|
|||
version.setVersionName("1");
|
||||
version.setUserVersionName("1");
|
||||
sub.setVersionInfo(version);
|
||||
sub.setOwner("Subscription Owner");
|
||||
sub.setOwner(registry.getOwner());
|
||||
sub.setStatus(StatusTypes.APPROVED);
|
||||
|
||||
sub.setStartTime(EbxmlObjectUtil.getTimeAsXMLGregorianCalendar(0));
|
||||
|
@ -304,7 +531,7 @@ public class RegistryReplicationManager {
|
|||
String endpointType = DeliveryMethodTypes.SOAP;
|
||||
W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
|
||||
builder.address(RegistrySOAPServices.getNotificationListenerServiceUrl(
|
||||
localRegistryBaseURL).toString());
|
||||
registry.getBaseURL()).toString());
|
||||
W3CEndpointReference ref = builder.build();
|
||||
DOMResult dom = new DOMResult();
|
||||
ref.writeTo(dom);
|
||||
|
@ -355,8 +582,8 @@ public class RegistryReplicationManager {
|
|||
/** The server configuration */
|
||||
private NotificationHostConfiguration config;
|
||||
|
||||
/** The base URL of the remote registry */
|
||||
private String baseURL;
|
||||
/** The remote registry */
|
||||
private RegistryType registry;
|
||||
|
||||
/**
|
||||
* Creates a new SubmitSubscriptionTask
|
||||
|
@ -367,15 +594,16 @@ public class RegistryReplicationManager {
|
|||
* The base URL of the remote registry
|
||||
*/
|
||||
public SubmitSubscriptionTask(NotificationHostConfiguration config,
|
||||
String baseURL) {
|
||||
RegistryType registry) {
|
||||
this.config = config;
|
||||
this.baseURL = baseURL;
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!success) {
|
||||
String remoteRegistryBaseURL = config.getRegistryBaseURL();
|
||||
final String remoteRegistryBaseURL = config
|
||||
.getRegistryBaseURL();
|
||||
statusHandler.info("Checking if remote registry at ["
|
||||
+ remoteRegistryBaseURL + "] is available...");
|
||||
|
||||
|
@ -390,7 +618,25 @@ public class RegistryReplicationManager {
|
|||
return;
|
||||
}
|
||||
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;
|
||||
} catch (Exception e) {
|
||||
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">
|
||||
<constructor-arg ref="slotTypeDao" />
|
||||
<constructor-arg ref="AuditableEventTypeDao" />
|
||||
<constructor-arg ref="metadataTxTemplate"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
<property name="partyDao" ref="partyDao" />
|
||||
<property name="webUtil" ref="RegistryWebUtil" />
|
||||
</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"
|
||||
class="com.raytheon.uf.edex.registry.ebxml.services.rest.RegistryAvailableRestService" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# The period which registry subscriptions are processed
|
||||
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
|
||||
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
|
||||
* Apr 17, 2013 1914 djohnson Use strategy for subscription processing.
|
||||
* 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>
|
||||
*
|
||||
|
@ -94,9 +95,6 @@ public class AuditableEventTypeDao extends
|
|||
/** Cutoff parameter for the query to get the expired events */
|
||||
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 */
|
||||
private static final String GET_EXPIRED_EVENTS_QUERY = "FROM AuditableEventType event where event.timestamp < :"
|
||||
+ 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
|
||||
* If errors occur purging auditable events
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public void deleteExpiredEvents() throws EbxmlRegistryException {
|
||||
public List<AuditableEventType> getExpiredEvents(int limit)
|
||||
throws EbxmlRegistryException {
|
||||
Calendar cutoffTime = TimeUtil.newGmtCalendar();
|
||||
cutoffTime.add(Calendar.HOUR_OF_DAY, -AUDITABLE_EVENT_RETENTION_TIME);
|
||||
List<AuditableEventType> expiredEvents = this.executeHQLQuery(
|
||||
GET_EXPIRED_EVENTS_QUERY, GET_EXPIRED_EVENTS_QUERY_BATCH_SIZE,
|
||||
return this.executeHQLQuery(GET_EXPIRED_EVENTS_QUERY, limit,
|
||||
GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER, EbxmlObjectUtil
|
||||
.getTimeAsXMLGregorianCalendar(cutoffTime
|
||||
.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 com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
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
|
||||
* 4/9/2013 1802 bphillip Removed exception catching
|
||||
* 6/4/2013 2022 bphillip Added delete objects of type method
|
||||
* 7/29/2013 2191 bphillip Added new methods to support registry synchronization
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -48,25 +48,31 @@ public class RegistryObjectDao extends
|
|||
RegistryObjectTypeDao<RegistryObjectType> {
|
||||
|
||||
/** 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() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes objects of a specific type from the registry
|
||||
* Gets the object ids of objects of the given object type
|
||||
*
|
||||
* @param objectType
|
||||
* The object type to delete
|
||||
* @throws DataAccessLayerException
|
||||
* If errors occur on the delete
|
||||
* The object type to get the ids for
|
||||
* @return The list of object ids of objects of the given type
|
||||
*/
|
||||
public void deleteObjectsOfType(String objectType)
|
||||
throws DataAccessLayerException {
|
||||
int objectsDeleted = this.executeHQLStatement(DELETE_OBJECT_TYPE,
|
||||
"objectType", objectType);
|
||||
statusHandler.info(objectsDeleted + " objects of type " + objectType
|
||||
+ " deleted from registry");
|
||||
public List<String> getRegistryObjectIdsOfType(String objectType) {
|
||||
return this.executeHQLQuery(GET_IDS_BY_OBJECT_TYPE, "objectType",
|
||||
objectType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.raytheon.uf.edex.database.dao.SessionManagedDao;
|
||||
|
||||
/**
|
||||
|
@ -39,6 +36,7 @@ import com.raytheon.uf.edex.database.dao.SessionManagedDao;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 7/11/2013 1707 bphillip Initial implementation
|
||||
* 7/29/2013 2191 bphillip Modified method to get orphaned slots
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -71,35 +69,34 @@ public class SlotTypeDao extends SessionManagedDao<Integer, SlotType> {
|
|||
+ "select child_slot_key from ebxml.emailaddress_slot "
|
||||
+ "UNION "
|
||||
+ "select child_slot_key from ebxml.postaladdress_slot "
|
||||
+ ")";
|
||||
|
||||
/** 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 + ")";
|
||||
+ ") limit %s";
|
||||
|
||||
@Override
|
||||
protected Class<SlotType> getEntityClass() {
|
||||
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")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public void deleteOrphanedSlots() {
|
||||
List<Integer> orphanedSlotIds = this.getSessionFactory()
|
||||
.getCurrentSession().createSQLQuery(ORPHANED_SLOT_QUERY).list();
|
||||
if (!orphanedSlotIds.isEmpty()) {
|
||||
public List<Integer> getOrphanedSlotIds(int limit) {
|
||||
return this
|
||||
.getSessionFactory()
|
||||
.getCurrentSession()
|
||||
.createSQLQuery(
|
||||
String.format(ORPHANED_SLOT_QUERY,
|
||||
String.valueOf(limit))).list();
|
||||
}
|
||||
|
||||
List<SlotType> slots = this.executeHQLQuery(GET_BY_ID_QUERY,
|
||||
GET_BY_ID_QUERY_BATCH_SIZE, GET_BY_ID_QUERY_KEYS_PARAMETER,
|
||||
orphanedSlotIds);
|
||||
statusHandler.info("Removing " + orphanedSlotIds.size()
|
||||
+ " orphaned slots...");
|
||||
this.deleteAll(slots);
|
||||
public void deleteBySlotId(Integer id) {
|
||||
SlotType slot = this.getById(id);
|
||||
if (slot != null) {
|
||||
this.template.delete(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,22 @@
|
|||
**/
|
||||
package com.raytheon.uf.edex.registry.ebxml.services;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AuditableEventType;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.edex.database.RunnableWithTransaction;
|
||||
import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao;
|
||||
import com.raytheon.uf.edex.registry.ebxml.dao.SlotTypeDao;
|
||||
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
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 7/11/2013 1707 bphillip Initial implementation
|
||||
* 7/29/2013 2191 bphillip Added executors to remove orphaned slots and expired events
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
@Service
|
||||
@Transactional
|
||||
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 */
|
||||
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 */
|
||||
private SlotTypeDao slotDao;
|
||||
|
||||
/** Data access object for AuditableEventType */
|
||||
private AuditableEventTypeDao eventDao;
|
||||
|
||||
private static final int QUEUE_MAX_SIZE = 500;
|
||||
|
||||
/**
|
||||
* Creates a new GarbageCollector object
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public RegistryGarbageCollector(SlotTypeDao slotDao,
|
||||
AuditableEventTypeDao eventDao) {
|
||||
AuditableEventTypeDao eventDao, TransactionTemplate txTemplate) {
|
||||
this();
|
||||
this.slotDao = slotDao;
|
||||
this.eventDao = eventDao;
|
||||
this.txTemplate = txTemplate;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the registry by removing unused and/or orphaned objects
|
||||
*/
|
||||
public void gc() throws EbxmlRegistryException {
|
||||
public void gc() {
|
||||
|
||||
if (!running.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
eventDao.deleteExpiredEvents();
|
||||
slotDao.deleteOrphanedSlots();
|
||||
purgeOrphanedSlots();
|
||||
purgeExpiredEvents();
|
||||
} catch (EbxmlRegistryException e) {
|
||||
statusHandler.error("Error purging auditable events!", e);
|
||||
} finally {
|
||||
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.ClassificationNodeType;
|
||||
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.QueryType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||
|
@ -329,7 +328,8 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
statusHandler
|
||||
.info("Client has selected to check object references before submitting objects.");
|
||||
ValidateObjectsRequest validateObjectsRequest = new ValidateObjectsRequest();
|
||||
validateObjectsRequest.setOriginalObjects(request.getRegistryObjectList());
|
||||
validateObjectsRequest.setOriginalObjects(request
|
||||
.getRegistryObjectList());
|
||||
|
||||
// Uses the validation service directly, not going through the
|
||||
// web-service client interface
|
||||
|
@ -338,8 +338,10 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
EbxmlObjectUtil.spiObjectFactory
|
||||
.createValidateObjectsResponse());
|
||||
|
||||
final List<RegistryExceptionType> validationExceptions = validationResponse.getException();
|
||||
final List<RegistryExceptionType> responseExceptions = response.getException();
|
||||
final List<RegistryExceptionType> validationExceptions = validationResponse
|
||||
.getException();
|
||||
final List<RegistryExceptionType> responseExceptions = response
|
||||
.getException();
|
||||
|
||||
if (!validationExceptions.isEmpty()) {
|
||||
// Only care about unresolved references
|
||||
|
@ -636,7 +638,7 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
}
|
||||
|
||||
private void checkReplica(SubmitObjectsRequest request,
|
||||
ExtensibleObjectType object1, ExtensibleObjectType object2)
|
||||
RegistryObjectType object1, RegistryObjectType object2)
|
||||
throws MsgRegistryException {
|
||||
boolean fromNotification = request
|
||||
.getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME) != null;
|
||||
|
@ -645,7 +647,11 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
String object2Home = object2
|
||||
.getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME);
|
||||
|
||||
if (object1.getOwner().equals(object2.getOwner())) {
|
||||
return;
|
||||
}
|
||||
if (fromNotification) {
|
||||
|
||||
if (object1Home != null && object2Home == null) {
|
||||
throw EbxmlExceptionUtil.createMsgRegistryException(
|
||||
"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.status.IUFStatusHandler;
|
||||
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.NotificationTypeDao;
|
||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||
|
@ -164,39 +163,32 @@ public class RegistryNotificationManager {
|
|||
subscription, objectsOfInterest);
|
||||
|
||||
if (!eventsOfInterest.isEmpty()) {
|
||||
try {
|
||||
for (NotificationListenerWrapper listener : listeners) {
|
||||
int subListCount = eventsOfInterest.size() / SIZE_LIMIT;
|
||||
int lastListSize = eventsOfInterest.size() % SIZE_LIMIT;
|
||||
for (int i = 0; i < subListCount; i++) {
|
||||
NotificationType notification = getNotification(
|
||||
subscription, listener.address,
|
||||
objectsOfInterest, eventsOfInterest.subList(
|
||||
SIZE_LIMIT * i, SIZE_LIMIT * i
|
||||
+ SIZE_LIMIT));
|
||||
if (!notification.getEvent().isEmpty()) {
|
||||
sendNotification(listener, notification,
|
||||
listener.address);
|
||||
}
|
||||
for (NotificationListenerWrapper listener : listeners) {
|
||||
int subListCount = eventsOfInterest.size() / SIZE_LIMIT;
|
||||
int lastListSize = eventsOfInterest.size() % SIZE_LIMIT;
|
||||
for (int i = 0; i < subListCount; i++) {
|
||||
NotificationType notification = getNotification(
|
||||
subscription,
|
||||
listener.address,
|
||||
objectsOfInterest,
|
||||
eventsOfInterest.subList(SIZE_LIMIT * i, SIZE_LIMIT
|
||||
* i + SIZE_LIMIT));
|
||||
if (!notification.getEvent().isEmpty()) {
|
||||
sendNotification(listener, notification,
|
||||
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) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Unable to determine notification destinations.", e);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -310,11 +310,7 @@ public class RegistrySubscriptionManager implements
|
|||
if (subscriptionShouldRun(sub)) {
|
||||
try {
|
||||
processSubscription(subNotificationListener);
|
||||
} catch (EbxmlRegistryException e) {
|
||||
statusHandler.error(
|
||||
"Errors occurred while processing subscription ["
|
||||
+ sub.getId() + "]", e);
|
||||
} catch (MsgRegistryException e) {
|
||||
} catch (Throwable e) {
|
||||
statusHandler.error(
|
||||
"Errors occurred while processing subscription ["
|
||||
+ 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 -->
|
||||
<jaxrs:server id="registryRestServices" address="/">
|
||||
<jaxrs:serviceBeans>
|
||||
<ref bean="registryDataAccessService"/>
|
||||
<ref bean="registryAvailabilityService" />
|
||||
<ref bean="registryObjectsRestService" />
|
||||
<ref bean="repositoryObjectsRestService" />
|
||||
|
|
Loading…
Add table
Reference in a new issue