Merge pull request #563 from tiffanycmeyer13/unidata_20.3.2
Removed multiple EDEX plugins from feature.xml.
This commit is contained in:
commit
9b6adc5b90
61 changed files with 2 additions and 3699 deletions
|
@ -34,18 +34,6 @@
|
|||
name="AAG"
|
||||
value="aviation/aag">
|
||||
</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
|
||||
application="EDEX"
|
||||
localizationType="COMMON_STATIC"
|
||||
|
|
|
@ -241,10 +241,6 @@
|
|||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.text.feature" />
|
||||
</antcall>
|
||||
<antcall target="build">
|
||||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.aviation.feature" />
|
||||
</antcall>
|
||||
<antcall target="build">
|
||||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.satellite.feature" />
|
||||
|
@ -261,6 +257,7 @@
|
|||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.radar.feature" />
|
||||
</antcall>
|
||||
<!--
|
||||
<antcall target="build">
|
||||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.hydro.feature" />
|
||||
|
@ -273,6 +270,7 @@
|
|||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.dat.feature" />
|
||||
</antcall>
|
||||
-->
|
||||
<antcall target="build">
|
||||
<param name="feature"
|
||||
value="com.raytheon.uf.edex.config.auto.feature" />
|
||||
|
|
|
@ -224,10 +224,6 @@
|
|||
id="com.raytheon.uf.edex.text.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.aviation.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.satellite.feature"
|
||||
version="0.0.0"/>
|
||||
|
@ -236,18 +232,10 @@
|
|||
id="com.raytheon.uf.edex.gfe.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.hydro.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.radar.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.dat.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.ncep.feature"
|
||||
version="0.0.0"/>
|
||||
|
@ -272,10 +260,6 @@
|
|||
id="com.raytheon.uf.edex.config.auto.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.mpe.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.menus.vb.feature"
|
||||
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"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.edex.backupsvc"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.common.dissemination"
|
||||
download-size="0"
|
||||
|
@ -70,13 +63,6 @@
|
|||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.common.backupsvc"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.common.sounding"
|
||||
download-size="0"
|
||||
|
@ -133,18 +119,4 @@
|
|||
version="0.0.0"
|
||||
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>
|
||||
|
|
|
@ -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