VLab Issue #3854 - EDEX plugins for remote script execution
Change-Id: I56c15e3f8c93d1c26c3dd0dc4091ffb21aceff86 Former-commit-id:77a682e24c
[formerly05a81e65d1
] [formerly77a682e24c
[formerly05a81e65d1
] [formerly2eb77074ab
[formerly c02bc1656bf82dea215aba10168f22cab127e9bf]]] Former-commit-id:2eb77074ab
Former-commit-id:47ddfa4f41
[formerly7d15401b0b
] Former-commit-id:32dfd4aaff
This commit is contained in:
parent
cfe098fb87
commit
d5aff9bc6e
27 changed files with 1741 additions and 0 deletions
|
@ -143,4 +143,8 @@
|
|||
id="com.raytheon.uf.edex.dataprovideragent.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.remote.script.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
</feature>
|
||||
|
|
7
edexOsgi/com.raytheon.uf.common.remote.script/.classpath
Normal file
7
edexOsgi/com.raytheon.uf.common.remote.script/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?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.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry excluding="com/raytheon/uf/common/remote/script/data/" kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
edexOsgi/com.raytheon.uf.common.remote.script/.project
Normal file
28
edexOsgi/com.raytheon.uf.common.remote.script/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.common.remote.script</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>
|
|
@ -0,0 +1,11 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
|
@ -0,0 +1,14 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Common
|
||||
Bundle-SymbolicName: com.raytheon.uf.common.remote.script
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RATHEON
|
||||
Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.localization;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.auth;bundle-version="1.12.1174",
|
||||
org.apache.commons.lang;bundle-version="2.3.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.raytheon.uf.common.remote.script
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
/**
|
||||
* Useful constants for remote scripts.
|
||||
* <p>
|
||||
* The resource defaults noted here are the ones defined in this class and are
|
||||
* used when the a property value is not defined. These values can be overridden
|
||||
* for the EDEX server by defining a property value in the EDEX resources file:
|
||||
* com.raytheon.uf.edex.remote.script.properties.
|
||||
* <p>
|
||||
* Except where noted a given run request may override a value. See
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}.
|
||||
*
|
||||
* <pre>
|
||||
* Resource properties:
|
||||
*
|
||||
* KEY VALUES DESCRIPTION
|
||||
* ======================================================
|
||||
* remote.script.directory Localized directories to search for scripts. (default
|
||||
* remoteScripts). Cannot be overridden in a request.
|
||||
* remote.script.timeout Kill script process if it doesn't finish by this
|
||||
* number of seconds (default 30).
|
||||
* remote.script.use.stderr When true separate standard out and standard error
|
||||
* (default false).
|
||||
* remote.script.setup.error Exit error to use when unable to run a script
|
||||
* (default 99).
|
||||
* </pre>
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 12, 2014 #2742 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class RemoteScriptConstants {
|
||||
/**
|
||||
* Resource key to obtain script directory. Cannot be overridden in script
|
||||
* properties. See
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}. .
|
||||
*/
|
||||
public static final String scriptDirectoryKey = "remote.script.directory";
|
||||
|
||||
/**
|
||||
* Resource/Property key to obtain execution timeout in seconds. See @{link
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}.
|
||||
*/
|
||||
public static final String scriptTimeoutKey = "remote.script.timeout";
|
||||
|
||||
/**
|
||||
* Resource/Property key to obtain boolean to separate standard error from
|
||||
* the standard out stream. See
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}.
|
||||
*/
|
||||
public static final String scriptUseStdErrKey = "remote.script.use.stderr";
|
||||
|
||||
/**
|
||||
* Resource/Property key to obtain exit value to use when unable to run the
|
||||
* script.
|
||||
*/
|
||||
public static final String scriptSetupErrrorKey = "remote.script.setup.error";
|
||||
|
||||
/**
|
||||
* Default common static directory for remote scripts. See
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}.
|
||||
*/
|
||||
public static final String scriptDirectoryDefault = "remoteScripts";
|
||||
|
||||
/**
|
||||
* Default time out value in seconds. See
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}.
|
||||
*/
|
||||
public static final String scriptTimeoutDefault = "30";
|
||||
|
||||
/**
|
||||
* Default flag to separate standard error from the standard out stream. See
|
||||
* {@link RemoteScriptRunRequest#putProperty(String, String)}.
|
||||
*/
|
||||
public static final String scriptUseStdErrDefault = "false";
|
||||
|
||||
/**
|
||||
* Error exit value to use when unable to run the script.
|
||||
*/
|
||||
public static final String scriptSetUpErrorDefault = "99";
|
||||
|
||||
private RemoteScriptConstants() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
/**
|
||||
* This class is a request to obtain listing of remote scripts from desired
|
||||
* localization directories.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 13, 2014 2742 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@DynamicSerialize
|
||||
public class RemoteScriptListRequest extends RemoteScriptRequest {
|
||||
|
||||
/**
|
||||
* The contexts to search for scripts.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private LocalizationContext[] contexts;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public RemoteScriptListRequest() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param userId
|
||||
*/
|
||||
public RemoteScriptListRequest(String userId, LocalizationContext[] contexts) {
|
||||
this();
|
||||
setUserId(userId);
|
||||
setContexts(contexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter.
|
||||
*
|
||||
* @return contexts
|
||||
*/
|
||||
public LocalizationContext[] getContexts() {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter.
|
||||
*
|
||||
* @param contexts
|
||||
* - when null contexts is cleared.
|
||||
*/
|
||||
public void setContexts(LocalizationContext[] contexts) {
|
||||
if (contexts != null) {
|
||||
this.contexts = contexts;
|
||||
} else {
|
||||
contexts = new LocalizationContext[0];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("RemoteScriptListRequest {");
|
||||
sb.append("userId: ").append(getUserId());
|
||||
sb.append(", contexts: ").append(getContexts());
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
/**
|
||||
* This contains Localization Context map that is the result of a remote script
|
||||
* list request. The keys are sorted list of the script file names.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 11, 2014 2742 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@DynamicSerialize
|
||||
public class RemoteScriptListResponse {
|
||||
/**
|
||||
* Map of contexts with sorted list of scripts as keys.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private Map<String, List<LocalizationContext>> scripts = new TreeMap<String, List<LocalizationContext>>(
|
||||
String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
public RemoteScriptListResponse() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param scripts
|
||||
*/
|
||||
public RemoteScriptListResponse(
|
||||
Map<String, List<LocalizationContext>> scripts) {
|
||||
setScripts(scripts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter map of scripts' context lists the script keys are sorted.
|
||||
*
|
||||
* @return scripts
|
||||
*/
|
||||
public Map<String, List<LocalizationContext>> getScripts() {
|
||||
return scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter.
|
||||
*
|
||||
* @param scripts
|
||||
* - when null scripts are cleared.
|
||||
*/
|
||||
public void setScripts(Map<String, List<LocalizationContext>> scripts) {
|
||||
this.scripts.clear();
|
||||
if (scripts != null) {
|
||||
this.scripts.putAll(scripts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convince method to a add file's script name and context to scripts.
|
||||
*
|
||||
* @param lFile
|
||||
* @return true if not already in the set
|
||||
*/
|
||||
public boolean add(LocalizationFile lFile) {
|
||||
String script = getName(lFile);
|
||||
LocalizationContext context = lFile.getContext();
|
||||
|
||||
List<LocalizationContext> contexts = scripts.get(script);
|
||||
if (contexts == null) {
|
||||
contexts = new ArrayList<LocalizationContext>();
|
||||
scripts.put(script, contexts);
|
||||
}
|
||||
|
||||
if (!contexts.contains(context)) {
|
||||
contexts.add(context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convince method to remove the file's context from scripts.
|
||||
*
|
||||
* @param true - if file's script and context was in scripts.
|
||||
*/
|
||||
public boolean remove(LocalizationFile lFile) {
|
||||
String name = getName(lFile);
|
||||
List<LocalizationContext> contexts = scripts.get(name);
|
||||
if (contexts == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contexts.remove(contexts)) {
|
||||
if (contexts.size() == 0) {
|
||||
scripts.remove(name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script name of the localized file.
|
||||
*
|
||||
* @param lFile
|
||||
* @return name
|
||||
*/
|
||||
private String getName(LocalizationFile lFile) {
|
||||
String name = lFile.getName().trim();
|
||||
return name.substring(name.lastIndexOf(IPathManager.SEPARATOR) + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return String.format("RemoteScriptListResponse: {scripts: %s}",
|
||||
getScripts());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import com.raytheon.uf.common.auth.req.AbstractPrivilegedRequest;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
/**
|
||||
* Class with common elements for the remote script requests,
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 11, 2014 2742 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
@DynamicSerialize
|
||||
public class RemoteScriptRequest extends AbstractPrivilegedRequest {
|
||||
|
||||
/** User making the request. */
|
||||
@DynamicSerializeElement
|
||||
private String userId;
|
||||
|
||||
/** not authorized message. */
|
||||
@DynamicSerializeElement
|
||||
private String notAuthorizedMessage = "Not Authorized";
|
||||
|
||||
/**
|
||||
* Getter.
|
||||
*
|
||||
* @return userId
|
||||
*/
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter.
|
||||
*
|
||||
* @param userId
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter.
|
||||
*
|
||||
* @return notAuthorizedMessage
|
||||
*/
|
||||
public String getNotAuthorizedMessage() {
|
||||
return notAuthorizedMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter.
|
||||
*
|
||||
* @param notAuthorizedMessage
|
||||
*/
|
||||
public void setNotAuthorizedMessage(String notAuthorizedMessage) {
|
||||
this.notAuthorizedMessage = notAuthorizedMessage;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.text.StrMatcher;
|
||||
import org.apache.commons.lang.text.StrTokenizer;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
/**
|
||||
* This class is a request to run a remote script from desired localization
|
||||
* directory.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 19, 2014 2743 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@DynamicSerialize
|
||||
public class RemoteScriptRunRequest extends RemoteScriptRequest {
|
||||
@DynamicSerializeElement
|
||||
String script;
|
||||
|
||||
@DynamicSerializeElement
|
||||
LocalizationContext context;
|
||||
|
||||
/**
|
||||
* Mapping of resource properties to override. See
|
||||
* {@link RemoteScriptConstants}.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private Map<String, String> propertyMap = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* Command line arguments for the remote script.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private List<String> scriptArguments = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public RemoteScriptRunRequest() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param userId
|
||||
* - user to run the script
|
||||
* @param filename
|
||||
* - script's filename located in the script directory. See
|
||||
* {@link RemoteScriptConstants}.
|
||||
* @param context
|
||||
* - The localize directory's context that contains the script.
|
||||
* See {@link RemoteScriptListResponse#get(String)}
|
||||
*/
|
||||
public RemoteScriptRunRequest(String userId, String script,
|
||||
LocalizationContext context) {
|
||||
this();
|
||||
setUserId(userId);
|
||||
setScript(script);
|
||||
setContext(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context associated with the script's filename. See
|
||||
* {@link RemoteScriptListResponse#get(String)}.
|
||||
*
|
||||
* @return context
|
||||
*/
|
||||
public LocalizationContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context associated with the script's filename. See
|
||||
* {@link RemoteScriptListResponse#get(String)}.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void setContext(LocalizationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for script property map. Recommend this only be used for
|
||||
* serialization, see {@link RemoteScriptConstants}.
|
||||
*
|
||||
* @return propertyMap
|
||||
*/
|
||||
public Map<String, String> getPropertyMap() {
|
||||
return propertyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for script property map. This is used to override the script
|
||||
* property values for handling the script. Recommend this only be used for
|
||||
* serialization, see {@link RemoteScriptConstants}.
|
||||
*
|
||||
* @param propertyMap
|
||||
* - when null map cleared so default values will be used
|
||||
*/
|
||||
public void setPropertyMap(Map<String, String> propertyMap) {
|
||||
this.propertyMap.clear();
|
||||
if (propertyMap != null) {
|
||||
this.propertyMap.putAll(propertyMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default resource property, see {@link RemoteScriptConstants}
|
||||
* .
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return oldValue - previous value for key
|
||||
*/
|
||||
public String putProperty(String key, String value) {
|
||||
return propertyMap.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove property.
|
||||
*
|
||||
* @param key
|
||||
* - property to remove
|
||||
* @return value - Value removed or null if none
|
||||
*/
|
||||
public String removeProperty(String key) {
|
||||
return propertyMap.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of command line arguments for the script in the order sent to
|
||||
* the process builder. See {@link java.lang.ProcessBuilder#command(List)}.
|
||||
* Note the full path name to the script to run will be added by the handler
|
||||
* when sending the request.
|
||||
*
|
||||
* @return scriptArguments
|
||||
*/
|
||||
public List<String> getScriptArguments() {
|
||||
return scriptArguments;
|
||||
}
|
||||
|
||||
public String getScript() {
|
||||
return script;
|
||||
}
|
||||
|
||||
public void setScript(String script) {
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of command line arguments for the script in the order they
|
||||
* are to be sent to the process builder. See
|
||||
* {@link java.lang.ProcessBuilder#command(List)}. Note the full path name
|
||||
* to the script to run will be added by the handler when sending the
|
||||
* request.
|
||||
*
|
||||
* @param scriptArguments
|
||||
*/
|
||||
public void setScriptArguments(List<String> scriptArguments) {
|
||||
this.scriptArguments.clear();
|
||||
if (scriptArguments != null) {
|
||||
this.scriptArguments.addAll(scriptArguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an argument to the script's argument list.
|
||||
*
|
||||
* @param argument
|
||||
* @return success - true when added to the list
|
||||
*/
|
||||
public boolean addScriptArgument(String argument) {
|
||||
return scriptArguments.add(argument);
|
||||
}
|
||||
|
||||
/**
|
||||
* This clears the script argument list and breaks arguments into a list
|
||||
* which becomes the new script argument list. The arguments is split into
|
||||
* tokens delimited by whitespace. A token may be surrounded by single or
|
||||
* double quotes. A quote may be escaped within a quoted section by
|
||||
* duplicating itself.
|
||||
*
|
||||
* <pre>
|
||||
* Examples of lists from java strings:
|
||||
* "a b c" - Three arguments [a, b, c]
|
||||
* "1 'a b c'd 3" - Three arguments [1, a b cd, 3]
|
||||
* "1 \"a b c\"d 3" - Three arguments [1, a b cd, 3]
|
||||
* "1 'a b ''c'''d 3" - Three arguments [1, a b 'c'd, 3]
|
||||
* "1 \"a b \"\"c\"\"\"d 3" - Three arguments [1, a b "c"d, 3]
|
||||
* </pre>
|
||||
*/
|
||||
public void parseAndSetScriptArguments(String arguments) {
|
||||
if (arguments == null || (arguments.trim().length() == 0)) {
|
||||
clearScriptArguements();
|
||||
return;
|
||||
}
|
||||
String[] args = (new StrTokenizer(arguments, StrMatcher.spaceMatcher(),
|
||||
StrMatcher.quoteMatcher())).getTokenArray();
|
||||
setScriptArguments(Arrays.asList(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all arguments from the script's argument list.
|
||||
*/
|
||||
public void clearScriptArguements() {
|
||||
scriptArguments.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(getClass().getName());
|
||||
sb.append("[ userId: ").append(getUserId());
|
||||
sb.append(", script: ").append(getScript());
|
||||
sb.append(", context: ").append(getContext());
|
||||
sb.append(", propertyMap: ").append(propertyMap);
|
||||
sb.append(", scriptArguments: ").append(getScriptArguments());
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
/**
|
||||
* This contains the results from running a remote script.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 19, 2014 2743 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@DynamicSerialize
|
||||
public class RemoteScriptRunResponse {
|
||||
/**
|
||||
* The exit status for the script.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private Integer exitStatus;
|
||||
|
||||
/**
|
||||
* The scripts output either just stdout or a combination of stadout and
|
||||
* stderr. See {@link RemoteScriptConstants}.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private String output = "";
|
||||
|
||||
/**
|
||||
* When requested a separate sting with stderr. See
|
||||
* {@link RemoteScriptConstants}.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private String error = "";
|
||||
|
||||
/**
|
||||
* When true script process timed out and was killed otherwise false. See
|
||||
* {@link RemoteScriptConstants}.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
private boolean timedOut = false;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
public RemoteScriptRunResponse() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exit status for the process running the script.
|
||||
*
|
||||
* @return exitStatus
|
||||
*/
|
||||
public Integer getExitStatus() {
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exit status for script's process. Should only be used by the
|
||||
* handler and serialization.
|
||||
*
|
||||
* @param exitStatus
|
||||
*/
|
||||
public void setExitStatus(Integer exitStatus) {
|
||||
this.exitStatus = exitStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script's output. Based on the request properties this is either
|
||||
* just stdout or a combination of stdout and stderr. See
|
||||
* {@link RemoteScriptConstants}.
|
||||
*
|
||||
* @return output - never null
|
||||
*/
|
||||
public String getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the script's output. Based on the request properties this is either
|
||||
* just stdout or a combination of stdout and stderr. Should only be used by
|
||||
* the handler and serialization. See {@link RemoteScriptConstants}.
|
||||
*
|
||||
* @param output
|
||||
*/
|
||||
public void setOutput(String output) {
|
||||
this.output = (output == null) ? "" : output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get script's stderr when not placed in output.
|
||||
*
|
||||
* @return error - never null
|
||||
*/
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set script's stderr when not place in output. Should only be used by the
|
||||
* handler and serialization.
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
public void setError(String error) {
|
||||
this.error = (error == null) ? "" : error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to indicate script did not finish in the desired number of seconds.
|
||||
* See {@link RemoteScriptConstants}.
|
||||
*
|
||||
* @return true when script process is killed otherwise false
|
||||
*/
|
||||
public boolean isTimedOut() {
|
||||
return timedOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timed out flag. Should only be used by the handler and
|
||||
* serialization. See {@link RemoteScriptConstants}.
|
||||
*
|
||||
* @param timeOut
|
||||
*/
|
||||
public void setTimedOut(boolean timedOut) {
|
||||
this.timedOut = timedOut;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(this.getClass().getName());
|
||||
sb.append("[");
|
||||
sb.append("exitStatus: ").append(getExitStatus());
|
||||
sb.append(", timedOut: ").append(isTimedOut());
|
||||
sb.append(", error: \"").append(getError()).append("\"");
|
||||
sb.append(", output: \"").append(getOutput()).append("\"");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
17
edexOsgi/com.raytheon.uf.edex.remote.script.feature/.project
Normal file
17
edexOsgi/com.raytheon.uf.edex.remote.script.feature/.project
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.edex.remote.script.feature</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.FeatureBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1 @@
|
|||
bin.includes = feature.xml
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="com.raytheon.uf.edex.remote.script.feature"
|
||||
label="Remote Script Feature"
|
||||
version="1.0.0.qualifier"
|
||||
provider-name="RAYTHEON">
|
||||
|
||||
<description url="http://www.example.com/description">
|
||||
[Enter Feature Description here.]
|
||||
</description>
|
||||
|
||||
<copyright url="http://www.example.com/copyright">
|
||||
[Enter Copyright Description here.]
|
||||
</copyright>
|
||||
|
||||
<license url="http://www.example.com/license">
|
||||
[Enter License Description here.]
|
||||
</license>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.edex.remote.script"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.common.remote.script"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
7
edexOsgi/com.raytheon.uf.edex.remote.script/.classpath
Normal file
7
edexOsgi/com.raytheon.uf.edex.remote.script/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?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.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
edexOsgi/com.raytheon.uf.edex.remote.script/.project
Normal file
28
edexOsgi/com.raytheon.uf.edex.remote.script/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.edex.remote.script</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>
|
|
@ -0,0 +1,11 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
|
@ -0,0 +1,18 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: RemoteScript
|
||||
Bundle-SymbolicName: com.raytheon.uf.edex.remote.script
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.localization;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.remote.script;bundle-version="1.0.0",
|
||||
com.raytheon.uf.common.status;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.edex.auth;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.auth;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.util;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.comm;bundle-version="1.12.1174"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Export-Package: com.raytheon.uf.edex.remote.script
|
|
@ -0,0 +1,5 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
res/
|
|
@ -0,0 +1,25 @@
|
|||
<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-3.1.xsd">
|
||||
|
||||
<!-- Instantiate the handler class for RemoteScriptList Handler -->
|
||||
<bean id="RemoteScriptListHandler"
|
||||
class="com.raytheon.uf.edex.remote.script.RemoteScriptListHandler"/>
|
||||
|
||||
<!-- Register the handler class with the RemoteScriptListRequest Register. -->
|
||||
<bean id="remoteScriptListHandlerRegistered" factory-bean="handlerRegistry" factory-method="register">
|
||||
<constructor-arg value="com.raytheon.uf.common.remote.script.RemoteScriptListRequest"/>
|
||||
<constructor-arg ref="RemoteScriptListHandler"/>
|
||||
</bean>
|
||||
|
||||
<!-- Instantiate the handler class for RemoteScriptRun Handler -->
|
||||
<bean id="RemoteScriptRunHandler"
|
||||
class="com.raytheon.uf.edex.remote.script.RemoteScriptRunHandler"/>
|
||||
|
||||
<!-- Register the handler class with the RemoteScriptRunRequest Register. -->
|
||||
<bean id="remoteScriptRunHandlerRegistered" factory-bean="handlerRegistry" factory-method="register">
|
||||
<constructor-arg value="com.raytheon.uf.common.remote.script.RemoteScriptRunRequest"/>
|
||||
<constructor-arg ref="RemoteScriptRunHandler"/>
|
||||
</bean>
|
||||
</beans>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# The values shown here are the default values in the RemoteScriptConstants class.
|
||||
# To change a property's default value for the EDEX server do the following:
|
||||
# 1 - Edit this file and uncomment the desired property line(s).
|
||||
# (remove the # at the start of the line.)
|
||||
# 2 - Change the property's value
|
||||
# 3 - Save the Changes
|
||||
# 4 - Restart EDEX request.
|
||||
|
||||
# The localized directory that contains scripts.
|
||||
remote.script.directory=ncep/remoteScripts
|
||||
|
||||
# Number of seconds to wait for script's process to complete before handler kills the process.
|
||||
# Note the value will be adjusted to be less then the HttpClient's socket timeout value.
|
||||
#remote.script.timeout=30
|
||||
|
||||
# Default use of standard error. When true Separate the standard output and error streams;
|
||||
# otherwise combine them into standard out.
|
||||
#remote.script.use.stderr=false
|
||||
|
||||
# Exit error to use when unable to run a script. Must be an integer.
|
||||
#remote.script.setup.error=99
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import com.raytheon.uf.common.auth.exception.AuthorizationException;
|
||||
import com.raytheon.uf.common.auth.user.IUser;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptConstants;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptRequest;
|
||||
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.ITimer;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
import com.raytheon.uf.edex.auth.AuthManager;
|
||||
import com.raytheon.uf.edex.auth.AuthManagerFactory;
|
||||
import com.raytheon.uf.edex.auth.req.AbstractPrivilegedRequestHandler;
|
||||
import com.raytheon.uf.edex.auth.resp.AuthorizationResponse;
|
||||
import com.raytheon.uf.edex.auth.roles.IRoleStorage;
|
||||
|
||||
/**
|
||||
* Abstract class for the remote script handlers. Performs authorization and
|
||||
* timing of requests.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 12, 2014 2742 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class AbstractRemoteScriptHandler extends
|
||||
AbstractPrivilegedRequestHandler<RemoteScriptRequest> {
|
||||
|
||||
/** Status handler of the handling class using this class. */
|
||||
protected final transient IUFStatusHandler statusHandler;
|
||||
|
||||
/** Common static directory for scripts. */
|
||||
protected final String scriptsDirectory;
|
||||
|
||||
/** The handler's roleId defined in the common remoteScriptAdminRoles.xml */
|
||||
protected final String roleId;
|
||||
|
||||
/**
|
||||
* Application name. This must match the application tag in the user role
|
||||
* file.
|
||||
*/
|
||||
private static final String APPLICATION = "Remote Script";
|
||||
|
||||
/**
|
||||
* Construct.
|
||||
*
|
||||
* @param statusHandler
|
||||
*/
|
||||
public AbstractRemoteScriptHandler(String roleId) {
|
||||
this.statusHandler = UFStatus.getHandler(this.getClass());
|
||||
this.roleId = roleId;
|
||||
|
||||
String scriptsDirectory = FileUtil.edexPath(System.getProperty(
|
||||
RemoteScriptConstants.scriptDirectoryKey,
|
||||
RemoteScriptConstants.scriptDirectoryDefault));
|
||||
|
||||
// Strip tailing separators.
|
||||
if (scriptsDirectory.endsWith(IPathManager.SEPARATOR)) {
|
||||
StringBuilder sb = new StringBuilder(scriptsDirectory);
|
||||
do {
|
||||
sb.setLength(sb.length() - 1);
|
||||
} while ((sb.length() > 0)
|
||||
&& (sb.lastIndexOf(IPathManager.SEPARATOR) == (sb.length() - 1)));
|
||||
scriptsDirectory = sb.toString();
|
||||
}
|
||||
this.scriptsDirectory = scriptsDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method a subclass must implement to perform the work for the desired
|
||||
* request.
|
||||
*
|
||||
* @param request
|
||||
* @return results
|
||||
*/
|
||||
abstract protected Object performRequest(RemoteScriptRequest request);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest
|
||||
* (com.raytheon.uf.common.serialization.comm.IServerRequest)
|
||||
*/
|
||||
@Override
|
||||
public Object handleRequest(RemoteScriptRequest request) throws Exception {
|
||||
Object result = null;
|
||||
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
statusHandler.handle(Priority.INFO, String.format(
|
||||
"Start for %s, do %s", request.getUserId(), getRoleId()));
|
||||
}
|
||||
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
result = performRequest(request);
|
||||
timer.stop();
|
||||
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
statusHandler.handle(
|
||||
Priority.INFO,
|
||||
String.format("Finish for %s, do %s, took %s",
|
||||
request.getUserId(), getRoleId(),
|
||||
TimeUtil.prettyDuration(timer.getElapsedTime())));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the authorization work for the handlers.
|
||||
*
|
||||
* @param user
|
||||
* @param request
|
||||
* @return authorizationResponse
|
||||
* @throws AuthorizationException
|
||||
*/
|
||||
public AuthorizationResponse authorized(IUser user,
|
||||
RemoteScriptRequest request) throws AuthorizationException {
|
||||
AuthManager manager = AuthManagerFactory.getInstance().getManager();
|
||||
IRoleStorage roleStorage = manager.getRoleStorage();
|
||||
|
||||
String roleId = getRoleId();
|
||||
|
||||
boolean authorized = roleStorage.isAuthorized(roleId, user.uniqueId()
|
||||
.toString(), APPLICATION);
|
||||
|
||||
if (authorized) {
|
||||
return new AuthorizationResponse(authorized);
|
||||
} else {
|
||||
String message = "Not Authorized to run " + roleId;
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
statusHandler.handle(Priority.INFO,
|
||||
String.format("%s, %s", user.uniqueId(), message));
|
||||
}
|
||||
return new AuthorizationResponse(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptListRequest;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptListResponse;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptRequest;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
||||
/**
|
||||
* Handler to get the remote script list.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 14, 2014 2742 rferrel Initial creation
|
||||
* Exclude files with md5 checksum extension.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class RemoteScriptListHandler extends AbstractRemoteScriptHandler {
|
||||
|
||||
/** Extension for check sum files to remove from listing. */
|
||||
private final String MD5_EXT = ".md5";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public RemoteScriptListHandler() {
|
||||
// The role id in the common remoteScriptAdminRoles.xml
|
||||
super("remote.script.list");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.edex.remote.script.RemoteScriptHandler#performRequest
|
||||
* (com.raytheon.uf.common.remote.script.RemoteScriptRequest)
|
||||
*/
|
||||
public Object performRequest(RemoteScriptRequest request) {
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
RemoteScriptListRequest req = (RemoteScriptListRequest) request;
|
||||
|
||||
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
|
||||
statusHandler.handle(Priority.DEBUG,
|
||||
String.format("Request: %s", req));
|
||||
}
|
||||
|
||||
LocalizationContext[] ctxs = req.getContexts();
|
||||
|
||||
RemoteScriptListResponse result = new RemoteScriptListResponse();
|
||||
|
||||
for (LocalizationContext ctx : ctxs) {
|
||||
LocalizationFile[] lFiles = pm.listFiles(ctx, scriptsDirectory,
|
||||
null, false, true);
|
||||
if ((lFiles != null) && (lFiles.length > 0)) {
|
||||
for (LocalizationFile lFile : lFiles) {
|
||||
if (!lFile.getName().trim().endsWith(MD5_EXT)) {
|
||||
result.add(lFile);
|
||||
System.out.println(lFile.getFile().getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
|
||||
statusHandler.handle(Priority.DEBUG,
|
||||
String.format("Results: %s", result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
/**
|
||||
* 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.remote.script;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.uf.common.comm.HttpClient;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptConstants;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptRequest;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptRunRequest;
|
||||
import com.raytheon.uf.common.remote.script.RemoteScriptRunResponse;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.RunProcess;
|
||||
|
||||
/**
|
||||
* Handler to Run a remote script and return the results.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 19, 2014 2743 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class RemoteScriptRunHandler extends AbstractRemoteScriptHandler {
|
||||
|
||||
/**
|
||||
* Time to back off from socket time out to allow completion of a timeout
|
||||
* script.
|
||||
*/
|
||||
private static final int BACKOFF_MSEC = 100;
|
||||
|
||||
/**
|
||||
* Resource timeout.
|
||||
*/
|
||||
private final int defaultTimeoutSec;
|
||||
|
||||
/**
|
||||
* Resource flag value.
|
||||
*/
|
||||
private final boolean defaultUseStdErrFlag;
|
||||
|
||||
/**
|
||||
* Resource set up exit status.
|
||||
*/
|
||||
private final int defaultSetupExit;
|
||||
|
||||
/**
|
||||
* Constructor setup roleId and resource property values.
|
||||
*/
|
||||
public RemoteScriptRunHandler() {
|
||||
// The role id in the common remoteScriptAdminRoles.xml
|
||||
super("remote.script.run");
|
||||
|
||||
// Set up default values.
|
||||
String defaultTimeoutStr = System.getProperty(
|
||||
RemoteScriptConstants.scriptTimeoutKey,
|
||||
RemoteScriptConstants.scriptTimeoutDefault);
|
||||
int defaultTimeoutSec = -1;
|
||||
try {
|
||||
defaultTimeoutSec = Integer.parseInt(defaultTimeoutStr);
|
||||
} catch (NumberFormatException ex) {
|
||||
defaultTimeoutSec = -1;
|
||||
} finally {
|
||||
if (defaultTimeoutSec <= 0) {
|
||||
defaultTimeoutSec = Integer
|
||||
.parseInt(RemoteScriptConstants.scriptTimeoutDefault);
|
||||
}
|
||||
this.defaultTimeoutSec = defaultTimeoutSec;
|
||||
}
|
||||
|
||||
String defaultUseStdErr = System.getProperty(
|
||||
RemoteScriptConstants.scriptUseStdErrKey,
|
||||
RemoteScriptConstants.scriptUseStdErrDefault);
|
||||
this.defaultUseStdErrFlag = Boolean.parseBoolean(defaultUseStdErr);
|
||||
|
||||
String defaultSetupErrorStr = System.getProperty(
|
||||
RemoteScriptConstants.scriptSetupErrrorKey,
|
||||
RemoteScriptConstants.scriptUseStdErrDefault);
|
||||
int defaultSetupExit = 0;
|
||||
try {
|
||||
defaultSetupExit = Integer.parseInt(defaultSetupErrorStr);
|
||||
|
||||
} catch (NumberFormatException ex) {
|
||||
defaultSetupExit = 0;
|
||||
} finally {
|
||||
if (defaultSetupExit <= 0) {
|
||||
defaultSetupExit = Integer
|
||||
.parseInt(RemoteScriptConstants.scriptSetUpErrorDefault);
|
||||
}
|
||||
this.defaultSetupExit = defaultSetupExit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest
|
||||
* (com.raytheon.uf.common.serialization.comm.IServerRequest)
|
||||
*/
|
||||
@Override
|
||||
public Object handleRequest(RemoteScriptRequest request) throws Exception {
|
||||
return super.handleRequest(request);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.edex.remote.script.RemoteScriptHandler#performRequest
|
||||
* (com.raytheon.uf.common.remote.script.RemoteScriptRequest)
|
||||
*/
|
||||
public Object performRequest(RemoteScriptRequest request) {
|
||||
RemoteScriptRunRequest req = (RemoteScriptRunRequest) request;
|
||||
RemoteScriptRunResponse result = new RemoteScriptRunResponse();
|
||||
|
||||
Map<String, String> propMap = req.getPropertyMap();
|
||||
|
||||
String timeoutValue = propMap
|
||||
.get(RemoteScriptConstants.scriptTimeoutKey);
|
||||
int timeoutSec = -1;
|
||||
if (timeoutValue == null) {
|
||||
timeoutSec = defaultTimeoutSec;
|
||||
} else {
|
||||
try {
|
||||
timeoutSec = Integer.parseInt(timeoutValue);
|
||||
if (timeoutSec <= 0) {
|
||||
timeoutSec = defaultTimeoutSec;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
String.format("Bad timeout value %s", timeoutValue));
|
||||
timeoutSec = defaultTimeoutSec;
|
||||
} finally {
|
||||
if (timeoutSec <= 0) {
|
||||
timeoutSec = defaultTimeoutSec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long timeout = timeoutSec * TimeUtil.MILLIS_PER_SECOND;
|
||||
|
||||
String useStdErrString = propMap
|
||||
.get(RemoteScriptConstants.scriptUseStdErrKey);
|
||||
|
||||
boolean useStdErr = defaultUseStdErrFlag;
|
||||
if (useStdErrString != null) {
|
||||
useStdErr = Boolean.parseBoolean(useStdErrString);
|
||||
}
|
||||
|
||||
String setupExitValue = propMap
|
||||
.get(RemoteScriptConstants.scriptSetupErrrorKey);
|
||||
int setupExit = -1;
|
||||
|
||||
if (setupExitValue == null) {
|
||||
setupExit = defaultSetupExit;
|
||||
} else {
|
||||
|
||||
try {
|
||||
setupExit = Integer.parseInt(setupExitValue);
|
||||
} catch (NumberFormatException ex) {
|
||||
statusHandler.handle(Priority.PROBLEM, String.format(
|
||||
"Bad setup Error exit value %s", setupExitValue));
|
||||
setupExit = defaultSetupExit;
|
||||
} finally {
|
||||
if (setupExit <= 0) {
|
||||
setupExit = defaultSetupExit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> arguments = req.getScriptArguments();
|
||||
String script = req.getScript();
|
||||
LocalizationContext context = req.getContext();
|
||||
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
String name = scriptsDirectory + IPathManager.SEPARATOR + script;
|
||||
LocalizationFile lFile = pm.getLocalizationFile(context, name);
|
||||
File file = lFile.getFile();
|
||||
File dir = file.getParentFile();
|
||||
|
||||
if (!file.canExecute()) {
|
||||
String message = String.format("Not an executable script: \"%s\".",
|
||||
lFile);
|
||||
return sendMessage(result, message, useStdErr, setupExit);
|
||||
}
|
||||
|
||||
int maxTimeout = HttpClient.getInstance().getSocketTimeout()
|
||||
- BACKOFF_MSEC;
|
||||
if (maxTimeout <= 0) {
|
||||
String message = String
|
||||
.format("HttpClient's socket timeout of %d msec not enough time to run a remote script.",
|
||||
HttpClient.getInstance().getSocketTimeout());
|
||||
return sendMessage(result, message, useStdErr, setupExit);
|
||||
} else if (timeout > maxTimeout) {
|
||||
timeout = maxTimeout;
|
||||
}
|
||||
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add(file.getAbsolutePath());
|
||||
if (arguments != null && (arguments.size() > 0)) {
|
||||
args.addAll(arguments);
|
||||
}
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
pb.redirectErrorStream(!useStdErr);
|
||||
pb.directory(dir);
|
||||
Process p = null;
|
||||
RunProcess rp = RunProcess.getRunProcess();
|
||||
String errorMessage = null;
|
||||
|
||||
// TODO - The timeout/destroy should be placed in RunProcess along with
|
||||
// limiting the size of stdout/stderr.
|
||||
try {
|
||||
p = pb.start();
|
||||
rp.setProcess(p);
|
||||
synchronized (rp) {
|
||||
rp.wait(timeout);
|
||||
if (!rp.isExecComplete()) {
|
||||
p.destroy();
|
||||
result.setTimedOut(true);
|
||||
rp.notify();
|
||||
errorMessage = "Script timed out.";
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
errorMessage = "Problem running script: "
|
||||
+ ex.getLocalizedMessage().trim();
|
||||
statusHandler.handle(Priority.PROBLEM, errorMessage, ex);
|
||||
|
||||
} finally {
|
||||
if (p != null) {
|
||||
result.setOutput(rp.getStdout());
|
||||
result.setError(rp.getStderr());
|
||||
}
|
||||
result.setExitStatus(rp.waitFor());
|
||||
if (errorMessage != null) {
|
||||
if (useStdErr) {
|
||||
result.setError(result.getError() + "\n" + errorMessage);
|
||||
} else {
|
||||
result.setOutput(result.getOutput() + "\n" + errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a problem in running the script.
|
||||
*
|
||||
* @param result
|
||||
* @param message
|
||||
* @param useStdErr
|
||||
* @param setupExit
|
||||
* @return result
|
||||
*/
|
||||
private RemoteScriptRunResponse sendMessage(RemoteScriptRunResponse result,
|
||||
String message, boolean useStdErr, int setupExit) {
|
||||
statusHandler.handle(Priority.PROBLEM, message);
|
||||
|
||||
if (useStdErr) {
|
||||
result.setError(message);
|
||||
} else {
|
||||
result.setOutput(message);
|
||||
}
|
||||
|
||||
result.setExitStatus(setupExit);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<nwsRoleData xmlns:ns2="group">
|
||||
<application>Remote Script</application>
|
||||
<!-- Remote Script List permission.-->
|
||||
<permission id="remote.script.list">
|
||||
<description>
|
||||
This permission allows the user to retrive a listing of remote scripts.
|
||||
</description>
|
||||
</permission>
|
||||
<!-- Remote Script Execute permission. -->
|
||||
<permission id="remote.script.run">
|
||||
<description>
|
||||
This permission allows the user to execute a remote script.
|
||||
</description>
|
||||
</permission>
|
||||
<user userId="ALL">
|
||||
<userPermission>remote.script.list</userPermission>
|
||||
<userPermission>remote.script.run</userPermission>
|
||||
</user>
|
||||
</nwsRoleData>
|
Loading…
Add table
Reference in a new issue