Merge "Issue #2385 Add capability to backup/restore data delivery subscriptions" into development
Former-commit-id:4893afee2d
[formerly 7693ac994d0f3f251c31e45c13301e7749d3a52a] Former-commit-id:29febe5dc5
This commit is contained in:
commit
4a838c56b5
3 changed files with 453 additions and 0 deletions
|
@ -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
|
||||
* </pre>
|
||||
*
|
||||
* @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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* </pre>
|
||||
*
|
||||
* @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<String> 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("<table border=\"1\" style=\"border-style:solid; border-width:thin\"> ");
|
||||
response.append("<tr>");
|
||||
response.append("<th>ID</th>");
|
||||
for (String slotName : slotNames) {
|
||||
response.append("<th>").append(slotName).append("</th>");
|
||||
}
|
||||
response.append("</tr>");
|
||||
|
||||
List<RegistryObjectType> 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("<tr>");
|
||||
for (String val : values) {
|
||||
response.append("<td>").append(val).append("</td>");
|
||||
}
|
||||
response.append("</tr>");
|
||||
}
|
||||
response.append("</table>");
|
||||
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("]<br>");
|
||||
}
|
||||
response.append("Subscription [").append(subId)
|
||||
.append("] successfully backed up to [")
|
||||
.append(backupFile.getPath()).append("]<br>");
|
||||
}
|
||||
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<RegistryObjectType> 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("<br>");
|
||||
statusHandler.error("Error restoring subscription from file ["
|
||||
+ subscriptionFile + "]", e);
|
||||
return response.toString();
|
||||
}
|
||||
subscriptionFile.delete();
|
||||
response.append("Subscription successfully restored from file [")
|
||||
.append(subscriptionFile).append("]<br>");
|
||||
} else {
|
||||
response.append("No backup file exists for subscription[")
|
||||
.append(subscriptionName).append("]<br>");
|
||||
}
|
||||
|
||||
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<br>");
|
||||
} 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("<br>");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
response.append("No subscriptions found to restore<br>");
|
||||
}
|
||||
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("]<br>");
|
||||
} else {
|
||||
response.append("Error deleting backup file [")
|
||||
.append(file.getPath()).append("]<br>");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
response.append("No backup files to delete");
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
public void setRegistryObjectDao(RegistryObjectDao registryObjectDao) {
|
||||
this.registryObjectDao = registryObjectDao;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<style type="text/css">
|
||||
a {font-weight:bold;}
|
||||
td {width:200px;}
|
||||
button {width:190px;}
|
||||
input{width:300px;}
|
||||
table {border:0;}
|
||||
select {width:200px;}
|
||||
body { font-family: Helvetica;
|
||||
margin-left: 75px;
|
||||
margin-right: 75px;
|
||||
background: #D3D3D3;}
|
||||
</style>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<script type="text/javascript" src='/dwr/engine.js'></script>
|
||||
<script type="text/javascript" src='/dwr/util.js'></script>
|
||||
<title>Backup/Restore Subscriptions</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h3>BACKUP/RESTORE DATA DELIVERY SUBSCRIPTIONS</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<button id="backupSubscriptionButton" onClick="backupSubscription()" >Backup Subscription</button>
|
||||
</td>
|
||||
<td>
|
||||
<input id="backupSubscriptionText" type="text"/></td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button id="backupAllSubscriptionsButton" onClick="backupAllSubscriptions()">Backup All Subscriptions</button>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button id="restoreSubscriptionButton" onClick="restoreSubscription()" >Restore Subscription</button>
|
||||
</td>
|
||||
<td>
|
||||
<input id="restoreSubscriptionText" type="text"/></td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button id="restoreSubscriptionsButton" onClick="restoreSubscriptions()">Restore Subscriptions</button>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button id="viewSubscriptionsButton" onClick="viewSubscriptions()">View Subscriptions</button>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button id="clearBackedUpSubscriptionsButton" onClick="clearBackupDir()">Clear Backup Files</button>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<p>
|
||||
<div id="statusSpan" style="font-weight:bold; font-size:8pt"></span>
|
||||
<br>
|
||||
</body>
|
||||
|
||||
<script language="JavaScript">
|
||||
|
||||
function clearBackupDir(){
|
||||
updateStatus("Clearing backup files...")
|
||||
updateStatus(callRESTService("clearSubscriptionBackupFiles"))
|
||||
}
|
||||
|
||||
function viewSubscriptions(){
|
||||
updateStatus("Retrieving Subscriptions...")
|
||||
updateStatus(callRESTService("getSubscriptions"))
|
||||
}
|
||||
|
||||
function restoreSubscription(){
|
||||
subscription = document.getElementById("restoreSubscriptionText").value
|
||||
if(subscription){
|
||||
updateStatus("Restoring subscription: ["+subscription+"]...")
|
||||
updateStatus(callRESTService("restoreSubscription/"+subscription))
|
||||
}else{
|
||||
updateStatus("Please input a subscription name to be restored")
|
||||
}
|
||||
}
|
||||
|
||||
function restoreSubscriptions(){
|
||||
updateStatus("Restoring Subscriptions...")
|
||||
updateStatus(callRESTService("restoreSubscriptions"))
|
||||
}
|
||||
|
||||
function backupSubscription(){
|
||||
subscription = document.getElementById("backupSubscriptionText").value
|
||||
if(subscription){
|
||||
updateStatus("Backing up subscription: ["+subscription+"]...")
|
||||
updateStatus(callRESTService("backupSubscription/"+subscription))
|
||||
}else{
|
||||
updateStatus("Please input a subscription name to be backed up")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function backupAllSubscriptions(){
|
||||
updateStatus("Backing up subscriptions...")
|
||||
updateStatus(callRESTService("backupAllSubscriptions"))
|
||||
}
|
||||
|
||||
function callRESTService(func){
|
||||
var url = "http://"+window.location.host+"/rest/dataAccess/"+func;
|
||||
var client = new XMLHttpRequest();
|
||||
client.open("GET", url, false);
|
||||
client.setRequestHeader("Content-Type", "text/plain");
|
||||
client.send();
|
||||
return client.responseText
|
||||
}
|
||||
|
||||
function updateStatus(status){
|
||||
document.getElementById("statusSpan").innerHTML = status
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
Loading…
Add table
Reference in a new issue