Removed multiple EDEX plugins from feature.xml.
Plugins removed from commenting out com.raytheon.uf.edex.hydro.feature from com.raytheo.edex.feature.uframe/feature.xml: com.raytheon.edex.plugin.shef.jar com.raytheon.uf.common.dataplugin.mpe.jar com.raytheon.uf.common.dataplugin.shef.jar com.raytheon.uf.common.hydro.jar com.raytheon.uf.common.mpe.jar com.raytheon.uf.common.ohd.jar com.raytheon.uf.common.xmrg.jar Plugins not built because com.raytheon.uf.edex.mpe.feature was removed from com.raytheo.edex.feature.uframe/feature.xml com.raytheon.uf.common.mpe.gribit2.jar com.raytheon.uf.edex.plugin.mpe.dpa.jar com.raytheon.uf.edex.plugin.mpe.jar com.raytheon.uf.edex.plugin.mpe.test.jar Plugins not built because com.raytheon.uf.edex.dat.feature was removed from com.raytheo.edex.feature.uframe/feature.xml com.raytheon.uf.common.dataplugin.cwat.jar com.raytheon.uf.common.dataplugin.ffmp.jar com.raytheon.uf.common.dataplugin.fog.jar com.raytheon.uf.common.dataplugin.fssobs.jar com.raytheon.uf.common.dataplugin.preciprate.jar com.raytheon.uf.common.dataplugin.qpf.jar com.raytheon.uf.common.dataplugin.scan.jar com.raytheon.uf.common.dataplugin.vil.jar com.raytheon.uf.common.monitor.cpg.jar com.raytheon.uf.common.monitor.jar com.raytheon.uf.edex.cpgsrv.jar com.raytheon.uf.edex.dat.utils.jar com.raytheon.uf.edex.ohd.jar com.raytheon.uf.edex.plugin.cwat.jar com.raytheon.uf.edex.plugin.ffmp.jar com.raytheon.uf.edex.plugin.fog.jar com.raytheon.uf.edex.plugin.fssobs.jar com.raytheon.uf.edex.plugin.loctables.jar com.raytheon.uf.edex.plugin.preciprate.jar com.raytheon.uf.edex.plugin.qpf.jar com.raytheon.uf.edex.plugin.scan.common.jar com.raytheon.uf.edex.plugin.scan.jar com.raytheon.uf.edex.plugin.vil.jar Plugins not built because com.raytheon.uf.edex.aviation.feature was removed from com.raytheo.edex.feature.uframe/feature.xml com.raytheon.uf.common.tafqueue.jar com.raytheon.uf.edex.aviation.aag.jar com.raytheon.uf.edex.aviation.jar com.raytheon.uf.edex.metartohmdbsrv.jar The following plugins we completely removed: com.raytheon.uf.common.backupsvc.jar com.raytheon.uf.common.localization.backup.jar com.raytheon.uf.edex.backupsvc.jar com.raytheon.uf.edex.localization.backup.jar
This commit is contained in:
parent
21aa132812
commit
c51e287bea
61 changed files with 2 additions and 3699 deletions
|
@ -34,18 +34,6 @@
|
||||||
name="AAG"
|
name="AAG"
|
||||||
value="aviation/aag">
|
value="aviation/aag">
|
||||||
</path>
|
</path>
|
||||||
<path
|
|
||||||
application="EDEX"
|
|
||||||
localizationType="COMMON_STATIC"
|
|
||||||
name="Backup Service"
|
|
||||||
value="backupsvc">
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
application="EDEX"
|
|
||||||
localizationType="COMMON_STATIC"
|
|
||||||
name="Localization Backup"
|
|
||||||
value="localizationBackup">
|
|
||||||
</path>
|
|
||||||
<path
|
<path
|
||||||
application="EDEX"
|
application="EDEX"
|
||||||
localizationType="COMMON_STATIC"
|
localizationType="COMMON_STATIC"
|
||||||
|
|
|
@ -241,10 +241,6 @@
|
||||||
<param name="feature"
|
<param name="feature"
|
||||||
value="com.raytheon.uf.edex.text.feature" />
|
value="com.raytheon.uf.edex.text.feature" />
|
||||||
</antcall>
|
</antcall>
|
||||||
<antcall target="build">
|
|
||||||
<param name="feature"
|
|
||||||
value="com.raytheon.uf.edex.aviation.feature" />
|
|
||||||
</antcall>
|
|
||||||
<antcall target="build">
|
<antcall target="build">
|
||||||
<param name="feature"
|
<param name="feature"
|
||||||
value="com.raytheon.uf.edex.satellite.feature" />
|
value="com.raytheon.uf.edex.satellite.feature" />
|
||||||
|
@ -261,6 +257,7 @@
|
||||||
<param name="feature"
|
<param name="feature"
|
||||||
value="com.raytheon.uf.edex.radar.feature" />
|
value="com.raytheon.uf.edex.radar.feature" />
|
||||||
</antcall>
|
</antcall>
|
||||||
|
<!--
|
||||||
<antcall target="build">
|
<antcall target="build">
|
||||||
<param name="feature"
|
<param name="feature"
|
||||||
value="com.raytheon.uf.edex.hydro.feature" />
|
value="com.raytheon.uf.edex.hydro.feature" />
|
||||||
|
@ -273,6 +270,7 @@
|
||||||
<param name="feature"
|
<param name="feature"
|
||||||
value="com.raytheon.uf.edex.dat.feature" />
|
value="com.raytheon.uf.edex.dat.feature" />
|
||||||
</antcall>
|
</antcall>
|
||||||
|
-->
|
||||||
<antcall target="build">
|
<antcall target="build">
|
||||||
<param name="feature"
|
<param name="feature"
|
||||||
value="com.raytheon.uf.edex.config.auto.feature" />
|
value="com.raytheon.uf.edex.config.auto.feature" />
|
||||||
|
|
|
@ -224,10 +224,6 @@
|
||||||
id="com.raytheon.uf.edex.text.feature"
|
id="com.raytheon.uf.edex.text.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
|
||||||
<includes
|
|
||||||
id="com.raytheon.uf.edex.aviation.feature"
|
|
||||||
version="0.0.0"/>
|
|
||||||
|
|
||||||
<includes
|
<includes
|
||||||
id="com.raytheon.uf.edex.satellite.feature"
|
id="com.raytheon.uf.edex.satellite.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
@ -236,18 +232,10 @@
|
||||||
id="com.raytheon.uf.edex.gfe.feature"
|
id="com.raytheon.uf.edex.gfe.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
|
||||||
<includes
|
|
||||||
id="com.raytheon.uf.edex.hydro.feature"
|
|
||||||
version="0.0.0"/>
|
|
||||||
|
|
||||||
<includes
|
<includes
|
||||||
id="com.raytheon.uf.edex.radar.feature"
|
id="com.raytheon.uf.edex.radar.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
|
||||||
<includes
|
|
||||||
id="com.raytheon.uf.edex.dat.feature"
|
|
||||||
version="0.0.0"/>
|
|
||||||
|
|
||||||
<includes
|
<includes
|
||||||
id="com.raytheon.uf.edex.ncep.feature"
|
id="com.raytheon.uf.edex.ncep.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
@ -272,10 +260,6 @@
|
||||||
id="com.raytheon.uf.edex.config.auto.feature"
|
id="com.raytheon.uf.edex.config.auto.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
|
||||||
<includes
|
|
||||||
id="com.raytheon.uf.edex.mpe.feature"
|
|
||||||
version="0.0.0"/>
|
|
||||||
|
|
||||||
<includes
|
<includes
|
||||||
id="com.raytheon.uf.edex.menus.vb.feature"
|
id="com.raytheon.uf.edex.menus.vb.feature"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
|
||||||
<classpathentry kind="src" path="src"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
|
||||||
</classpath>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>com.raytheon.uf.common.backupsvc</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.pde.PluginNature</nature>
|
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
|
@ -1,10 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=11
|
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
|
||||||
org.eclipse.jdt.core.compiler.release=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.source=11
|
|
|
@ -1,17 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Bundle-ManifestVersion: 2
|
|
||||||
Bundle-Name: Backup Service Plug-in
|
|
||||||
Bundle-SymbolicName: com.raytheon.uf.common.backupsvc
|
|
||||||
Bundle-Version: 1.16.0.qualifier
|
|
||||||
Bundle-Vendor: RAYTHEON
|
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
|
||||||
Export-Package: com.raytheon.uf.common.backupsvc.request,
|
|
||||||
com.raytheon.uf.common.backupsvc.response,
|
|
||||||
com.raytheon.uf.common.backupsvc
|
|
||||||
Require-Bundle: com.raytheon.uf.common.serialization.comm,
|
|
||||||
com.raytheon.uf.common.serialization,
|
|
||||||
org.slf4j,
|
|
||||||
com.raytheon.uf.common.comm,
|
|
||||||
com.raytheon.uf.common.message,
|
|
||||||
com.raytheon.uf.common.util,
|
|
||||||
javax.xml.bind
|
|
|
@ -1,4 +0,0 @@
|
||||||
source.. = src/
|
|
||||||
output.. = bin/
|
|
||||||
bin.includes = META-INF/,\
|
|
||||||
.,\
|
|
|
@ -1,336 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetBackupServiceCapabilitiesRequest;
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetEDEXVersionRequest;
|
|
||||||
import com.raytheon.uf.common.backupsvc.response.GetEDEXVersionResponse;
|
|
||||||
import com.raytheon.uf.common.comm.HttpClient;
|
|
||||||
import com.raytheon.uf.common.comm.HttpClientConfigBuilder;
|
|
||||||
import com.raytheon.uf.common.message.WsId;
|
|
||||||
import com.raytheon.uf.common.serialization.ExceptionWrapper;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.RequestWrapper;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.response.ServerErrorResponse;
|
|
||||||
import com.raytheon.uf.common.util.SystemUtil;
|
|
||||||
import com.raytheon.uf.common.util.app.AppInfo;
|
|
||||||
import com.raytheon.uf.common.util.app.Version;
|
|
||||||
import com.raytheon.uf.common.util.rate.TokenBucket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Backup host and optional port as specified in config XML file
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 28, 2016 5937 tgurney Initial creation
|
|
||||||
* Dec 9, 2016 5937 tgurney Add copy constructor
|
|
||||||
* Jul 20, 2017 6352 tgurney Add equals(), hashCode(), DynamicSerialize
|
|
||||||
* Jul 24, 2017 6352 tgurney Move request-sending from BackupService
|
|
||||||
* Oct 3, 2019 7929 tgurney Add special MY_VERSION version value.
|
|
||||||
* Move class from edex to common. Use a
|
|
||||||
* httpClient with gzip enabled
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
|
||||||
public class BackupHost {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
||||||
|
|
||||||
private static final int DEFAULT_THRIFT_PORT = Integer
|
|
||||||
.parseInt(System.getenv("HTTP_PORT"));
|
|
||||||
|
|
||||||
private static final String THRIFT_HTTP_PATH;
|
|
||||||
static {
|
|
||||||
String serverPath = System.getenv("HTTP_SERVER_PATH");
|
|
||||||
if (!serverPath.startsWith("/")) {
|
|
||||||
serverPath = "/" + serverPath;
|
|
||||||
}
|
|
||||||
THRIFT_HTTP_PATH = serverPath + "/thrift";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpClient httpClient;
|
|
||||||
|
|
||||||
static {
|
|
||||||
HttpClientConfigBuilder cfgBuilder = new HttpClientConfigBuilder();
|
|
||||||
cfgBuilder.setGzipEnabled(true);
|
|
||||||
httpClient = new HttpClient(cfgBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Special value that can be used in place of the minimum or maximum
|
|
||||||
* required version, indicating that the requirement is the sender's current
|
|
||||||
* EDEX version.
|
|
||||||
*/
|
|
||||||
public static final String MY_VERSION = "my";
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
@XmlElement
|
|
||||||
private int port = DEFAULT_THRIFT_PORT;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
@XmlElement(required = true)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String hostEdexVersion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No-arg constructor for serialization
|
|
||||||
*/
|
|
||||||
public BackupHost() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor
|
|
||||||
*
|
|
||||||
* @param aBackupHost
|
|
||||||
* The BackupHost to copy
|
|
||||||
*/
|
|
||||||
public BackupHost(BackupHost aBackupHost) {
|
|
||||||
port = aBackupHost.port;
|
|
||||||
name = aBackupHost.name;
|
|
||||||
hostEdexVersion = aBackupHost.hostEdexVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(int port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + (name == null ? 0 : name.hashCode());
|
|
||||||
result = prime * result + port;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!obj.getClass().equals(BackupHost.class)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BackupHost other = (BackupHost) obj;
|
|
||||||
if (name == null) {
|
|
||||||
if (other.name != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!name.equals(other.name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (port != other.port) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an IServerRequest to this host
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @return the object the server returns
|
|
||||||
* @throws Exception
|
|
||||||
* If sending the request fails for some reason
|
|
||||||
*/
|
|
||||||
public Object sendRequest(IServerRequest request) throws Exception {
|
|
||||||
return sendRequest(request, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an IServerRequest to this host
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param rateLimiter
|
|
||||||
* Token bucket to rate-limit the request, can be null
|
|
||||||
* @return the object the server returns
|
|
||||||
* @throws Exception
|
|
||||||
* If sending the request fails for some reason
|
|
||||||
*/
|
|
||||||
public Object sendRequest(IServerRequest request, TokenBucket rateLimiter)
|
|
||||||
throws Exception {
|
|
||||||
RequestWrapper wrapper = new RequestWrapper(request, new WsId());
|
|
||||||
Object rval = null;
|
|
||||||
if (rateLimiter != null) {
|
|
||||||
rval = httpClient.postDynamicSerialize(
|
|
||||||
"http://" + name + ":" + port + THRIFT_HTTP_PATH, wrapper,
|
|
||||||
true, rateLimiter);
|
|
||||||
} else {
|
|
||||||
rval = httpClient.postDynamicSerialize(
|
|
||||||
"http://" + name + ":" + port + THRIFT_HTTP_PATH, wrapper,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
if (rval instanceof ServerErrorResponse) {
|
|
||||||
ServerErrorResponse resp = (ServerErrorResponse) rval;
|
|
||||||
Throwable serverException = ExceptionWrapper
|
|
||||||
.unwrapThrowable(resp.getException());
|
|
||||||
throw new BackupServiceException(serverException.getMessage(),
|
|
||||||
serverException);
|
|
||||||
}
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param useCached
|
|
||||||
* If true, use cached version string if it is available
|
|
||||||
* @return version string. Will query the remote host if necessary. null if
|
|
||||||
* there is no cached value and the host could not be contacted.
|
|
||||||
*/
|
|
||||||
public String getEDEXVersion(boolean useCached) {
|
|
||||||
if (hostEdexVersion == null || !useCached) {
|
|
||||||
try {
|
|
||||||
GetEDEXVersionRequest request = new GetEDEXVersionRequest();
|
|
||||||
request.setRequestingHost(SystemUtil.getHostName());
|
|
||||||
Object response = sendRequest(new GetEDEXVersionRequest());
|
|
||||||
if (response instanceof GetEDEXVersionResponse) {
|
|
||||||
hostEdexVersion = ((GetEDEXVersionResponse) response)
|
|
||||||
.getEdexVersion();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(
|
|
||||||
"Error when sending GetEDEXVersionRequest to " + name,
|
|
||||||
e);
|
|
||||||
hostEdexVersion = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hostEdexVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @return version string. Will use cached version string if it is
|
|
||||||
* available, otherwise will query the remote host.
|
|
||||||
*/
|
|
||||||
public String getEDEXVersion() {
|
|
||||||
return getEDEXVersion(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param minVersionRequired
|
|
||||||
* If null, use this host's current EDEX version. If
|
|
||||||
* {@link #MY_VERSION}, use the caller's current EDEX version.
|
|
||||||
* @param maxVersionRequired
|
|
||||||
* If null, use this host's current EDEX version. If
|
|
||||||
* {@link #MY_VERSION}, use the caller's current EDEX version.
|
|
||||||
* @return Zero if this host's EDEX version falls within the range of
|
|
||||||
* (minVersionRequired, maxVersionRequired). A positive integer if
|
|
||||||
* this host's EDEX version is greater than maxVersionRequired. A
|
|
||||||
* negative integer if this host's EDEX version is less than
|
|
||||||
* minVersionRequired. Null if unable to contact the host
|
|
||||||
*/
|
|
||||||
public Integer compareVersion(String minVersionRequired,
|
|
||||||
String maxVersionRequired) {
|
|
||||||
// refresh cached version string
|
|
||||||
getEDEXVersion(false);
|
|
||||||
if (hostEdexVersion == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (minVersionRequired == null) {
|
|
||||||
minVersionRequired = hostEdexVersion;
|
|
||||||
}
|
|
||||||
if (maxVersionRequired == null) {
|
|
||||||
maxVersionRequired = hostEdexVersion;
|
|
||||||
}
|
|
||||||
if (MY_VERSION.equals(minVersionRequired)) {
|
|
||||||
minVersionRequired = AppInfo.getInstance().getVersion();
|
|
||||||
}
|
|
||||||
if (MY_VERSION.equals(maxVersionRequired)) {
|
|
||||||
maxVersionRequired = AppInfo.getInstance().getVersion();
|
|
||||||
}
|
|
||||||
Version minVer;
|
|
||||||
Version maxVer;
|
|
||||||
Version ver;
|
|
||||||
try {
|
|
||||||
minVer = Version.fromString(minVersionRequired);
|
|
||||||
maxVer = Version.fromString(maxVersionRequired);
|
|
||||||
ver = Version.fromString(hostEdexVersion);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
logger.warn("Failed to parse version string (hostEdexVersion: "
|
|
||||||
+ hostEdexVersion + ", minVersionRequired: "
|
|
||||||
+ minVersionRequired + ", maxVersionRequired: "
|
|
||||||
+ maxVersionRequired + ")", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (ver.compareTo(minVer) < 0) {
|
|
||||||
// Version is less than the minimum required
|
|
||||||
return -1;
|
|
||||||
} else if (ver.compareTo(maxVer) > 0) {
|
|
||||||
// Version is greater than the max allowed
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
// Version falls within allowed range
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return List of all this host's capabilities. */
|
|
||||||
public Set<String> getCapabilities() {
|
|
||||||
Set<String> rval = null;
|
|
||||||
try {
|
|
||||||
Object response = sendRequest(
|
|
||||||
new GetBackupServiceCapabilitiesRequest());
|
|
||||||
if (response instanceof Set<?>) {
|
|
||||||
rval = (Set<String>) response;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(
|
|
||||||
"Error when sending GetBackupServiceCapabilitiesRequest to "
|
|
||||||
+ name,
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception for Backup Service related problems
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Aug 2, 2017 tgurney Initial creation
|
|
||||||
* Oct 3, 2019 7929 tgurney Move to common
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupServiceException extends Exception {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BackupServiceException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BackupServiceException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BackupServiceException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A refreshable {@link IServerRequest}. Calling {@link #refresh()} allows the
|
|
||||||
* request to update itself arbitrarily.
|
|
||||||
*
|
|
||||||
* Introduced for BackupService, which stores IServerRequests to be sent later.
|
|
||||||
* Such requests may be "stale" for whatever reason by the time they'd be sent.
|
|
||||||
* This mechanism allows for a stale request to be updated or even canceled
|
|
||||||
* before it would be sent.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Oct 7, 2019 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface IRefreshableServerRequest extends IServerRequest {
|
|
||||||
/**
|
|
||||||
* @return the request itself updated arbitrarily, or a new/different
|
|
||||||
* request object of the same type, or a different type of request
|
|
||||||
* object, or nothing.
|
|
||||||
*/
|
|
||||||
Optional<IServerRequest> refresh();
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc.request;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to queue up a backup job
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 10, 2016 5937 tgurney Initial creation
|
|
||||||
* Jul 20, 2017 6352 tgurney Add min/maxversionRequired
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class BackupEnqueueRequest implements IServerRequest {
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private IServerRequest request;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String jobName;
|
|
||||||
|
|
||||||
/** Lower number = higher priority. May be negative */
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private int priority;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String minVersionRequired;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String maxVersionRequired;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private List<String> hosts;
|
|
||||||
|
|
||||||
public IServerRequest getRequest() {
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequest(IServerRequest request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJobName() {
|
|
||||||
return jobName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJobName(String jobName) {
|
|
||||||
this.jobName = jobName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPriority() {
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPriority(int priority) {
|
|
||||||
this.priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getHosts() {
|
|
||||||
return hosts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHosts(List<String> hosts) {
|
|
||||||
this.hosts = hosts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMinVersionRequired() {
|
|
||||||
return minVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinVersionRequired(String minVersionRequired) {
|
|
||||||
this.minVersionRequired = minVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMaxVersionRequired() {
|
|
||||||
return maxVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxVersionRequired(String maxVersionRequired) {
|
|
||||||
this.maxVersionRequired = maxVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc.request;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to get map of backup hosts to set of capabilities for each host
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 20, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class GetBackupHostCapabilitiesMapRequest implements IServerRequest {
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc.request;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to get list of backup hosts and EDEX version for each host
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 20, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class GetBackupHostVersionMapRequest implements IServerRequest {
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc.request;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to get list of BackupService capabilities for a single server
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 26, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class GetBackupServiceCapabilitiesRequest implements IServerRequest {
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc.request;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to get EDEX version string
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Oct 17, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class GetEDEXVersionRequest implements IServerRequest {
|
|
||||||
/** Name of the host that is sending this request. */
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String requestingHost;
|
|
||||||
|
|
||||||
public String getRequestingHost() {
|
|
||||||
return requestingHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequestingHost(String requestingHost) {
|
|
||||||
this.requestingHost = requestingHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "GetEDEXVersionRequest [requestingHost=" + requestingHost + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.backupsvc.response;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Response to GetEDEXVersionRequest
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Oct 17, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class GetEDEXVersionResponse {
|
|
||||||
|
|
||||||
/** String returned in response when EDEX version is not known */
|
|
||||||
public static final String UNDEFINED = "Undefined";
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String edexVersion;
|
|
||||||
|
|
||||||
/** Host that is sending this response. */
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String respondingHost;
|
|
||||||
|
|
||||||
public String getEdexVersion() {
|
|
||||||
return edexVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEdexVersion(String edexVersion) {
|
|
||||||
this.edexVersion = edexVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRespondingHost() {
|
|
||||||
return respondingHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRespondingHost(String respondingHost) {
|
|
||||||
this.respondingHost = respondingHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "GetEDEXVersionResponse [edexVersion=" + edexVersion
|
|
||||||
+ ", respondingHost=" + respondingHost + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
|
||||||
<classpathentry kind="src" path="src"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
|
||||||
</classpath>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>com.raytheon.uf.common.localization.backup</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.pde.PluginNature</nature>
|
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
|
@ -1,10 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=11
|
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
|
||||||
org.eclipse.jdt.core.compiler.release=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.source=11
|
|
|
@ -1,16 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Bundle-ManifestVersion: 2
|
|
||||||
Bundle-Name: Localization Backup Plug-in
|
|
||||||
Bundle-SymbolicName: com.raytheon.uf.common.localization.backup
|
|
||||||
Bundle-Version: 1.16.0.qualifier
|
|
||||||
Bundle-Vendor: RAYTHEON
|
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
|
||||||
Export-Package: com.raytheon.uf.common.localization.backup.request
|
|
||||||
Require-Bundle: com.raytheon.uf.common.status,
|
|
||||||
com.raytheon.uf.common.serialization,
|
|
||||||
com.raytheon.uf.common.serialization.comm,
|
|
||||||
com.raytheon.uf.common.util,
|
|
||||||
com.raytheon.uf.common.localization,
|
|
||||||
com.raytheon.uf.common.backupsvc,
|
|
||||||
org.apache.commons.io,
|
|
||||||
org.slf4j
|
|
|
@ -1,4 +0,0 @@
|
||||||
source.. = src/
|
|
||||||
output.. = bin/
|
|
||||||
bin.includes = META-INF/,\
|
|
||||||
.,\
|
|
|
@ -1,109 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.localization.backup.request;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.IRefreshableServerRequest;
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to delete a localization file
|
|
||||||
*
|
|
||||||
* NOTE: This is meant only for use with BackupService. If you need an API for
|
|
||||||
* generic localization file operations then use the localization REST
|
|
||||||
* interface.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 11, 2016 5937 tgurney Initial creation
|
|
||||||
* Oct 8, 2019 7929 tgurney Implement refresh()
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class LocalizationFileDeleteRequest
|
|
||||||
implements IRefreshableServerRequest {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String path;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private LocalizationContext context;
|
|
||||||
|
|
||||||
public LocalizationFileDeleteRequest() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalizationFileDeleteRequest(ILocalizationFile lf) {
|
|
||||||
this.path = lf.getPath();
|
|
||||||
this.context = lf.getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPath(String path) {
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalizationContext getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(LocalizationContext context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<IServerRequest> refresh() {
|
|
||||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
|
||||||
ILocalizationFile lf = pathMgr.getLocalizationFile(context, path);
|
|
||||||
if (lf.exists()) {
|
|
||||||
try {
|
|
||||||
return Optional.of(new LocalizationFileSaveRequest(lf));
|
|
||||||
} catch (IOException | LocalizationException e) {
|
|
||||||
logger.warn("Failed to create a new save request for " + lf
|
|
||||||
+ ". Returning the old request unchanged", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.of(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.common.localization.backup.request;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.IRefreshableServerRequest;
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to save a localization file. Includes the entire contents of the file
|
|
||||||
* to save.
|
|
||||||
*
|
|
||||||
* NOTE: This is meant only for use with BackupService. If you need an API for
|
|
||||||
* generic localization file operations then use the localization REST
|
|
||||||
* interface.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 9, 2016 5937 tgurney Initial creation
|
|
||||||
* Oct 8, 2019 7929 tgurney Implement refresh(). Add file checksum
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@DynamicSerialize
|
|
||||||
public class LocalizationFileSaveRequest implements IRefreshableServerRequest {
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private byte[] bytes;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String path;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private LocalizationContext context;
|
|
||||||
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private String checksum;
|
|
||||||
|
|
||||||
public LocalizationFileSaveRequest() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalizationFileSaveRequest(ILocalizationFile lf)
|
|
||||||
throws IOException, LocalizationException {
|
|
||||||
this.path = lf.getPath();
|
|
||||||
this.context = lf.getContext();
|
|
||||||
this.checksum = lf.getCheckSum();
|
|
||||||
try (InputStream inStream = lf.openInputStream()) {
|
|
||||||
this.bytes = IOUtils.toByteArray(inStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPath(String path) {
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalizationContext getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(LocalizationContext context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBytes(byte[] bytes) {
|
|
||||||
this.bytes = bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getChecksum() {
|
|
||||||
return checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChecksum(String checksum) {
|
|
||||||
this.checksum = checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<IServerRequest> refresh() {
|
|
||||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
|
||||||
ILocalizationFile lf = pathMgr.getLocalizationFile(context, path);
|
|
||||||
if (lf.exists() && !lf.getCheckSum().equals(checksum)) {
|
|
||||||
try {
|
|
||||||
return Optional.of(new LocalizationFileSaveRequest(lf));
|
|
||||||
} catch (IOException | LocalizationException e) {
|
|
||||||
logger.warn("Failed to create a new save request for " + lf
|
|
||||||
+ ". Returning the old request unchanged", e);
|
|
||||||
}
|
|
||||||
} else if (!lf.exists()) {
|
|
||||||
LocalizationFileDeleteRequest newReq = new LocalizationFileDeleteRequest();
|
|
||||||
newReq.setContext(context);
|
|
||||||
newReq.setPath(path);
|
|
||||||
return Optional.of(newReq);
|
|
||||||
}
|
|
||||||
return Optional.of(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
|
||||||
<classpathentry kind="src" path="src"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
|
||||||
</classpath>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>com.raytheon.uf.edex.backupsvc</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.pde.PluginNature</nature>
|
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
|
@ -1,10 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=11
|
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
|
||||||
org.eclipse.jdt.core.compiler.release=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.source=11
|
|
|
@ -1,22 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Bundle-ManifestVersion: 2
|
|
||||||
Bundle-Name: Backup Service Plug-in
|
|
||||||
Bundle-SymbolicName: com.raytheon.uf.edex.backupsvc
|
|
||||||
Bundle-Version: 1.18.0.qualifier
|
|
||||||
Bundle-Vendor: RAYTHEON
|
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
|
||||||
Bundle-ActivationPolicy: lazy
|
|
||||||
Import-Package: javax.persistence
|
|
||||||
Require-Bundle: com.raytheon.uf.edex.database,
|
|
||||||
com.raytheon.uf.common.serialization.comm,
|
|
||||||
com.raytheon.uf.common.backupsvc,
|
|
||||||
com.raytheon.uf.common.serialization,
|
|
||||||
com.raytheon.uf.common.status,
|
|
||||||
com.raytheon.uf.edex.core,
|
|
||||||
com.raytheon.uf.common.comm,
|
|
||||||
com.raytheon.uf.common.message,
|
|
||||||
com.raytheon.uf.common.util,
|
|
||||||
com.raytheon.uf.common.localization,
|
|
||||||
com.raytheon.uf.common.time,
|
|
||||||
org.slf4j,
|
|
||||||
javax.xml.bind
|
|
|
@ -1,6 +0,0 @@
|
||||||
source.. = src/
|
|
||||||
output.. = bin/
|
|
||||||
bin.includes = META-INF/,\
|
|
||||||
res/,\
|
|
||||||
utility/,\
|
|
||||||
.,\
|
|
|
@ -1,60 +0,0 @@
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
|
||||||
http://camel.apache.org/schema/spring
|
|
||||||
http://camel.apache.org/schema/spring/camel-spring.xsd">
|
|
||||||
|
|
||||||
<bean id="backupSvcDbPluginProperties" class="com.raytheon.uf.edex.database.DatabasePluginProperties">
|
|
||||||
<property name="pluginFQN" value="com.raytheon.uf.edex.backupsvc"/>
|
|
||||||
<property name="database" value="metadata"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="backupSvcDbRegistered" factory-bean="dbPluginRegistry" factory-method="register">
|
|
||||||
<constructor-arg value="com.raytheon.uf.edex.backupsvc"/>
|
|
||||||
<constructor-arg ref="backupSvcDbPluginProperties"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="backupServiceCapabilityManager" class="com.raytheon.uf.edex.backupsvc.service.BackupServiceCapabilityManager"
|
|
||||||
factory-method="getInstance" />
|
|
||||||
|
|
||||||
<bean id="getBackupHostCapabilitiesMapHandler" class="com.raytheon.uf.edex.backupsvc.handlers.GetBackupHostCapabilitiesMapHandler" />
|
|
||||||
|
|
||||||
<bean id="getBackupHostVersionMapHandler" class="com.raytheon.uf.edex.backupsvc.handlers.GetBackupHostVersionMapHandler" />
|
|
||||||
|
|
||||||
<bean id="getEdexVersionHandler" class="com.raytheon.uf.edex.backupsvc.handlers.GetEDEXVersionHandler" />
|
|
||||||
|
|
||||||
<bean id="getBackupServiceCapabilitiesHandler" class="com.raytheon.uf.edex.backupsvc.handlers.GetBackupServiceCapabilitiesHandler" />
|
|
||||||
|
|
||||||
<bean id="backupEnqueueHandler" class="com.raytheon.uf.edex.backupsvc.handlers.BackupEnqueueHandler" />
|
|
||||||
|
|
||||||
<bean id="backupSvc" class="com.raytheon.uf.edex.backupsvc.service.BackupService" depends-on="backupSvcDbRegistered" />
|
|
||||||
|
|
||||||
<camelContext id="clusteredBackupSvcContext"
|
|
||||||
xmlns="http://camel.apache.org/schema/spring"
|
|
||||||
errorHandlerRef="errorHandler">
|
|
||||||
<endpoint id="backupSvcStatsCron"
|
|
||||||
uri="quartz://backupSvcStatsScheduled/?cron=0+7+*+*+*+?)"/>
|
|
||||||
|
|
||||||
<route id="backupSvcStatsScheduled">
|
|
||||||
<from uri="backupSvcStatsCron" />
|
|
||||||
<doTry>
|
|
||||||
<bean ref="backupSvc" method="reportStats" />
|
|
||||||
<doCatch>
|
|
||||||
<exception>java.lang.Throwable</exception>
|
|
||||||
<to uri="log:backupSvc?level=ERROR"/>
|
|
||||||
</doCatch>
|
|
||||||
</doTry>
|
|
||||||
</route>
|
|
||||||
</camelContext>
|
|
||||||
|
|
||||||
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
|
|
||||||
<constructor-arg ref="clusteredBackupSvcContext" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean factory-bean="contextManager" factory-method="registerContextStateProcessor">
|
|
||||||
<constructor-arg ref="clusteredBackupSvcContext"/>
|
|
||||||
<constructor-arg ref="backupSvc"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
|
|
@ -1,70 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.database;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.SequenceGenerator;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Separate blob table for backup jobs
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 10, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@SequenceGenerator(initialValue = 1, name = "backup_blobseq", sequenceName = "backup_blobseq", allocationSize = 1)
|
|
||||||
@Table(name = "backup_blob")
|
|
||||||
public class BackupBlob implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Column
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(generator = "backup_blobseq", strategy = GenerationType.SEQUENCE)
|
|
||||||
private long id;
|
|
||||||
|
|
||||||
@Column
|
|
||||||
private byte[] blob;
|
|
||||||
|
|
||||||
public byte[] getBlob() {
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBlob(byte[] blob) {
|
|
||||||
this.blob = blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.database;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.SequenceGenerator;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Index;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Backup job that includes a host name and data to send to that host
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Oct 18, 2016 5937 tgurney Initial creation
|
|
||||||
* Jul 20, 2017 6352 tgurney Add min/maxversionRequired
|
|
||||||
* Apr 06, 2021 22487 smoorthy increase field size of jobName
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@SequenceGenerator(initialValue = 1, name = "backup_jobseq", sequenceName = "backup_jobseq", allocationSize = 1)
|
|
||||||
@Table(name = "backup_job")
|
|
||||||
public class BackupJob implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Column
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(generator = "backup_jobseq", strategy = GenerationType.SEQUENCE)
|
|
||||||
private long id;
|
|
||||||
|
|
||||||
@Column(nullable = false, length = 256)
|
|
||||||
private String jobName;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
private int priority;
|
|
||||||
|
|
||||||
@Column(name = "host", nullable = false, length = 128)
|
|
||||||
@Index(name = "backupJobHostIdx")
|
|
||||||
private String host;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: There is no getter for this field. Access should be done via a
|
|
||||||
* primary key lookup on backup_blob table, hence the separate backupBlobId
|
|
||||||
* field.
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "backup_blob_id")
|
|
||||||
private BackupBlob requestBlob;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
private long createdTime;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
private int blobSize;
|
|
||||||
|
|
||||||
@Column(name = "backup_blob_id", insertable = false, updatable = false)
|
|
||||||
private long backupBlobId;
|
|
||||||
|
|
||||||
@Column(length = 16)
|
|
||||||
private String minVersionRequired;
|
|
||||||
|
|
||||||
@Column(length = 16)
|
|
||||||
private String maxVersionRequired;
|
|
||||||
|
|
||||||
public int getPriority() {
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPriority(int priority) {
|
|
||||||
this.priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJobName() {
|
|
||||||
return jobName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJobName(String jobName) {
|
|
||||||
this.jobName = jobName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequestBlob(BackupBlob requestBlob) {
|
|
||||||
this.requestBlob = requestBlob;
|
|
||||||
this.blobSize = requestBlob.getBlob().length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCreatedTime() {
|
|
||||||
return createdTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedTime(long createdTime) {
|
|
||||||
this.createdTime = createdTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBlobSize() {
|
|
||||||
return blobSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHost(String host) {
|
|
||||||
this.host = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBackupBlobId() {
|
|
||||||
return backupBlobId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMinVersionRequired() {
|
|
||||||
return minVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinVersionRequired(String minVersionRequired) {
|
|
||||||
this.minVersionRequired = minVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMaxVersionRequired() {
|
|
||||||
return maxVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxVersionRequired(String maxVersionRequired) {
|
|
||||||
this.maxVersionRequired = maxVersionRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,237 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.database;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.StatelessSession;
|
|
||||||
import org.hibernate.Transaction;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
|
||||||
import com.raytheon.uf.edex.database.dao.CoreDao;
|
|
||||||
import com.raytheon.uf.edex.database.dao.DaoConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data access methods for backup job operations.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 10, 2016 5937 tgurney Initial creation
|
|
||||||
* Jul 20, 2017 6352 tgurney Add versionRequired parameters to
|
|
||||||
* createNewJob()
|
|
||||||
* Oct 3, 2019 7929 tgurney Add FIXME for potential issue with
|
|
||||||
* large numbers of deferred jobs clogging
|
|
||||||
* up the queue
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupJobDao extends CoreDao {
|
|
||||||
|
|
||||||
private static final String DB_NAME = "metadata";
|
|
||||||
|
|
||||||
private static final String POLL_QUERY = "select j1.id id from "
|
|
||||||
+ " (select max(id) id, jobname from backup_job "
|
|
||||||
+ " where host = :host group by jobname) j1 "
|
|
||||||
+ " join (select id, priority from backup_job) j2 "
|
|
||||||
+ " on j1.id=j2.id order by priority asc";
|
|
||||||
|
|
||||||
private static final String PURGE_OLD_JOBS_QUERY = "delete from backup_job "
|
|
||||||
+ " where jobname = :jobName and host = :host and id <= :jobId ";
|
|
||||||
|
|
||||||
private static final String PURGE_HOSTS_QUERY = "delete from backup_job "
|
|
||||||
+ " where host in (:hosts)";
|
|
||||||
|
|
||||||
private static final String PURGE_BLOBS_QUERY = "delete from backup_blob "
|
|
||||||
+ " where id in "
|
|
||||||
+ "(select b.id from backup_blob b left join backup_job j"
|
|
||||||
+ " on b.id = j.backup_blob_id "
|
|
||||||
+ " where j.backup_blob_id is null)";
|
|
||||||
|
|
||||||
public BackupJobDao() {
|
|
||||||
super(DaoConfig.forDatabase(DB_NAME));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete this job and any older jobs that it replaced.
|
|
||||||
*
|
|
||||||
* @param job
|
|
||||||
*/
|
|
||||||
public void removeFinishedJob(BackupJob job) {
|
|
||||||
Map<String, Object> paramMap = new HashMap<>();
|
|
||||||
paramMap.put("jobName", job.getJobName());
|
|
||||||
paramMap.put("host", job.getHost());
|
|
||||||
paramMap.put("jobId", job.getId());
|
|
||||||
executeSQLUpdate(PURGE_OLD_JOBS_QUERY, paramMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all jobs except those for the specified hosts. Then delete any
|
|
||||||
* orphan blobs.
|
|
||||||
*
|
|
||||||
* @param hostsToKeep
|
|
||||||
* Keep only the jobs that would run for these hosts.
|
|
||||||
*/
|
|
||||||
public void cleanUp(List<String> hostsToKeep) {
|
|
||||||
long t0 = System.currentTimeMillis();
|
|
||||||
Object[] result = executeSQLQuery(
|
|
||||||
"select distinct host from backup_job");
|
|
||||||
if (result != null && result.length > 0) {
|
|
||||||
List<String> hostsToRemove = Arrays.stream(result)
|
|
||||||
.map(Object::toString)
|
|
||||||
.filter(item -> !hostsToKeep.contains(item))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (!hostsToRemove.isEmpty()) {
|
|
||||||
logger.info("Found " + hostsToRemove.size()
|
|
||||||
+ " old hosts. Purging old host jobs");
|
|
||||||
int purgeCount = executeSQLUpdate(PURGE_HOSTS_QUERY, "hosts",
|
|
||||||
hostsToRemove);
|
|
||||||
logger.info("Purged " + purgeCount + " jobs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int purgeCount = executeSQLUpdate(PURGE_BLOBS_QUERY);
|
|
||||||
long t1 = System.currentTimeMillis();
|
|
||||||
logger.info("Purged " + purgeCount + " finished request blobs");
|
|
||||||
logger.info("Cleanup took " + TimeUtil.prettyDuration(t1 - t0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new backup job.
|
|
||||||
*
|
|
||||||
* @param jobName
|
|
||||||
* @param priority
|
|
||||||
* Lower number = higher priority
|
|
||||||
* @param blob
|
|
||||||
* The serialized request blob
|
|
||||||
* @param hosts
|
|
||||||
* List of hosts to send the request to
|
|
||||||
* @param minVersionRequired
|
|
||||||
* Host must have at least this EDEX version to receive this
|
|
||||||
* request
|
|
||||||
* @param maxVersionRequired
|
|
||||||
* Host must have no greater than this EDEX version to receive
|
|
||||||
* this request
|
|
||||||
*/
|
|
||||||
public void createNewJob(String jobName, int priority, byte[] blob,
|
|
||||||
List<String> hosts, String minVersionRequired,
|
|
||||||
String maxVersionRequired) {
|
|
||||||
Session session = null;
|
|
||||||
Transaction tx = null;
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
try {
|
|
||||||
session = getSessionFactory().openSession();
|
|
||||||
tx = session.beginTransaction();
|
|
||||||
BackupBlob requestBlob = new BackupBlob();
|
|
||||||
requestBlob.setBlob(blob);
|
|
||||||
session.persist(requestBlob);
|
|
||||||
for (String host : hosts) {
|
|
||||||
BackupJob job = new BackupJob();
|
|
||||||
job.setJobName(jobName);
|
|
||||||
job.setPriority(priority);
|
|
||||||
job.setRequestBlob(requestBlob);
|
|
||||||
job.setCreatedTime(now);
|
|
||||||
job.setHost(host);
|
|
||||||
job.setMinVersionRequired(minVersionRequired);
|
|
||||||
job.setMaxVersionRequired(maxVersionRequired);
|
|
||||||
session.persist(job);
|
|
||||||
}
|
|
||||||
tx.commit();
|
|
||||||
} catch (HibernateException e) {
|
|
||||||
if (tx != null) {
|
|
||||||
tx.rollback();
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (session != null) {
|
|
||||||
session.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get next jobs to run for a single host
|
|
||||||
*
|
|
||||||
* @param host
|
|
||||||
* @return List of jobs
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public List<BackupJob> poll(String host) {
|
|
||||||
/*
|
|
||||||
* FIXME: Returning only the 1000 oldest/highest priority jobs means
|
|
||||||
* that in the unlikely event that there are 1000 or more jobs in the
|
|
||||||
* queue, and the top 1000 are being held due to version mismatch
|
|
||||||
* between sender and receiver, then any jobs behind those will be stuck
|
|
||||||
* for a long time. The solution here is not obvious, and this seems
|
|
||||||
* pretty unlikely to happen in any operational situation, but if it did
|
|
||||||
* happen it could be a big problem.
|
|
||||||
*/
|
|
||||||
Object[] ids = executeSQLQuery(POLL_QUERY, "host", host, 1000);
|
|
||||||
if (ids == null || ids.length == 0) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
List<Long> longIds = Arrays.stream(ids).map(Object::toString)
|
|
||||||
.map(Long::valueOf).collect(Collectors.toList());
|
|
||||||
Session s = null;
|
|
||||||
try {
|
|
||||||
s = getSessionFactory().openSession();
|
|
||||||
List<BackupJob> jobs = s
|
|
||||||
.createQuery("from BackupJob where id in (:ids)")
|
|
||||||
.setParameterList("ids", longIds).list();
|
|
||||||
return jobs;
|
|
||||||
} finally {
|
|
||||||
if (s != null) {
|
|
||||||
s.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get request blob for a specified job
|
|
||||||
*
|
|
||||||
* @param job
|
|
||||||
* @return The serialized request
|
|
||||||
*/
|
|
||||||
public byte[] fetchBlob(BackupJob job) {
|
|
||||||
StatelessSession ss = null;
|
|
||||||
try {
|
|
||||||
ss = getSessionFactory().openStatelessSession();
|
|
||||||
BackupBlob blobRecord = (BackupBlob) ss.get(BackupBlob.class,
|
|
||||||
job.getBackupBlobId());
|
|
||||||
return blobRecord.getBlob();
|
|
||||||
} finally {
|
|
||||||
if (ss != null) {
|
|
||||||
ss.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,151 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.handlers;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupServiceException;
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.BackupEnqueueRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.DynamicSerializationManager;
|
|
||||||
import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType;
|
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.response.GenericResponse;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.database.BackupJobDao;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.service.BackupServiceConfigManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for BackupEnqueueRequest
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 10, 2016 5937 tgurney Initial creation
|
|
||||||
* Dec 9, 2016 5937 tgurney Better config handling
|
|
||||||
* Jul 20, 2017 6352 tgurney Add versionRequired parameters to enqueue
|
|
||||||
* Oct 8, 2019 7929 tgurney Store the request uncompressed
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupEnqueueHandler
|
|
||||||
implements IRequestHandler<BackupEnqueueRequest> {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
||||||
|
|
||||||
private BackupJobDao dao;
|
|
||||||
|
|
||||||
private BackupServiceConfigManager configMgr;
|
|
||||||
|
|
||||||
public BackupEnqueueHandler() {
|
|
||||||
dao = new BackupJobDao();
|
|
||||||
configMgr = BackupServiceConfigManager.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enqueue a request to send to backup hosts. A new job with the same name
|
|
||||||
* as a job that is already in queue will supersede that already existing
|
|
||||||
* job. If you don't want this behavior then you need to use a unique job
|
|
||||||
* name every time you enqueue a job. Note that this method will not create
|
|
||||||
* a job (i.e. is a no-op) if no backup hosts are configured.
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* Request to send
|
|
||||||
* @param jobName
|
|
||||||
* Job name
|
|
||||||
* @param priority
|
|
||||||
* Request priority (lower number = higher priority)
|
|
||||||
* @param hostnames
|
|
||||||
* List of hosts to send the request to. If empty, send to all
|
|
||||||
* hosts configured with BackupService
|
|
||||||
* @param minVersionRequired
|
|
||||||
* Host must have at least this EDEX version to receive this
|
|
||||||
* request
|
|
||||||
* @param maxVersionRequired
|
|
||||||
* Host must have no greater than this EDEX version to receive
|
|
||||||
* this request
|
|
||||||
* @throws SerializationException
|
|
||||||
* @throws BackupServiceException
|
|
||||||
* If the enqueue failed. This is either a database-related
|
|
||||||
* error, or a failure to serialize the provided request, or a
|
|
||||||
* problem with BackupService configuration
|
|
||||||
*/
|
|
||||||
private void enqueue(IServerRequest request, String jobName, int priority,
|
|
||||||
List<String> hostnames, String minVersionRequired,
|
|
||||||
String maxVersionRequired)
|
|
||||||
throws BackupServiceException, SerializationException {
|
|
||||||
List<String> filteredHostnames = new ArrayList<>();
|
|
||||||
List<String> configuredHostnames = configMgr.getHostnamesOnly();
|
|
||||||
if (configuredHostnames.isEmpty()) {
|
|
||||||
throw new BackupServiceException("No backup hosts are configured.");
|
|
||||||
}
|
|
||||||
if (hostnames != null) {
|
|
||||||
for (String hostname : hostnames) {
|
|
||||||
if (configuredHostnames.contains(hostname)) {
|
|
||||||
filteredHostnames.add(hostname);
|
|
||||||
} else {
|
|
||||||
// Host specified that is not configured
|
|
||||||
throw new BackupServiceException("Host " + hostname
|
|
||||||
+ " is not a configured backup host.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No hostnames specified. Send to all configured hosts
|
|
||||||
filteredHostnames = configuredHostnames;
|
|
||||||
}
|
|
||||||
byte[] blob = DynamicSerializationManager
|
|
||||||
.getManager(SerializationType.Thrift).serialize(request);
|
|
||||||
try {
|
|
||||||
dao.createNewJob(jobName, priority, blob, filteredHostnames,
|
|
||||||
minVersionRequired, maxVersionRequired);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new BackupServiceException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(BackupEnqueueRequest request) throws Exception {
|
|
||||||
GenericResponse response = new GenericResponse();
|
|
||||||
response.setSuccess(false);
|
|
||||||
try {
|
|
||||||
enqueue(request.getRequest(), request.getJobName(),
|
|
||||||
request.getPriority(), request.getHosts(),
|
|
||||||
request.getMinVersionRequired(),
|
|
||||||
request.getMaxVersionRequired());
|
|
||||||
response.setSuccess(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Failed to enqueue backup job " + request.getJobName()
|
|
||||||
+ ": ", e);
|
|
||||||
response.setMessage(e.getMessage());
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.handlers;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupHost;
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetBackupHostCapabilitiesMapRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.service.BackupServiceConfigManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for {@link GetBackupHostCapabilitiesMapRequest}
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 20, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GetBackupHostCapabilitiesMapHandler
|
|
||||||
implements IRequestHandler<GetBackupHostCapabilitiesMapRequest> {
|
|
||||||
|
|
||||||
public GetBackupHostCapabilitiesMapHandler() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(GetBackupHostCapabilitiesMapRequest request)
|
|
||||||
throws Exception {
|
|
||||||
BackupServiceConfigManager configMgr = BackupServiceConfigManager
|
|
||||||
.getInstance();
|
|
||||||
configMgr.reload();
|
|
||||||
List<BackupHost> hosts = BackupServiceConfigManager.getInstance()
|
|
||||||
.getBackupHosts();
|
|
||||||
Map<String, Set<String>> hostMap = new HashMap<>();
|
|
||||||
for (BackupHost host : hosts) {
|
|
||||||
Set<String> capabilities = host.getCapabilities();
|
|
||||||
if (capabilities != null) {
|
|
||||||
hostMap.put(host.getName(), capabilities);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hostMap;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.handlers;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupHost;
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetBackupHostVersionMapRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.service.BackupServiceConfigManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for {@link GetBackupHostVersionMapRequest}
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 20, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GetBackupHostVersionMapHandler
|
|
||||||
implements IRequestHandler<GetBackupHostVersionMapRequest> {
|
|
||||||
|
|
||||||
public GetBackupHostVersionMapHandler() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(GetBackupHostVersionMapRequest request)
|
|
||||||
throws Exception {
|
|
||||||
BackupServiceConfigManager configMgr = BackupServiceConfigManager
|
|
||||||
.getInstance();
|
|
||||||
configMgr.reload();
|
|
||||||
List<BackupHost> hosts = BackupServiceConfigManager.getInstance()
|
|
||||||
.getBackupHosts();
|
|
||||||
Map<String, String> hostMap = new HashMap<>();
|
|
||||||
for (BackupHost host : hosts) {
|
|
||||||
String version = host.getEDEXVersion();
|
|
||||||
if (version != null) {
|
|
||||||
hostMap.put(host.getName(), version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hostMap;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.handlers;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetBackupServiceCapabilitiesRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.service.BackupServiceCapabilityManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for {@link GetBackupServiceCapabilitiesRequest}
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 26, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GetBackupServiceCapabilitiesHandler
|
|
||||||
implements IRequestHandler<GetBackupServiceCapabilitiesRequest> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(GetBackupServiceCapabilitiesRequest request)
|
|
||||||
throws Exception {
|
|
||||||
return BackupServiceCapabilityManager.getInstance().getCapabilities();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.handlers;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetEDEXVersionRequest;
|
|
||||||
import com.raytheon.uf.common.backupsvc.response.GetEDEXVersionResponse;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.common.util.SystemUtil;
|
|
||||||
import com.raytheon.uf.common.util.app.AppInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for GetEDEXVersionRequest
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Oct 17, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GetEDEXVersionHandler
|
|
||||||
implements IRequestHandler<GetEDEXVersionRequest> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(GetEDEXVersionRequest request)
|
|
||||||
throws Exception {
|
|
||||||
GetEDEXVersionResponse response = new GetEDEXVersionResponse();
|
|
||||||
response.setEdexVersion(GetEDEXVersionResponse.UNDEFINED);
|
|
||||||
response.setRespondingHost(SystemUtil.getHostName());
|
|
||||||
String edexVersion = AppInfo.getInstance().getVersion();
|
|
||||||
if (edexVersion != null) {
|
|
||||||
response.setEdexVersion(edexVersion);
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,310 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupHost;
|
|
||||||
import com.raytheon.uf.common.backupsvc.IRefreshableServerRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.DynamicSerializationManager;
|
|
||||||
import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType;
|
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.RequestRouter;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.response.GenericResponse;
|
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
|
||||||
import com.raytheon.uf.common.util.SizeUtil;
|
|
||||||
import com.raytheon.uf.common.util.rate.TokenBucket;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.database.BackupJob;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.database.BackupJobDao;
|
|
||||||
import com.raytheon.uf.edex.core.EDEXUtil;
|
|
||||||
import com.raytheon.uf.edex.core.EdexTimerBasedThread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service for pushing data to other EDEX hosts. Designed for pushing
|
|
||||||
* localization file updates to backup hosts, but may be used for other
|
|
||||||
* inter-site communication purposes.
|
|
||||||
*
|
|
||||||
* This is a clustered singleton service. It must only be instantiated from
|
|
||||||
* Spring and only in one place.
|
|
||||||
*
|
|
||||||
* USAGE: Submit a BackupEnqueueRequest that contains the request you want to
|
|
||||||
* send out to the backup hosts.
|
|
||||||
*
|
|
||||||
* CONFIGURATION: The service is configured by a site-level localization XML
|
|
||||||
* file. That file lists the hosts that all data will be sent to, and specifies
|
|
||||||
* the rate limit (in KiB) for sending requests. The config file is reloaded
|
|
||||||
* each time the backup service wakes up.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Oct 18, 2016 5937 tgurney Initial creation
|
|
||||||
* Dec 9, 2016 5937 tgurney Fix initial sleep interval
|
|
||||||
* Dec 9, 2016 5937 tgurney Improve configuration logic
|
|
||||||
* Mar 23, 2017 5937 tgurney Do not process() during EDEX startup
|
|
||||||
* Mar 30, 2017 5937 rjpeter Use EdexTimerBasedThread logger.
|
|
||||||
* Jul 20, 2017 6352 tgurney Add min/maxVersionRequired job parameters
|
|
||||||
* Jul 24, 2017 6352 tgurney Move stats reporting code to new class
|
|
||||||
* Oct 3, 2019 7929 tgurney Defer jobs that are destined for a server
|
|
||||||
* with newer EDEX version (instead of
|
|
||||||
* throwing them out). Also log stats for
|
|
||||||
* deferred jobs. Add mechanism to refresh
|
|
||||||
* a request before it is sent
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupService extends EdexTimerBasedThread {
|
|
||||||
public enum JobStatus {
|
|
||||||
SUCCESSFUL, FAILED, DEFERRED, CANCELED;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
String name = name().toLowerCase();
|
|
||||||
return Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final BackupServiceStatsReporter statsReporter;
|
|
||||||
|
|
||||||
private final BackupJobDao dao;
|
|
||||||
|
|
||||||
private TokenBucket rateLimiter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public constructor for Spring only; do not try to instantiate this
|
|
||||||
* yourself
|
|
||||||
*/
|
|
||||||
public BackupService() {
|
|
||||||
long t0 = System.currentTimeMillis();
|
|
||||||
threadSleepInterval = (int) (BackupServiceConfigManager.getInstance()
|
|
||||||
.getPollIntervalSeconds() * TimeUtil.MILLIS_PER_SECOND);
|
|
||||||
dao = new BackupJobDao();
|
|
||||||
statsReporter = new BackupServiceStatsReporter();
|
|
||||||
long t1 = System.currentTimeMillis();
|
|
||||||
logger.info("Initialized in " + TimeUtil.prettyDuration(t1 - t0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run a single job for a single host.
|
|
||||||
*
|
|
||||||
* @param job
|
|
||||||
* @param host
|
|
||||||
* @return the job status
|
|
||||||
*/
|
|
||||||
private JobStatus runJob(BackupJob job, BackupHost host) {
|
|
||||||
try {
|
|
||||||
// Send the request
|
|
||||||
Optional<IServerRequest> maybeRequest = getRequestFromJob(job);
|
|
||||||
if (!maybeRequest.isPresent()) {
|
|
||||||
return JobStatus.CANCELED;
|
|
||||||
}
|
|
||||||
IServerRequest request = maybeRequest.get();
|
|
||||||
Object response = null;
|
|
||||||
try {
|
|
||||||
response = host.sendRequest(request, rateLimiter);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Error when sending request " + request + " to "
|
|
||||||
+ host + " for job " + job.getJobName(), e);
|
|
||||||
return JobStatus.FAILED;
|
|
||||||
}
|
|
||||||
if (response instanceof IServerRequest) {
|
|
||||||
// Route response-request if we got one
|
|
||||||
try {
|
|
||||||
RequestRouter.route((IServerRequest) response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Error when handling response " + response
|
|
||||||
+ " from " + host, e);
|
|
||||||
}
|
|
||||||
} else if (response instanceof GenericResponse) {
|
|
||||||
// Handle generic response if we got one
|
|
||||||
GenericResponse genericResponse = (GenericResponse) response;
|
|
||||||
if (genericResponse.isSuccess()) {
|
|
||||||
logger.debug("Got success response from " + host);
|
|
||||||
} else {
|
|
||||||
logger.warn("Got failure response from " + host + ": "
|
|
||||||
+ genericResponse.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.info("Got unknown type of response from " + host + ": "
|
|
||||||
+ response.toString());
|
|
||||||
}
|
|
||||||
return JobStatus.SUCCESSFUL;
|
|
||||||
} catch (SerializationException e) {
|
|
||||||
logger.error("Error when deserializing stored request for job "
|
|
||||||
+ job.getJobName(), e);
|
|
||||||
return JobStatus.FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<IServerRequest> getRequestFromJob(BackupJob job)
|
|
||||||
throws SerializationException {
|
|
||||||
IServerRequest request = (IServerRequest) DynamicSerializationManager
|
|
||||||
.getManager(SerializationType.Thrift)
|
|
||||||
.deserialize(dao.fetchBlob(job));
|
|
||||||
if (!(request instanceof IRefreshableServerRequest)) {
|
|
||||||
return Optional.of(request);
|
|
||||||
}
|
|
||||||
IRefreshableServerRequest refreshable = (IRefreshableServerRequest) request;
|
|
||||||
Optional<IServerRequest> maybeRequest = refreshable.refresh();
|
|
||||||
if (maybeRequest.isPresent() && maybeRequest.get() != request) {
|
|
||||||
logger.info("Job " + job.getJobName() + " was refreshed");
|
|
||||||
}
|
|
||||||
return maybeRequest;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take a snapshot of enqueued jobs and run them one at a time.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void process() throws Exception {
|
|
||||||
if (!EDEXUtil.isRunning()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
statsReporter.logRun();
|
|
||||||
logger.info("Checking for Backup Service jobs...");
|
|
||||||
BackupServiceConfigManager configMgr = BackupServiceConfigManager
|
|
||||||
.getInstance();
|
|
||||||
configMgr.reload();
|
|
||||||
threadSleepInterval = (int) (configMgr.getPollIntervalSeconds()
|
|
||||||
* TimeUtil.MILLIS_PER_SECOND);
|
|
||||||
if (rateLimiter == null || configMgr.getRateLimitKBps()
|
|
||||||
* SizeUtil.BYTES_PER_KB != rateLimiter.getCapacity()) {
|
|
||||||
rateLimiter = new TokenBucket((int) (configMgr.getRateLimitKBps()
|
|
||||||
* SizeUtil.BYTES_PER_KB));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<BackupHost> hosts = configMgr.getBackupHosts();
|
|
||||||
if (hosts.isEmpty()) {
|
|
||||||
logger.info("No backup sites configured, exiting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long bytesSentThisRun = 0;
|
|
||||||
int requestsSentThisRun = 0;
|
|
||||||
long t0 = System.currentTimeMillis();
|
|
||||||
for (BackupHost host : hosts) {
|
|
||||||
if (EDEXUtil.isShuttingDown()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (BackupJob job : dao.poll(host.getName())) {
|
|
||||||
if (EDEXUtil.isShuttingDown()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Integer versionMatches = host.compareVersion(
|
|
||||||
job.getMinVersionRequired(),
|
|
||||||
job.getMaxVersionRequired());
|
|
||||||
JobStatus jobStatus = JobStatus.DEFERRED;
|
|
||||||
if (versionMatches == null) {
|
|
||||||
logger.warn("Unable to contact " + job.getHost()
|
|
||||||
+ " for version information. Skipping job "
|
|
||||||
+ job.getJobName() + " for this host. "
|
|
||||||
+ "Will try again next time");
|
|
||||||
} else if (versionMatches != 0) {
|
|
||||||
logger.info("Skipping job " + job.getJobName() + " for "
|
|
||||||
+ job.getHost() + " as that server's version ("
|
|
||||||
+ host.getEDEXVersion()
|
|
||||||
+ ") is outside the allowed range ["
|
|
||||||
+ job.getMinVersionRequired() + ", "
|
|
||||||
+ job.getMaxVersionRequired()
|
|
||||||
+ "]. Will try again next time");
|
|
||||||
} else {
|
|
||||||
if (job.getBlobSize() > configMgr.getBigJobSize()) {
|
|
||||||
logger.warn(String.format(
|
|
||||||
"Job %s includes large request (%s)",
|
|
||||||
job.getJobName(),
|
|
||||||
SizeUtil.prettyByteSize(job.getBlobSize())));
|
|
||||||
}
|
|
||||||
jobStatus = runJob(job, host);
|
|
||||||
if (jobStatus == JobStatus.SUCCESSFUL) {
|
|
||||||
/*
|
|
||||||
* TODO this size is not correct anymore. It's only
|
|
||||||
* correct for the request blob as stored in the
|
|
||||||
* database. The request is now gzipped by HttpClient so
|
|
||||||
* we don't know how many bytes are actually being sent.
|
|
||||||
* Also the request could have been refreshed before
|
|
||||||
* sending, which could change the size arbitrarily. So
|
|
||||||
* this stat isn't of much use except as an
|
|
||||||
* approximation.
|
|
||||||
*/
|
|
||||||
bytesSentThisRun += job.getBlobSize();
|
|
||||||
requestsSentThisRun++;
|
|
||||||
dao.removeFinishedJob(job);
|
|
||||||
} else if (jobStatus == JobStatus.CANCELED) {
|
|
||||||
logger.info("Job " + job.getJobName()
|
|
||||||
+ " was canceled on refresh");
|
|
||||||
dao.removeFinishedJob(job);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statsReporter.logProcessedJob(job, jobStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long t1 = System.currentTimeMillis();
|
|
||||||
if (requestsSentThisRun > 0) {
|
|
||||||
logger.info(String.format("Sent %d requests totaling %s in %s.",
|
|
||||||
requestsSentThisRun,
|
|
||||||
SizeUtil.prettyByteSize(bytesSentThisRun),
|
|
||||||
TimeUtil.prettyDuration(t1 - t0)));
|
|
||||||
} else {
|
|
||||||
logger.info("No jobs to run");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EDEXUtil.isShuttingDown() && requestsSentThisRun > 0) {
|
|
||||||
// This is a maintenance task that need not be performed every run
|
|
||||||
dao.cleanUp(configMgr.getHostnamesOnly());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getThreadGroupName() {
|
|
||||||
return "backupServiceThread";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preStop() {
|
|
||||||
super.preStop();
|
|
||||||
|
|
||||||
// Stop any network I/O
|
|
||||||
synchronized (threads) {
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
thread.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump stats report to log and reset accumulated stats. Called via Spring
|
|
||||||
*/
|
|
||||||
public void reportStats() {
|
|
||||||
statsReporter.reportStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.service;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.GetBackupHostCapabilitiesMapRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores BackupService capabilities for this server.
|
|
||||||
*
|
|
||||||
* A "capability" in the BackupService context is just a string associated with
|
|
||||||
* a particular server. EDEX plugins may contribute capabilities by calling
|
|
||||||
* register(). Then anyone (client or server-side) may send a
|
|
||||||
* {@link GetBackupHostCapabilitiesMapRequest} to the server running
|
|
||||||
* BackupService to retrieve a list of all configured backup servers and the
|
|
||||||
* capabilities of each server.
|
|
||||||
*
|
|
||||||
* Example use cases:
|
|
||||||
*
|
|
||||||
* 1. A part of the system that wants to enqueue a backup job may query for a
|
|
||||||
* list of servers that have a particular capability, and only enqueue the job
|
|
||||||
* for those servers.
|
|
||||||
*
|
|
||||||
* 2. Creators of BackupService jobs can tailor a job's IServerRequest to each
|
|
||||||
* individual server, depending on what capabilities each server has.
|
|
||||||
*
|
|
||||||
* Notes:
|
|
||||||
*
|
|
||||||
* - The total number of different capabilities that a server may have is not
|
|
||||||
* enumerable. Any EDEX code can call registerCapability() with any string, and
|
|
||||||
* in doing so create a new capability.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 26, 2017 6352 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupServiceCapabilityManager {
|
|
||||||
|
|
||||||
private static final BackupServiceCapabilityManager INSTANCE = new BackupServiceCapabilityManager();
|
|
||||||
|
|
||||||
private Set<String> capabilities = new HashSet<>();
|
|
||||||
|
|
||||||
private BackupServiceCapabilityManager() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BackupServiceCapabilityManager getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(String capability) {
|
|
||||||
capabilities.add(capability);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return the list of capabilities that this server has */
|
|
||||||
public Set<String> getCapabilities() {
|
|
||||||
return new HashSet<>(capabilities);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.service;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupHost;
|
|
||||||
import com.raytheon.uf.common.util.SizeUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration XML file for backup service
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 2, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
@XmlRootElement(name = "backupServiceConfig")
|
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
|
||||||
public class BackupServiceConfig {
|
|
||||||
@XmlElement(name = "pollIntervalSeconds")
|
|
||||||
private int pollIntervalSeconds = 300;
|
|
||||||
|
|
||||||
@XmlElement(name = "rateLimitKBps")
|
|
||||||
private int rateLimitKBps = 16;
|
|
||||||
|
|
||||||
@XmlElement(name = "bigJobSize")
|
|
||||||
private int bigJobSize = (int) (5 * SizeUtil.BYTES_PER_MB);
|
|
||||||
|
|
||||||
@XmlElementWrapper(name = "hosts", required = true)
|
|
||||||
@XmlElement(name = "host")
|
|
||||||
private List<BackupHost> hosts = new ArrayList<>();
|
|
||||||
|
|
||||||
public List<BackupHost> getHosts() {
|
|
||||||
return hosts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHosts(List<BackupHost> hosts) {
|
|
||||||
this.hosts = hosts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPollIntervalSeconds() {
|
|
||||||
return pollIntervalSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPollIntervalSeconds(int pollIntervalSeconds) {
|
|
||||||
this.pollIntervalSeconds = pollIntervalSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRateLimitKBps() {
|
|
||||||
return rateLimitKBps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRateLimitKBps(int rateLimitKBps) {
|
|
||||||
this.rateLimitKBps = rateLimitKBps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBigJobSize() {
|
|
||||||
return bigJobSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBigJobSize(int bigJobSize) {
|
|
||||||
this.bigJobSize = bigJobSize;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.service;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupHost;
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
|
||||||
import com.raytheon.uf.common.serialization.SerializationException;
|
|
||||||
import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton that manages configuration for backup service
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 16, 2016 5937 tgurney Initial creation
|
|
||||||
* Dec 9, 2016 5937 tgurney Make thread safe. Change reload strategy
|
|
||||||
* Jul 24, 2017 6352 tgurney Host getters return ArrayList
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupServiceConfigManager {
|
|
||||||
|
|
||||||
private static final String SETTINGS_FILE = "backupsvc"
|
|
||||||
+ IPathManager.SEPARATOR + "backupSvc.xml";
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory
|
|
||||||
.getLogger(BackupServiceConfigManager.class);
|
|
||||||
|
|
||||||
private static final BackupServiceConfigManager INSTANCE = new BackupServiceConfigManager();
|
|
||||||
|
|
||||||
private SingleTypeJAXBManager<BackupServiceConfig> jaxbManager;
|
|
||||||
|
|
||||||
private volatile BackupServiceConfig config;
|
|
||||||
|
|
||||||
private BackupServiceConfigManager() {
|
|
||||||
reload();
|
|
||||||
PathManagerFactory.getPathManager()
|
|
||||||
.addLocalizationPathObserver(SETTINGS_FILE, (file) -> {
|
|
||||||
reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BackupServiceConfigManager getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load backup service configuration from the localization XML file. Will
|
|
||||||
* always load the file, regardless of last modified time. If there is an
|
|
||||||
* error when loading the file then we will fall back to the default
|
|
||||||
* configuration which contains no backup hosts.
|
|
||||||
*/
|
|
||||||
public synchronized void reload() {
|
|
||||||
IPathManager pathManager = PathManagerFactory.getPathManager();
|
|
||||||
LocalizationContext siteCtx = pathManager.getContext(
|
|
||||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE);
|
|
||||||
ILocalizationFile file = PathManagerFactory.getPathManager()
|
|
||||||
.getLocalizationFile(siteCtx, SETTINGS_FILE);
|
|
||||||
BackupServiceConfig newConfig = null;
|
|
||||||
try {
|
|
||||||
if (file.exists()) {
|
|
||||||
if (jaxbManager == null) {
|
|
||||||
jaxbManager = new SingleTypeJAXBManager<>(true,
|
|
||||||
BackupServiceConfig.class);
|
|
||||||
}
|
|
||||||
try (InputStream is = file.openInputStream()) {
|
|
||||||
newConfig = jaxbManager.unmarshalFromInputStream(
|
|
||||||
BackupServiceConfig.class, is);
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.debug("Error on stream close", e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Load the default config
|
|
||||||
newConfig = new BackupServiceConfig();
|
|
||||||
}
|
|
||||||
} catch (JAXBException | SerializationException
|
|
||||||
| LocalizationException e) {
|
|
||||||
logger.error("Failed to load settings from " + file.getPath(), e);
|
|
||||||
logger.warn("Falling back to default config with no hosts");
|
|
||||||
newConfig = new BackupServiceConfig();
|
|
||||||
}
|
|
||||||
config = newConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BackupHost> getBackupHosts() {
|
|
||||||
return config.getHosts().stream()
|
|
||||||
.map((aBackupHost) -> new BackupHost(aBackupHost))
|
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getHostnamesOnly() {
|
|
||||||
return config.getHosts().stream().map(BackupHost::getName)
|
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPollIntervalSeconds() {
|
|
||||||
return config.getPollIntervalSeconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBigJobSize() {
|
|
||||||
return config.getBigJobSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRateLimitKBps() {
|
|
||||||
return config.getRateLimitKBps();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.backupsvc.service;
|
|
||||||
|
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
|
||||||
import com.raytheon.uf.common.util.SizeUtil;
|
|
||||||
import com.raytheon.uf.edex.backupsvc.database.BackupJob;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collect and report statistics for BackupService. Thread-safe
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 25, 2017 6352 tgurney Initial creation, extracted from
|
|
||||||
* BackupService
|
|
||||||
* Oct 3, 2019 7929 tgurney Report stats for deferred jobs
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BackupServiceStatsReporter {
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
||||||
|
|
||||||
private Map<BackupService.JobStatus, Integer> processedJobs = new EnumMap<>(
|
|
||||||
BackupService.JobStatus.class);
|
|
||||||
|
|
||||||
private long bytesSent;
|
|
||||||
|
|
||||||
private long lastStatusReportTime;
|
|
||||||
|
|
||||||
private boolean ranSinceLastStatusReport;
|
|
||||||
|
|
||||||
public BackupServiceStatsReporter() {
|
|
||||||
resetStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void resetStats() {
|
|
||||||
bytesSent = 0;
|
|
||||||
processedJobs.clear();
|
|
||||||
for (BackupService.JobStatus status : BackupService.JobStatus
|
|
||||||
.values()) {
|
|
||||||
processedJobs.put(status, 0);
|
|
||||||
}
|
|
||||||
lastStatusReportTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void logProcessedJob(BackupJob job,
|
|
||||||
BackupService.JobStatus status) {
|
|
||||||
bytesSent += job.getBlobSize();
|
|
||||||
int last = processedJobs.get(status);
|
|
||||||
processedJobs.put(status, last + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void logRun() {
|
|
||||||
ranSinceLastStatusReport = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reportStats() {
|
|
||||||
if (!ranSinceLastStatusReport) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BackupServiceConfigManager configMgr = BackupServiceConfigManager
|
|
||||||
.getInstance();
|
|
||||||
ranSinceLastStatusReport = false;
|
|
||||||
String rateLimitText = SizeUtil.prettyByteSize(
|
|
||||||
configMgr.getRateLimitKBps() * SizeUtil.BYTES_PER_KB);
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
String timePeriod = TimeUtil.prettyDuration(now - lastStatusReportTime);
|
|
||||||
logger.info(String.format("Backup service activity for the last %s: ",
|
|
||||||
timePeriod));
|
|
||||||
int totalProcessedJobs = processedJobs.values().stream()
|
|
||||||
.mapToInt(Integer::intValue).sum();
|
|
||||||
for (BackupService.JobStatus status : BackupService.JobStatus
|
|
||||||
.values()) {
|
|
||||||
String msg = status + " jobs: " + processedJobs.get(status) + "/"
|
|
||||||
+ totalProcessedJobs;
|
|
||||||
logger.info(msg);
|
|
||||||
}
|
|
||||||
logger.info("Data sent: " + SizeUtil.prettyByteSize(bytesSent));
|
|
||||||
logger.info("Rate limit: " + rateLimitText + "/s");
|
|
||||||
logger.info("Backup hosts configured: "
|
|
||||||
+ configMgr.getBackupHosts().size());
|
|
||||||
resetStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This base file is not used. It only serves as a template for a site-level
|
|
||||||
file.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<backupServiceConfig xmlns:ns2="group">
|
|
||||||
|
|
||||||
<!-- Hosts are in descending order of priority. Port is optional. -->
|
|
||||||
<!--
|
|
||||||
<hosts>
|
|
||||||
<host>
|
|
||||||
<name>edexcluster-oax</name>
|
|
||||||
<port>9581</port>
|
|
||||||
</host>
|
|
||||||
<host>
|
|
||||||
<name>edexcluster-dmx</name>
|
|
||||||
</host>
|
|
||||||
<host>
|
|
||||||
<name>edexcluster-gid</name>
|
|
||||||
</host>
|
|
||||||
</hosts>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- How often to check for new jobs -->
|
|
||||||
<!-- <pollIntervalSeconds>300</pollIntervalSeconds> -->
|
|
||||||
|
|
||||||
<!-- Limit sending of requests to this many kbytes per second on average -->
|
|
||||||
<!-- <rateLimitKBps>16</rateLimitKBps> -->
|
|
||||||
|
|
||||||
<!-- Log a warning before processing any job bigger than this (bytes) -->
|
|
||||||
<!-- <bigJobSize>5242880</bigJobSize> -->
|
|
||||||
|
|
||||||
</backupServiceConfig>
|
|
|
@ -35,13 +35,6 @@
|
||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.raytheon.uf.edex.backupsvc"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
id="com.raytheon.uf.common.dissemination"
|
id="com.raytheon.uf.common.dissemination"
|
||||||
download-size="0"
|
download-size="0"
|
||||||
|
@ -70,13 +63,6 @@
|
||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.raytheon.uf.common.backupsvc"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
id="com.raytheon.uf.common.sounding"
|
id="com.raytheon.uf.common.sounding"
|
||||||
download-size="0"
|
download-size="0"
|
||||||
|
@ -133,18 +119,4 @@
|
||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.raytheon.uf.edex.localization.backup"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.raytheon.uf.common.localization.backup"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
</feature>
|
</feature>
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
|
||||||
<classpathentry kind="src" path="src"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
|
||||||
</classpath>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>com.raytheon.uf.edex.localization.backup</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.pde.PluginNature</nature>
|
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
|
@ -1,10 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=11
|
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
|
||||||
org.eclipse.jdt.core.compiler.release=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.source=11
|
|
|
@ -1,18 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Bundle-ManifestVersion: 2
|
|
||||||
Bundle-Name: Localization Backup Plug-in
|
|
||||||
Bundle-SymbolicName: com.raytheon.uf.edex.localization.backup
|
|
||||||
Bundle-Version: 1.17.0.qualifier
|
|
||||||
Bundle-Vendor: RAYTHEON
|
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
|
||||||
Bundle-ActivationPolicy: lazy
|
|
||||||
Require-Bundle: com.raytheon.uf.common.status,
|
|
||||||
com.raytheon.uf.common.serialization.comm,
|
|
||||||
org.apache.commons.io,
|
|
||||||
com.raytheon.uf.common.localization.backup,
|
|
||||||
com.raytheon.uf.common.localization,
|
|
||||||
com.raytheon.uf.common.backupsvc,
|
|
||||||
com.raytheon.uf.edex.core,
|
|
||||||
com.raytheon.uf.common.time,
|
|
||||||
org.slf4j,
|
|
||||||
com.raytheon.uf.common.util
|
|
|
@ -1,6 +0,0 @@
|
||||||
source.. = src/
|
|
||||||
output.. = bin/
|
|
||||||
bin.includes = META-INF/,\
|
|
||||||
res/,\
|
|
||||||
utility/,\
|
|
||||||
.,\
|
|
|
@ -1,49 +0,0 @@
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
|
||||||
http://camel.apache.org/schema/spring
|
|
||||||
http://camel.apache.org/schema/spring/camel-spring.xsd">
|
|
||||||
|
|
||||||
<bean id="localizationFileSaveHandler" class="com.raytheon.uf.edex.localization.backup.handlers.LocalizationFileSaveHandler" />
|
|
||||||
<bean factory-bean="handlerRegistry" factory-method="register">
|
|
||||||
<constructor-arg value="com.raytheon.uf.common.localization.backup.request.LocalizationFileSaveRequest"/>
|
|
||||||
<constructor-arg ref="localizationFileSaveHandler"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="localizationFileDeleteHandler" class="com.raytheon.uf.edex.localization.backup.handlers.LocalizationFileDeleteHandler" />
|
|
||||||
<bean factory-bean="handlerRegistry" factory-method="register">
|
|
||||||
<constructor-arg value="com.raytheon.uf.common.localization.backup.request.LocalizationFileDeleteRequest"/>
|
|
||||||
<constructor-arg ref="localizationFileDeleteHandler"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="localizationBackupService" class="com.raytheon.uf.edex.localization.backup.service.LocalizationBackupService" />
|
|
||||||
|
|
||||||
<camelContext id="clusteredLocalizationBackupContext"
|
|
||||||
xmlns="http://camel.apache.org/schema/spring"
|
|
||||||
errorHandlerRef="errorHandler">
|
|
||||||
<endpoint id="localizationBackupReloadCron"
|
|
||||||
uri="quartz://localizationBackupReloadScheduled/?cron=0+0/5+*+*+*+?)"/>
|
|
||||||
|
|
||||||
<route id="localizationBackupReloadScheduled">
|
|
||||||
<from uri="localizationBackupReloadCron" />
|
|
||||||
<doTry>
|
|
||||||
<bean ref="localizationBackupService" method="reloadConfig" />
|
|
||||||
<doCatch>
|
|
||||||
<exception>java.lang.Throwable</exception>
|
|
||||||
<to uri="log:localizationBackupService?level=ERROR"/>
|
|
||||||
</doCatch>
|
|
||||||
</doTry>
|
|
||||||
</route>
|
|
||||||
</camelContext>
|
|
||||||
|
|
||||||
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
|
|
||||||
<constructor-arg ref="clusteredLocalizationBackupContext" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean factory-bean="contextManager" factory-method="registerContextStateProcessor">
|
|
||||||
<constructor-arg ref="clusteredLocalizationBackupContext"/>
|
|
||||||
<constructor-arg ref="localizationBackupService"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
|
|
@ -1,76 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.localization.backup.handlers;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.backup.request.LocalizationFileDeleteRequest;
|
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.response.GenericResponse;
|
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for LocalizationFileDeleteRequest
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 9, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class LocalizationFileDeleteHandler
|
|
||||||
implements IRequestHandler<LocalizationFileDeleteRequest> {
|
|
||||||
|
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
|
||||||
.getHandler(LocalizationFileDeleteHandler.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GenericResponse handleRequest(LocalizationFileDeleteRequest request)
|
|
||||||
throws Exception {
|
|
||||||
IPathManager pathManager = PathManagerFactory.getPathManager();
|
|
||||||
ILocalizationFile file = pathManager
|
|
||||||
.getLocalizationFile(request.getContext(), request.getPath());
|
|
||||||
GenericResponse response = new GenericResponse();
|
|
||||||
try {
|
|
||||||
if (file != null) {
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
response.setSuccess(true);
|
|
||||||
} catch (LocalizationException e) {
|
|
||||||
String msg = "Failed to delete localization file " + file;
|
|
||||||
statusHandler.handle(Priority.PROBLEM, msg, e);
|
|
||||||
response.setSuccess(false);
|
|
||||||
response.setMessage(msg);
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.localization.backup.handlers;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.SaveableOutputStream;
|
|
||||||
import com.raytheon.uf.common.localization.backup.request.LocalizationFileSaveRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.response.GenericResponse;
|
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for LocalizationFileSaveRequest
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 9, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class LocalizationFileSaveHandler
|
|
||||||
implements IRequestHandler<LocalizationFileSaveRequest> {
|
|
||||||
|
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
|
||||||
.getHandler(LocalizationFileSaveHandler.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GenericResponse handleRequest(LocalizationFileSaveRequest request)
|
|
||||||
throws Exception {
|
|
||||||
IPathManager pathManager = PathManagerFactory.getPathManager();
|
|
||||||
ILocalizationFile file = pathManager
|
|
||||||
.getLocalizationFile(request.getContext(), request.getPath());
|
|
||||||
GenericResponse response = new GenericResponse();
|
|
||||||
if (file == null) {
|
|
||||||
response.setSuccess(false);
|
|
||||||
response.setMessage(request.getContext() + IPathManager.SEPARATOR
|
|
||||||
+ request.getPath() + ": Localization file is null");
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
try (SaveableOutputStream outStream = file.openOutputStream()) {
|
|
||||||
try {
|
|
||||||
outStream.write(request.getBytes());
|
|
||||||
outStream.save();
|
|
||||||
response.setSuccess(true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
String msg = "Failed to save localization file " + file;
|
|
||||||
statusHandler.handle(Priority.PROBLEM, msg, e);
|
|
||||||
response.setSuccess(false);
|
|
||||||
response.setMessage(msg);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.localization.backup.service;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Timer;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
|
||||||
import com.raytheon.uf.common.localization.filter.LocalizationFileFilter;
|
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File filter for localization backup service. Uses one whitelist and one
|
|
||||||
* blacklist with optional site override. Automatically reloads filter lists
|
|
||||||
* when changed, and also at a fixed interval (CONFIG_RELOAD_INTERVAL_MS)
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Dec 8, 2016 5937 tgurney Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class LocalizationBackupFileFilter {
|
|
||||||
|
|
||||||
private static final IUFStatusHandler statusHandler = UFStatus
|
|
||||||
.getHandler(LocalizationBackupFileFilter.class);
|
|
||||||
|
|
||||||
private static final String ACCEPT_LIST_PATH = "localizationBackup"
|
|
||||||
+ IPathManager.SEPARATOR + "localizationBackupList.txt";
|
|
||||||
|
|
||||||
private static final String REJECT_LIST_PATH = "localizationBackup"
|
|
||||||
+ IPathManager.SEPARATOR + "localizationBackupBlacklist.txt";
|
|
||||||
|
|
||||||
private static final LocalizationLevel[] SEARCH_LEVELS = new LocalizationLevel[] {
|
|
||||||
LocalizationLevel.BASE, LocalizationLevel.SITE };
|
|
||||||
|
|
||||||
private volatile LocalizationFileFilter filter;
|
|
||||||
|
|
||||||
private final Timer reloadTimer = new Timer();
|
|
||||||
|
|
||||||
private static final long CONFIG_RELOAD_INTERVAL_MS = 5
|
|
||||||
* TimeUtil.MILLIS_PER_MINUTE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor. Immediately loads all filter lists
|
|
||||||
*/
|
|
||||||
public LocalizationBackupFileFilter() {
|
|
||||||
filter = new LocalizationFileFilter();
|
|
||||||
reload();
|
|
||||||
PathManagerFactory.getPathManager()
|
|
||||||
.addLocalizationPathObserver(ACCEPT_LIST_PATH, (file) -> {
|
|
||||||
reload();
|
|
||||||
});
|
|
||||||
PathManagerFactory.getPathManager()
|
|
||||||
.addLocalizationPathObserver(REJECT_LIST_PATH, (file) -> {
|
|
||||||
reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private ILocalizationFile getFile(LocalizationLevel level, String path) {
|
|
||||||
IPathManager pathManager = PathManagerFactory.getPathManager();
|
|
||||||
LocalizationContext ctx = pathManager
|
|
||||||
.getContext(LocalizationType.COMMON_STATIC, level);
|
|
||||||
ILocalizationFile file = pathManager.getLocalizationFile(ctx, path);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reload all filter lists. If any lists fail to load, fall back to an empty
|
|
||||||
* whitelist and an empty blacklist.
|
|
||||||
*/
|
|
||||||
public synchronized void reload() {
|
|
||||||
LocalizationFileFilter newFilter = new LocalizationFileFilter();
|
|
||||||
try {
|
|
||||||
for (LocalizationLevel level : SEARCH_LEVELS) {
|
|
||||||
ILocalizationFile acceptList = getFile(level, ACCEPT_LIST_PATH);
|
|
||||||
if (acceptList != null && acceptList.exists()) {
|
|
||||||
try (InputStream is = acceptList.openInputStream()) {
|
|
||||||
newFilter.addAcceptList(is);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ILocalizationFile rejectList = getFile(level, REJECT_LIST_PATH);
|
|
||||||
if (rejectList != null && rejectList.exists()) {
|
|
||||||
try (InputStream is = rejectList.openInputStream()) {
|
|
||||||
newFilter.addRejectList(is);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException | LocalizationException e) {
|
|
||||||
statusHandler.handle(Priority.PROBLEM, "Failed to load filter list",
|
|
||||||
e);
|
|
||||||
statusHandler.warn("Falling back to empty filter lists");
|
|
||||||
newFilter = new LocalizationFileFilter();
|
|
||||||
}
|
|
||||||
filter = newFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean accept(ILocalizationFile file) {
|
|
||||||
return filter.accept(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,156 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.uf.edex.localization.backup.service;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.backupsvc.BackupHost;
|
|
||||||
import com.raytheon.uf.common.backupsvc.request.BackupEnqueueRequest;
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
|
||||||
import com.raytheon.uf.common.localization.ILocalizationPathObserver;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
|
||||||
import com.raytheon.uf.common.localization.backup.request.LocalizationFileDeleteRequest;
|
|
||||||
import com.raytheon.uf.common.localization.backup.request.LocalizationFileSaveRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
|
||||||
import com.raytheon.uf.common.serialization.comm.RequestRouter;
|
|
||||||
import com.raytheon.uf.edex.core.EDEXUtil;
|
|
||||||
import com.raytheon.uf.edex.core.IContextStateProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service that listens for changes to localization files and pushes changed
|
|
||||||
* files to backup hosts.
|
|
||||||
*
|
|
||||||
* This is a clustered singleton service. It must only be instantiated from
|
|
||||||
* Spring and only in one place.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Nov 9, 2016 5937 tgurney Initial creation
|
|
||||||
* Dec 20, 2016 5937 tgurney Fix reloadConfig() NPE
|
|
||||||
* Jul 20, 2017 6352 tgurney Specify required EDEX version on enqueue
|
|
||||||
* request
|
|
||||||
* Oct 3, 2019 7929 tgurney Set required version to be the sender's
|
|
||||||
* version at the time the job would be
|
|
||||||
* processed (not at the time the job
|
|
||||||
* is created).
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author tgurney
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class LocalizationBackupService implements IContextStateProcessor {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
private LocalizationBackupFileFilter filter;
|
|
||||||
|
|
||||||
private ILocalizationPathObserver pathObserver;
|
|
||||||
|
|
||||||
private IPathManager pathMgr = PathManagerFactory.getPathManager();
|
|
||||||
|
|
||||||
private boolean accept(ILocalizationFile file) {
|
|
||||||
LocalizationContext context = file.getContext();
|
|
||||||
if (context.getLocalizationLevel().equals(LocalizationLevel.BASE)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Only accept SITE and CONFIGURED files if they are for our own site
|
|
||||||
if ((context.getLocalizationLevel().equals(LocalizationLevel.SITE)
|
|
||||||
|| context.getLocalizationLevel()
|
|
||||||
.equals(LocalizationLevel.CONFIGURED))
|
|
||||||
&& !context.getContextName().equals(EDEXUtil.getEdexSite())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!filter.accept(file)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void process(ILocalizationFile file) {
|
|
||||||
if (accept(file)) {
|
|
||||||
try {
|
|
||||||
if (file.exists()) {
|
|
||||||
enqueue(new LocalizationFileSaveRequest(file), file);
|
|
||||||
} else {
|
|
||||||
enqueue(new LocalizationFileDeleteRequest(file), file);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Failed to create backup service job for " + file,
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enqueue(IServerRequest request, ILocalizationFile file)
|
|
||||||
throws Exception {
|
|
||||||
BackupEnqueueRequest enqueueRequest = new BackupEnqueueRequest();
|
|
||||||
enqueueRequest.setJobName("LocalizationBackupService:" + file);
|
|
||||||
enqueueRequest.setPriority(0);
|
|
||||||
enqueueRequest.setRequest(request);
|
|
||||||
enqueueRequest.setMinVersionRequired(BackupHost.MY_VERSION);
|
|
||||||
enqueueRequest.setMaxVersionRequired(BackupHost.MY_VERSION);
|
|
||||||
RequestRouter.route(enqueueRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called from spring to reload at fixed interval */
|
|
||||||
public void reloadConfig() {
|
|
||||||
if (filter != null) {
|
|
||||||
filter.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preStart() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postStart() {
|
|
||||||
if (filter == null) {
|
|
||||||
filter = new LocalizationBackupFileFilter();
|
|
||||||
} else {
|
|
||||||
reloadConfig();
|
|
||||||
}
|
|
||||||
if (pathObserver == null) {
|
|
||||||
pathObserver = this::process;
|
|
||||||
}
|
|
||||||
pathMgr.addLocalizationPathObserver("", pathObserver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preStop() {
|
|
||||||
if (pathObserver != null) {
|
|
||||||
pathMgr.removeLocalizationPathObserver(pathObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postStop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
# This file lists all localization paths that will NOT be sent to backup
|
|
||||||
# sites. This file overrides the whitelist in localizationBackupList.txt.
|
|
||||||
# That is, that file is checked first to determine which files are sent out,
|
|
||||||
# then this file determines which among those are NOT sent. The SITE version of
|
|
||||||
# this file adds to the BASE version, and all other levels are ignored.
|
|
||||||
#
|
|
||||||
# A line that starts with '#' is treated as a comment, and any other line is a
|
|
||||||
# localization level and path:
|
|
||||||
# localization_level:localization_type/subpath/to/file
|
|
||||||
#
|
|
||||||
# A simple example would be
|
|
||||||
# SITE:common_static/textdb/textCategoryClass.txt
|
|
||||||
#
|
|
||||||
# You can use * to match any level, type, or any part of a path. For example,
|
|
||||||
# to match all SITE afos2awips files:
|
|
||||||
# SITE:common_static/afos2awips/*
|
|
||||||
#
|
|
||||||
|
|
||||||
# BASE is hard-coded to never send to backup sites, but is included anyway
|
|
||||||
# for safety.
|
|
||||||
BASE:*
|
|
||||||
WORKSTATION:*
|
|
||||||
USER:*
|
|
|
@ -1,18 +0,0 @@
|
||||||
# This file lists all localization paths that will be sent to backup sites
|
|
||||||
# when a file at any path changes. The SITE version of this file adds to the
|
|
||||||
# BASE version, and all other levels are ignored.
|
|
||||||
#
|
|
||||||
# A line that starts with '#' is treated as a comment, and any other line is a
|
|
||||||
# localization level and path:
|
|
||||||
# localization_level:localization_type/subpath/to/file
|
|
||||||
#
|
|
||||||
# A simple example would be
|
|
||||||
# SITE:common_static/textdb/textCategoryClass.txt
|
|
||||||
#
|
|
||||||
# You can use * to match any level, type, or any part of a path. For example,
|
|
||||||
# to match all SITE afos2awips files:
|
|
||||||
# SITE:common_static/afos2awips/*
|
|
||||||
#
|
|
||||||
# REGION:*
|
|
||||||
# SITE:*
|
|
||||||
# CONFIGURED:*
|
|
Loading…
Add table
Reference in a new issue