From 026820d51381dcc2842749f80904ce864aeac5f5 Mon Sep 17 00:00:00 2001 From: Benjamin Phillippe Date: Fri, 20 Sep 2013 10:13:09 -0500 Subject: [PATCH] Issue #2385 Add capability to backup/restore data delivery subscriptions Change-Id: I281dcf3259f3db50feabef40574bdb4487c95c7e Former-commit-id: 1d2b59c0a211b3e19cf8ef1382bb3a34897ce80b [formerly 7eb5c27fcbcd4fb52e9776e5ed2e6f16248922e1] Former-commit-id: 344dd71813db818f94dee37eefc4f5f515b5a56d --- .../rest/IRegistryDataAccessService.java | 72 +++++ .../rest/RegistryDataAccessService.java | 245 ++++++++++++++++++ .../web/RegistrySubscriptionBackup.html | 136 ++++++++++ 3 files changed, 453 insertions(+) create mode 100644 edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/RegistrySubscriptionBackup.html diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/rest/IRegistryDataAccessService.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/rest/IRegistryDataAccessService.java index f09ec837b9..35f22fe369 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/rest/IRegistryDataAccessService.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/rest/IRegistryDataAccessService.java @@ -22,6 +22,7 @@ package com.raytheon.uf.common.registry.services.rest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.xml.bind.JAXBException; import com.raytheon.uf.common.registry.RegistryException; import com.raytheon.uf.common.registry.services.rest.response.RestCollectionResponse; @@ -37,6 +38,7 @@ import com.raytheon.uf.common.registry.services.rest.response.RestCollectionResp * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 7/29/2013 2191 bphillip Initial implementation + * 9/20/2013 2385 bphillip Added subscription backup functions * * * @author bphillip @@ -68,4 +70,74 @@ public interface IRegistryDataAccessService { @Path("/rest/dataAccess/removeSubscriptionsFor/{siteId}") public void removeSubscriptionsForSite(@PathParam("siteId") String siteId) throws RegistryException; + + /** + * Gets the subscriptions that are currently in the registry and formats + * them in HTML for viewing in a web browser + * + * @return The page containing the subscriptions + */ + @GET + @Path("/rest/dataAccess/getSubscriptions") + public String getSubscriptions(); + + /** + * + * Backs up the specified subscription to be restored at a later time + * + * @param subscriptionName + * The subscription to be backed up + * @return Status message about whether the backup was successful + * @throws JAXBException + * If marshalling/unmarshalling errors are encountered + */ + @GET + @Path("/rest/dataAccess/backupSubscription/{subscriptionName}") + public String backupSubscription( + @PathParam("subscriptionName") String subscriptionName) + throws JAXBException; + + /** + * Backs up all subscriptions currently in the registry + * + * @return Status message about whether the backup was successful + * @throws JAXBException + * If marshalling/unmarshalling errors are encountered + */ + @GET + @Path("/rest/dataAccess/backupAllSubscriptions/") + public String backupAllSubscriptions() throws JAXBException; + + /** + * Restores the specified subscription + * + * @param subscriptionName + * The name of the subscription to restore + * @return Status message about whether the backup was successful + * @throws JAXBException + */ + @GET + @Path("/rest/dataAccess/restoreSubscription/{subscriptionName}") + public String restoreSubscription( + @PathParam("subscriptionName") String subscriptionName) + throws JAXBException; + + /** + * Restores any subscriptions that were previously backed up + * + * @return Status messages relating to the success or failure of the restore + */ + @GET + @Path("/rest/dataAccess/restoreSubscriptions/") + public String restoreSubscriptions(); + + /** + * Clears the backup file directory + * + * @return Status message + */ + @GET + @Path("/rest/dataAccess/clearSubscriptionBackupFiles/") + public String clearSubscriptionBackupFiles(); + } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/rest/RegistryDataAccessService.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/rest/RegistryDataAccessService.java index 93420622a7..c5ad38babb 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/rest/RegistryDataAccessService.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/rest/RegistryDataAccessService.java @@ -19,16 +19,23 @@ **/ package com.raytheon.uf.edex.registry.ebxml.services.rest; +import java.io.File; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.xml.bind.JAXBException; import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager; +import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException; +import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode; import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.RemoveObjectsRequest; +import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest; 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.RegistryObjectListType; +import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType; import org.springframework.transaction.annotation.Transactional; @@ -36,6 +43,7 @@ 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.serialization.JAXBManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; @@ -51,6 +59,7 @@ import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 7/29/2013 2191 bphillip Initial implementation + * 9/20/2013 2385 bphillip Added subscription backup functions * * * @author bphillip @@ -63,12 +72,24 @@ public class RegistryDataAccessService implements IRegistryDataAccessService { private static final IUFStatusHandler statusHandler = UFStatus .getHandler(RegistryDataAccessService.class); + private static final File SUBSCRIPTION_BACKUP_DIR = new File( + System.getProperty("edex.home") + + "/data/registrySubscriptionBackup"); + + private static final String GET_SUBSCRIPTIONS_QUERY = "FROM RegistryObjectType obj where lower(obj.objectType) like '%subscription%' order by obj.id asc"; + /** Data access object for registry objects */ private RegistryObjectDao registryObjectDao; /** Lifecyclemanager */ private LifecycleManager lcm; + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .getRegistryObjectIdsOfType(String) + */ + @Override @GET @Path("/rest/dataAccess/getRegistryObjectIds/{objectType}") public RestCollectionResponse getRegistryObjectIdsOfType( @@ -81,6 +102,12 @@ public class RegistryDataAccessService implements IRegistryDataAccessService { return response; } + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .removeSubscriptionsForSite(String) + */ + @Override @GET @Path("/rest/dataAccess/removeSubscriptionsFor/{siteId}") public void removeSubscriptionsForSite(@PathParam("siteId") String siteId) { @@ -112,6 +139,224 @@ public class RegistryDataAccessService implements IRegistryDataAccessService { } } + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .getSubscriptions() + */ + @Override + @GET + @Path("/rest/dataAccess/getSubscriptions") + public String getSubscriptions() { + String[] slotNames = new String[] { "name", "owner", "dataSetName", + "provider", "dataSetType", "route", "active", "groupName", + "valid", "fullDataSet" }; + + StringBuilder response = new StringBuilder(); + response.append(" "); + response.append(""); + response.append(""); + for (String slotName : slotNames) { + response.append(""); + } + response.append(""); + + List subs = registryObjectDao + .executeHQLQuery(GET_SUBSCRIPTIONS_QUERY); + for (RegistryObjectType obj : subs) { + String[] values = new String[slotNames.length + 1]; + values[0] = obj.getId(); + for (int i = 0; i < slotNames.length; i++) { + values[i + 1] = String.valueOf(obj.getSlotValue(slotNames[i])); + } + response.append(""); + for (String val : values) { + response.append(""); + } + response.append(""); + } + response.append("
ID").append(slotName).append("
").append(val).append("
"); + return response.toString(); + } + + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .backupSubscription(String) + */ + @Override + @GET + @Path("/rest/dataAccess/backupSubscription/{subscriptionName}") + public String backupSubscription( + @PathParam("subscriptionName") String subscriptionName) + throws JAXBException { + StringBuilder response = new StringBuilder(); + RegistryObjectType sub = registryObjectDao.getById(subscriptionName); + + if (sub == null) { + response.append("Subscription with ID [").append(subscriptionName) + .append("] not found in registry"); + } else { + if (!SUBSCRIPTION_BACKUP_DIR.exists()) { + SUBSCRIPTION_BACKUP_DIR.mkdirs(); + } + JAXBManager jaxb = new JAXBManager(SubmitObjectsRequest.class); + String subId = sub.getId(); + File backupFile = new File(SUBSCRIPTION_BACKUP_DIR.getPath() + + File.separator + subId); + SubmitObjectsRequest submitObjectsRequest = new SubmitObjectsRequest(); + submitObjectsRequest.setCheckReferences(false); + submitObjectsRequest + .setComment("Restoring backed up subscriptions"); + submitObjectsRequest.setId("Restore subscription [" + subId + "]"); + submitObjectsRequest.setMode(Mode.CREATE_OR_REPLACE); + submitObjectsRequest + .setRegistryObjectList(new RegistryObjectListType()); + submitObjectsRequest.getRegistryObjects().add(sub); + + try { + jaxb.getJaxbContext().createMarshaller() + .marshal(submitObjectsRequest, backupFile); + } catch (JAXBException e) { + statusHandler.error("Error backing up subscription [" + subId + + "]", e); + response.append("Error backing up subscription [") + .append(subId).append("]
"); + } + response.append("Subscription [").append(subId) + .append("] successfully backed up to [") + .append(backupFile.getPath()).append("]
"); + } + return response.toString(); + } + + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .backupAllSubscriptions() + */ + @Override + @GET + @Path("/rest/dataAccess/backupAllSubscriptions/") + public String backupAllSubscriptions() throws JAXBException { + StringBuilder response = new StringBuilder(); + List subs = registryObjectDao + .executeHQLQuery(GET_SUBSCRIPTIONS_QUERY); + if (subs.isEmpty()) { + response.append("No subscriptions present to backup!"); + } else { + for (RegistryObjectType sub : subs) { + response.append(backupSubscription(sub.getId())); + } + } + return response.toString(); + } + + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .restoreSubscription(String) + */ + @Override + @GET + @Path("/rest/dataAccess/restoreSubscription/{subscriptionName}") + public String restoreSubscription( + @PathParam("subscriptionName") String subscriptionName) + throws JAXBException { + StringBuilder response = new StringBuilder(); + File subscriptionFile = new File(SUBSCRIPTION_BACKUP_DIR + + File.separator + subscriptionName); + if (subscriptionFile.exists()) { + JAXBManager jaxb = new JAXBManager(SubmitObjectsRequest.class); + SubmitObjectsRequest submitRequest = (SubmitObjectsRequest) jaxb + .getJaxbContext().createUnmarshaller() + .unmarshal(subscriptionFile); + try { + lcm.submitObjects(submitRequest); + } catch (MsgRegistryException e) { + response.append("Error restoring subscription from file [") + .append(subscriptionFile).append("] ") + .append(e.getMessage()).append("
"); + statusHandler.error("Error restoring subscription from file [" + + subscriptionFile + "]", e); + return response.toString(); + } + subscriptionFile.delete(); + response.append("Subscription successfully restored from file [") + .append(subscriptionFile).append("]
"); + } else { + response.append("No backup file exists for subscription[") + .append(subscriptionName).append("]
"); + } + + return response.toString(); + } + + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .restoreSubscriptions() + */ + @Override + @GET + @Path("/rest/dataAccess/restoreSubscriptions/") + public String restoreSubscriptions() { + StringBuilder response = new StringBuilder(); + if (SUBSCRIPTION_BACKUP_DIR.exists()) { + File[] filesToRestore = SUBSCRIPTION_BACKUP_DIR.listFiles(); + if (filesToRestore.length == 0) { + response.append("No subscriptions found to restore
"); + } else { + for (File subscription : filesToRestore) { + + try { + response.append(restoreSubscription(subscription + .getName())); + } catch (JAXBException e) { + statusHandler.error("Error restoring subscription [" + + subscription + "]", e); + response.append("Error restoring subscription [") + .append(subscription).append("] ") + .append(e.getMessage()).append("
"); + continue; + } + } + } + } else { + response.append("No subscriptions found to restore
"); + } + return response.toString(); + } + + /** + * @see + * com.raytheon.uf.common.registry.services.rest.IRegistryDataAccessService + * .clearSubscriptionBackupFiles() + */ + @GET + @Path("/rest/dataAccess/clearSubscriptionBackupFiles/") + public String clearSubscriptionBackupFiles() { + StringBuilder response = new StringBuilder(); + if (SUBSCRIPTION_BACKUP_DIR.exists()) { + File[] filesToDelete = SUBSCRIPTION_BACKUP_DIR.listFiles(); + if (filesToDelete.length == 0) { + response.append("No backup files to delete"); + } + for (File file : filesToDelete) { + if (file.delete()) { + response.append("Deleted backup file [") + .append(file.getPath()).append("]
"); + } else { + response.append("Error deleting backup file [") + .append(file.getPath()).append("]
"); + } + } + } else { + response.append("No backup files to delete"); + } + return response.toString(); + } + public void setRegistryObjectDao(RegistryObjectDao registryObjectDao) { this.registryObjectDao = registryObjectDao; } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/RegistrySubscriptionBackup.html b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/RegistrySubscriptionBackup.html new file mode 100644 index 0000000000..7c7677d1c0 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/RegistrySubscriptionBackup.html @@ -0,0 +1,136 @@ + + + + + + + + + Backup/Restore Subscriptions + + + +

BACKUP/RESTORE DATA DELIVERY SUBSCRIPTIONS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +

+

+

+
+ + + + + \ No newline at end of file