summaryrefslogtreecommitdiffstats
path: root/saltstack-adapter/saltstack-adapter-provider/src
diff options
context:
space:
mode:
Diffstat (limited to 'saltstack-adapter/saltstack-adapter-provider/src')
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java12
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java49
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java200
-rwxr-xr-xsaltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java51
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java51
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java74
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java196
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java36
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java6
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java58
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestConnectionBuilder.java174
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestSaltstackAdapterImpl.java410
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/model/TestJsonParser.java74
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test30
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json29
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json35
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json30
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt30
18 files changed, 1227 insertions, 318 deletions
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java
index 2f70a79af..1cbb495cf 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java
@@ -24,14 +24,14 @@
package org.onap.ccsdk.sli.adaptors.saltstack;
-import java.util.Map;
import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
import org.onap.ccsdk.sli.core.sli.SvcLogicException;
import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import java.util.Map;
+
/**
* This interface defines the operations that the Saltstack adapter exposes.
- *
*/
public interface SaltstackAdapter extends SvcLogicJavaPlugin {
/**
@@ -46,11 +46,16 @@ public interface SaltstackAdapter extends SvcLogicJavaPlugin {
* to context for DGs access, with a certain prefix*/
void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+ /* Method for execution of saltstack SLS command on SaltState server
+ * The response from Saltstack comes in json format and it is automatically put
+ * to context for DGs access, with a certain prefix*/
+ void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+
/* When SLS file is created/available then this Method can be used to post
* the file to saltstack server and execute the SLS file on SaltState server
* The response from Saltstack comes in json format and it is automatically put
* to context for DGs access, with a certain prefix*/
- void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+ void reqExecSLSFile(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
/* Method to get log of a saltState execution request
* The response from Saltstack comes in json format and it is automatically put
@@ -59,6 +64,7 @@ public interface SaltstackAdapter extends SvcLogicJavaPlugin {
/**
* Set the command execution timeout
+ *
* @param timeout time in milliseconds
*/
void setExecTimeout(long timeout);
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java
index 5dee9f5e1..65ab598dd 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java
@@ -24,7 +24,13 @@
package org.onap.ccsdk.sli.adaptors.saltstack.impl;
-import java.io.BufferedOutputStream;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.RandomStringUtils;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -32,15 +38,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
-import java.util.List;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.RandomStringUtils;
-import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
-import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes;
-import org.onap.ccsdk.sli.core.sli.SvcLogicException;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
/**
* Returns a custom SSH client
@@ -88,7 +85,7 @@ public class ConnectionBuilder {
* @return command execution status
*/
public SaltstackResult connectNExecute(String cmd) {
- return connectNExecute(cmd,-1,-1);
+ return connectNExecute(cmd, -1, -1);
}
/**
@@ -96,7 +93,7 @@ public class ConnectionBuilder {
* 2. Exec remote command over SSH. Return command execution status.
* Command output is written to out or err stream.
*
- * @param cmd Commands to execute
+ * @param cmd Commands to execute
* @param retryDelay delay between retry to make a SSH connection.
* @param retryCount number of count retry to make a SSH connection.
* @return command execution status
@@ -113,8 +110,8 @@ public class ConnectionBuilder {
if (result.getStatusCode() != SaltstackResultCodes.SUCCESS.getValue()) {
return result;
}
- String outFilePath = "/tmp/"+ RandomStringUtils.random(5,true,true);
- String errFilePath = "/tmp/"+ RandomStringUtils.random(5,true,true);
+ String outFilePath = "/tmp/" + RandomStringUtils.random(5, true, true);
+ String errFilePath = "/tmp/" + RandomStringUtils.random(5, true, true);
OutputStream out = new FileOutputStream(outFilePath);
OutputStream errs = new FileOutputStream(errFilePath);
result = sshConnection.execCommand(cmd, out, errs);
@@ -137,40 +134,42 @@ public class ConnectionBuilder {
return result;
}
- public SaltstackResult sortExitStatus (int exitStatus, String errFilePath, String cmd) {
+ public SaltstackResult sortExitStatus(int exitStatus, String errFilePath, String cmd) {
SaltstackResult result = new SaltstackResult();
- String err;
+ String err = "";
StringWriter writer = new StringWriter();
try {
IOUtils.copy(new FileInputStream(new File(errFilePath)), writer, "UTF-8");
err = writer.toString();
- } catch (Exception e){
- err = "";
+ } catch (FileNotFoundException e){
+ logger.info("Error stream file doesn't exist");
+ } catch (IOException e){
+ logger.info("Error stream file doesn't exist");
}
if (exitStatus == 255 || exitStatus == 1) {
String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ "]. Exit Code " + exitStatus + " and Error message : " +
- "Malformed configuration. "+ err;
+ "Malformed configuration. " + err;
logger.error(errMessage);
result.setStatusCode(SaltstackResultCodes.INVALID_COMMAND.getValue());
result.setStatusMessage(errMessage);
} else if (exitStatus == 5 || exitStatus == 65) {
String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ "]. Exit Code " + exitStatus + " and Error message : " +
- "Host not allowed to connect. "+ err;
+ "Host not allowed to connect. " + err;
logger.error(errMessage);
result.setStatusCode(SaltstackResultCodes.USER_UNAUTHORIZED.getValue());
result.setStatusMessage(errMessage);
} else if (exitStatus == 67 || exitStatus == 73) {
String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ "]. Exit Code " + exitStatus + " and Error message : " +
- "Key exchange failed. "+ err;
+ "Key exchange failed. " + err;
logger.error(errMessage);
result.setStatusCode(SaltstackResultCodes.CERTIFICATE_ERROR.getValue());
result.setStatusMessage(errMessage);
} else {
String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
- + "]. Exit Code " + exitStatus + " and Error message : "+ err;
+ + "]. Exit Code " + exitStatus + " and Error message : " + err;
logger.error(errMessage);
result.setStatusCode(SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue());
result.setStatusMessage(errMessage);
@@ -183,7 +182,7 @@ public class ConnectionBuilder {
* 2. Exec remote command over SSH. Return command execution status.
* Command output is written to out or err stream.
*
- * @param commands list of commands to execute
+ * @param commands list of commands to execute
* @param payloadSLS has the SLS file location that is to be sent to server
* @param retryDelay delay between retry to make a SSH connection.
* @param retryCount number of count retry to make a SSH connection.
@@ -205,7 +204,7 @@ public class ConnectionBuilder {
/**
* Disconnect from SSH server.
*/
- public SaltstackResult disConnect(){
+ public SaltstackResult disConnect() {
SaltstackResult result = new SaltstackResult();
try {
@@ -225,7 +224,7 @@ public class ConnectionBuilder {
* @param cmd command to execute
* @return command execution status
*/
- public SaltstackResult execute(String cmd) {
+ public SaltstackResult connectNExecuteLog(String cmd) {
SaltstackResult result = new SaltstackResult();
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java
index 5fe130fc7..e3046dba1 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java
@@ -24,11 +24,8 @@
package org.onap.ccsdk.sli.adaptors.saltstack.impl;
-import java.util.Map;
-import java.util.Properties;
-import org.apache.commons.lang.StringUtils;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter;
import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider;
import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackMessageParser;
@@ -37,8 +34,14 @@ import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes;
import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackServerEmulator;
import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
import org.onap.ccsdk.sli.core.sli.SvcLogicException;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
/**
* This class implements the {@link SaltstackAdapter} interface. This interface defines the behaviors
@@ -46,56 +49,45 @@ import com.att.eelf.configuration.EELFManager;
*/
public class SaltstackAdapterImpl implements SaltstackAdapter {
- private static final long EXEC_TIMEOUT = 120000;
- private long timeout = EXEC_TIMEOUT;
-
/**
* The constant used to define the service name in the mapped diagnostic context
*/
@SuppressWarnings("nls")
public static final String MDC_SERVICE = "service";
-
/**
* The constant for the status code for a failed outcome
*/
@SuppressWarnings("nls")
public static final String OUTCOME_FAILURE = "failure";
-
/**
* The constant for the status code for a successful outcome
*/
@SuppressWarnings("nls")
public static final String OUTCOME_SUCCESS = "success";
-
+ public static final String CONNECTION_RETRY_DELAY = "retryDelay";
+ public static final String CONNECTION_RETRY_COUNT = "retryCount";
+ private static final long EXEC_TIMEOUT = 120000;
/**
* Adapter Name
*/
private static final String ADAPTER_NAME = "Saltstack Adapter";
private static final String APPC_EXCEPTION_CAUGHT = "APPCException caught";
-
private static final String RESULT_CODE_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.result.code";
private static final String MESSAGE_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.message";
private static final String RESULTS_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.results";
private static final String ID_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.Id";
private static final String LOG_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.log";
-
- public static final String CONNECTION_RETRY_DELAY = "retryDelay";
- public static final String CONNECTION_RETRY_COUNT = "retryCount";
-
private static final String CLIENT_TYPE_PROPERTY_NAME = "org.onap.appc.adapter.saltstack.clientType";
private static final String SS_SERVER_HOSTNAME = "org.onap.appc.adapter.saltstack.host";
private static final String SS_SERVER_PORT = "org.onap.appc.adapter.saltstack.port";
private static final String SS_SERVER_USERNAME = "org.onap.appc.adapter.saltstack.userName";
private static final String SS_SERVER_PASSWORD = "org.onap.appc.adapter.saltstack.userPasswd";
private static final String SS_SERVER_SSH_KEY = "org.onap.appc.adapter.saltstack.sshKey";
-
-
/**
* The logger to be used
*/
private static final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackAdapterImpl.class);
-
-
+ private long timeout = EXEC_TIMEOUT;
/**
* Connection object
**/
@@ -122,6 +114,7 @@ public class SaltstackAdapterImpl implements SaltstackAdapter {
public SaltstackAdapterImpl() {
initialize(new SaltstackAdapterPropertiesProviderImpl());
}
+
public SaltstackAdapterImpl(SaltstackAdapterPropertiesProvider propProvider) {
initialize(propProvider);
}
@@ -150,9 +143,10 @@ public class SaltstackAdapterImpl implements SaltstackAdapter {
public void setExecTimeout(long timeout) {
this.timeout = timeout;
}
+
/**
- * Method posts info to Context memory in case of an error and throws a
- * SvcLogicException causing SLI to register this as a failure
+ * Method posts info to Context memory in case of an error and throws a
+ * SvcLogicException causing SLI to register this as a failure
*/
@SuppressWarnings("static-method")
private void doFailure(SvcLogicContext svcLogic, int code, String message) throws SvcLogicException {
@@ -160,7 +154,6 @@ public class SaltstackAdapterImpl implements SaltstackAdapter {
svcLogic.setStatus(OUTCOME_FAILURE);
svcLogic.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(code));
svcLogic.setAttribute(MESSAGE_ATTRIBUTE_NAME, message);
-
throw new SvcLogicException("Saltstack Adapter Error = " + message);
}
@@ -222,16 +215,8 @@ public class SaltstackAdapterImpl implements SaltstackAdapter {
logger.info("Initialized Saltstack Adapter");
}
- // Public Method to post single command request to execute saltState. Posts the following back
- // to Svc context memory
- // org.onap.appc.adapter.saltstack.req.code : 100 if successful
- // org.onap.appc.adapter.saltstack.req.messge : any message
- // org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
- @Override
- public void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
- String reqID;
- SaltstackResult testResult;
- if (sshClient == null){
+ private void setSSHClient(Map<String, String> params) throws SvcLogicException {
+ if (sshClient == null) {
logger.info("saltstack-adapter.properties not defined so reading saltstack host and " +
"auth details from DG's parameters");
String sshHost = messageProcessor.reqHostNameResult(params);
@@ -239,59 +224,130 @@ public class SaltstackAdapterImpl implements SaltstackAdapter {
String sshUserName = messageProcessor.reqUserNameResult(params);
String sshPassword = messageProcessor.reqPasswordResult(params);
logger.info("Creating ssh client with BASIC Auth");
- if(!testMode)
+ if (!testMode) {
sshClient = new ConnectionBuilder(sshHost, sshPort, sshUserName, sshPassword);
+ }
}
+ }
+
+ private String putToCommands(SvcLogicContext ctx, String slsFileName,
+ String reqID, String applyTo) throws SvcLogicException {
+ String constructedCommand = "";
try {
- reqID = params.get("Id");
- String commandToExecute = params.get("cmd");
- testResult = execCommand(params, commandToExecute);
- testResult = messageProcessor.parseResponse(ctx, reqID, testResult);
-
- // Check status of test request returned by Agent
- if (testResult.getStatusCode() == SaltstackResultCodes.FINAL_SUCCESS.getValue()) {
- logger.info(String.format("Execution of request-ID : %s successful.", reqID));
- testResult.setResults("Success");
+ File file = new File(slsFileName);
+ InputStream in = new FileInputStream(file);
+ byte[] data = new byte[(int) file.length()];
+ in.read(data);
+ String str = new String(data, "UTF-8");
+ in.close();
+ constructedCommand = "echo "+str+" > /srv/salt/"+reqID+".sls; salt '"+applyTo+"' state.apply "+reqID+" --out=json --static";
+ } catch (FileNotFoundException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input SLS file " +
+ "not found in path : " + slsFileName+". "+ e.getMessage());
+ } catch (IOException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input SLS file " +
+ "error in path : " + slsFileName +". "+ e.getMessage());
+ }
+ logger.info("Command to be executed on server : " + constructedCommand);
+ return constructedCommand;
+ }
+
+ private String putToCommands(String slsName, String applyTo) {
+ String
+ constructedCommand = "cd /srv/salt/; salt '"+applyTo+"' state.apply "+slsName+" --out=json --static";
+
+ logger.info("Command to be executed on server : " + constructedCommand);
+ return constructedCommand;
+ }
+
+ private void checkResponseStatus(SaltstackResult testResult, SvcLogicContext ctx, String reqID, boolean slsExec)
+ throws SvcLogicException {
+
+ // Check status of test request returned by Agent
+ if (testResult.getStatusCode() != SaltstackResultCodes.FINAL_SUCCESS.getValue()) {
+ doFailure(ctx, testResult.getStatusCode(), "Request for execution of command failed. Reason = " + testResult.getStatusMessage());
+ ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID);
+ return;
+ } else {
+ logger.info(String.format("Execution of request : successful."));
+ if (slsExec) {
+ ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(testResult.getStatusCode()));
+ ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, "success");
} else {
- doFailure(ctx, testResult.getStatusCode(), "Request for execution of command failed. Reason = " + testResult.getStatusMessage());
- return;
+ ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(SaltstackResultCodes.CHECK_CTX_FOR_CMD_SUCCESS.getValue()));
+ ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, "check context for execution status");
}
- } catch (SvcLogicException e) {
- logger.error(APPC_EXCEPTION_CAUGHT, e);
- doFailure(ctx, SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue(),
- "Request for execution of command failed. Reason = "
- + e.getMessage());
- return;
- } catch (Exception e) {
- logger.error("Exception caught", e);
- doFailure(ctx, SaltstackResultCodes.INVALID_COMMAND.getValue(),
- "Request for execution of command failed. Reason = "
- + e.getMessage());
- return;
+ ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID);
}
- ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(testResult.getStatusCode()));
- ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, testResult.getResults());
- ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID);
+ }
+
+ // Public Method to post single command request to execute saltState. Posts the following back
+ // to Svc context memory
+ // org.onap.appc.adapter.saltstack.req.code : 100 if successful
+ // org.onap.appc.adapter.saltstack.req.messge : any message
+ // org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
+ @Override
+ public void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+ String reqID;
+ boolean slsExec;
+ SaltstackResult testResult;
+ setSSHClient(params);
+ reqID = messageProcessor.reqId(params);
+ String commandToExecute = messageProcessor.reqCmd(params);
+ slsExec = messageProcessor.reqIsSLSExec(params);
+ testResult = execCommand(params, commandToExecute);
+ testResult = messageProcessor.parseResponse(ctx, reqID, testResult, slsExec);
+ checkResponseStatus(testResult, ctx, reqID, slsExec);
}
/**
- * Public Method to post SLS file request to execute saltState. Posts the following back
+ * Public Method to post SLS command request to execute saltState on server. Posts the following back
* to Svc context memory
- *
- * org.onap.appc.adapter.saltstack.req.code : 100 if successful
+ * <p>
+ * org.onap.appc.adapter.saltstack.req.code : 200 if successful
* org.onap.appc.adapter.saltstack.req.messge : any message
* org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
*/
@Override
public void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
- //TODO: to implement
+ String reqID;
+ SaltstackResult testResult;
+ setSSHClient(params);
+ reqID = messageProcessor.reqId(params);
+ String slsName = messageProcessor.reqSlsName(params);
+ String applyTo = messageProcessor.reqApplyToDevices(params);
+ String commandToExecute = putToCommands(slsName, applyTo);
+ testResult = execCommand(params, commandToExecute);
+ testResult = messageProcessor.parseResponse(ctx, reqID, testResult, true);
+ checkResponseStatus(testResult, ctx, reqID, true);
+ }
+ /**
+ * Public Method to post SLS file request to execute saltState. Posts the following back
+ * to Svc context memory
+ * <p>
+ * org.onap.appc.adapter.saltstack.req.code : 100 if successful
+ * org.onap.appc.adapter.saltstack.req.messge : any message
+ * org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
+ */
+ @Override
+ public void reqExecSLSFile(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+ String reqID;
+ SaltstackResult testResult;
+ setSSHClient(params);
+ reqID = messageProcessor.reqId(params);
+ String slsFile = messageProcessor.reqSlsFile(params);
+ String applyTo = messageProcessor.reqApplyToDevices(params);
+ String commandToExecute = putToCommands(ctx, slsFile, reqID, applyTo);
+ testResult = execCommand(params, commandToExecute);
+ testResult = messageProcessor.parseResponse(ctx, reqID, testResult, true);
+ checkResponseStatus(testResult, ctx, reqID, true);
}
/**
* Public method to get logs from saltState execution for a specific request Posts the following back
* to Svc context memory
- *
+ * <p>
* It blocks till the Saltstack Server responds or the session times out very similar to
* reqExecResult logs are returned in the DG context variable org.onap.appc.adapter.saltstack.log
*/
@@ -301,20 +357,20 @@ public class SaltstackAdapterImpl implements SaltstackAdapter {
}
- public SaltstackResult execCommand(Map<String, String> params, String commandToExecute){
+ public SaltstackResult execCommand(Map<String, String> params, String commandToExecute) {
SaltstackResult testResult;
if (params.get(CONNECTION_RETRY_DELAY) != null && params.get(CONNECTION_RETRY_COUNT) != null) {
int retryDelay = Integer.parseInt(params.get(CONNECTION_RETRY_DELAY));
int retryCount = Integer.parseInt(params.get(CONNECTION_RETRY_COUNT));
- if(!testMode)
+ if (!testMode) {
testResult = sshClient.connectNExecute(commandToExecute, retryCount, retryDelay);
- else {
+ } else {
testResult = testServer.MockReqExec(params);
}
} else {
- if(!testMode)
+ if (!testMode) {
testResult = sshClient.connectNExecute(commandToExecute);
- else {
+ } else {
testResult = testServer.MockReqExec(params);
}
}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java
index 24308851f..a4156558e 100755
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java
@@ -20,13 +20,6 @@
package org.onap.ccsdk.sli.adaptors.saltstack.impl;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Vector;
import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider;
import org.onap.ccsdk.sli.core.sli.ConfigurationException;
import org.onap.ccsdk.sli.core.utils.JREFileResolver;
@@ -37,11 +30,19 @@ import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Vector;
+
/**
* Responsible for determining the properties file to use and instantiating the
* <code>SqlResource</code> Service. The priority for properties file
* resolution is as follows:
- *
+ * <p>
* <ol>
* <li>A directory identified by the system environment variable
* <code>SDNC_CONFIG_DIR</code></li>
@@ -93,8 +94,8 @@ public class SaltstackAdapterPropertiesProviderImpl implements SaltstackAdapterP
properties.load(fileInputStream);
} catch (final IOException e) {
LOG.error("Failed to load properties for file: {}", propertiesFile.toString(),
- new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(),
- e));
+ new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(),
+ e));
}
} else {
// Try to read properties as resource
@@ -124,22 +125,11 @@ public class SaltstackAdapterPropertiesProviderImpl implements SaltstackAdapterP
}
/**
- * Extract svclogic config properties.
- *
- * @return the svclogic config properties
- */
- public Properties getProperties() {
- return properties;
- }
-
- /**
* Reports the method chosen for properties resolution to the
* <code>Logger</code>.
*
- * @param message
- * Some user friendly message
- * @param fileOptional
- * The file location of the chosen properties file
+ * @param message Some user friendly message
+ * @param fileOptional The file location of the chosen properties file
* @return the file location of the chosen properties file
*/
private static File reportSuccess(final String message, final Optional<File> fileOptional) {
@@ -155,10 +145,8 @@ public class SaltstackAdapterPropertiesProviderImpl implements SaltstackAdapterP
* Reports fatal errors. This is the case in which no properties file could be
* found.
*
- * @param message
- * An appropriate fatal error message
- * @param configurationException
- * An exception describing what went wrong during resolution
+ * @param message An appropriate fatal error message
+ * @param configurationException An exception describing what went wrong during resolution
*/
private static void reportFailure(final String message, final ConfigurationException configurationException) {
@@ -166,6 +154,15 @@ public class SaltstackAdapterPropertiesProviderImpl implements SaltstackAdapterP
}
/**
+ * Extract svclogic config properties.
+ *
+ * @return the svclogic config properties
+ */
+ public Properties getProperties() {
+ return properties;
+ }
+
+ /**
* Determines the sql-resource properties file to use based on the following priority:
* <ol>
* <li>A directory identified by the system environment variable
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java
index 41e6102d2..96ed7d2d6 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java
@@ -9,22 +9,23 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
+ *
* ECOMP is a trademark and service mark of AT&T Intellectual Property.
* ============LICENSE_END=========================================================
*/
package org.onap.ccsdk.sli.adaptors.saltstack.impl;
-import org.onap.appc.encryption.EncryptionTool;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
import org.apache.sshd.ClientChannel;
import org.apache.sshd.ClientSession;
import org.apache.sshd.SshClient;
@@ -33,12 +34,9 @@ import org.apache.sshd.client.future.AuthFuture;
import org.apache.sshd.client.future.OpenFuture;
import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.onap.appc.encryption.EncryptionTool;
import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes;
-import org.onap.ccsdk.sli.core.sli.SvcLogicException;
import java.io.OutputStream;
import java.security.KeyPair;
@@ -48,11 +46,11 @@ import java.security.KeyPair;
*/
class SshConnection {
+ public static final int DEFAULT_CONNECTION_RETRY_DELAY = 60;
+ public static final int DEFAULT_CONNECTION_RETRY_COUNT = 5;
private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
-
private static final long AUTH_TIMEOUT = 60000;
private static final long EXEC_TIMEOUT = 120000;
-
private String host;
private int port;
private String username;
@@ -62,9 +60,6 @@ class SshConnection {
private SshClient sshClient;
private ClientSession clientSession;
- public static final int DEFAULT_CONNECTION_RETRY_DELAY = 60;
- public static final int DEFAULT_CONNECTION_RETRY_COUNT = 5;
-
public SshConnection(String host, int port, String username, String password, String keyFile) {
this.host = host;
this.port = port;
@@ -87,13 +82,13 @@ class SshConnection {
sshClient.start();
try {
clientSession =
- sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession();
+ sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession();
if (password != null) {
clientSession.addPasswordIdentity(EncryptionTool.getInstance().decrypt(password));
}
if (keyFile != null) {
- KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[] {
- keyFile
+ KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[]{
+ keyFile
});
KeyPair keyPair = keyPairProvider.loadKeys().iterator().next();
clientSession.addPublicKeyIdentity(keyPair);
@@ -102,18 +97,18 @@ class SshConnection {
authFuture.await(AUTH_TIMEOUT);
if (!authFuture.isSuccess()) {
String errMessage = "Error establishing ssh connection to [" + username + "@" + host + ":" + port
- + "]. Authentication failed.";
+ + "]. Authentication failed.";
result.setStatusCode(SaltstackResultCodes.USER_UNAUTHORIZED.getValue());
result.setStatusMessage(errMessage);
}
} catch (RuntimeException e) {
String errMessage = "Error establishing ssh connection to [" + username + "@" + host + ":" + port + "]." +
- "Runtime Exception : "+ e.getMessage();
+ "Runtime Exception : " + e.getMessage();
result.setStatusCode(SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue());
result.setStatusMessage(errMessage);
} catch (Exception e) {
String errMessage = "Error establishing ssh connection to [" + username + "@" + host + ":" + port + "]." +
- "Host Unknown : " + e.getMessage();
+ "Host Unknown : " + e.getMessage();
result.setStatusCode(SaltstackResultCodes.HOST_UNKNOWN.getValue());
result.setStatusMessage(errMessage);
}
@@ -127,10 +122,12 @@ class SshConnection {
public SaltstackResult connectWithRetry(int retryCount, int retryDelay) {
int retriesLeft;
SaltstackResult result = new SaltstackResult();
- if(retryCount == 0)
- retryCount = DEFAULT_CONNECTION_RETRY_COUNT;
- if(retryDelay == 0)
- retryDelay = DEFAULT_CONNECTION_RETRY_DELAY;
+ if (retryCount == 0) {
+ retryCount = DEFAULT_CONNECTION_RETRY_COUNT;
+ }
+ if (retryDelay == 0) {
+ retryDelay = DEFAULT_CONNECTION_RETRY_DELAY;
+ }
retriesLeft = retryCount + 1;
do {
try {
@@ -142,11 +139,11 @@ class SshConnection {
waitForConnection(retryDelay);
retriesLeft--;
logger.debug("Retrying SSH connection. Attempt [" + Integer.toString(retryCount - retriesLeft + 1)
- + "] out of [" + retryCount + "]");
+ + "] out of [" + retryCount + "]");
} else {
throw e;
}
- }
+ }
} while (retriesLeft > 0);
return result;
}
@@ -207,12 +204,12 @@ class SshConnection {
return result;
} catch (RuntimeException e) {
String errMessage = "Error establishing ssh connection to [" + username + "@" + host + ":" + port + "]." +
- "Runtime Exception : "+ e.getMessage();
+ "Runtime Exception : " + e.getMessage();
result.setStatusCode(SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue());
result.setStatusMessage(errMessage);
} catch (Exception e1) {
String errMessage = "Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" +
- port + "]"+ e1.getMessage();
+ port + "]" + e1.getMessage();
result.setStatusCode(SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue());
result.setStatusMessage(errMessage);
}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java
index f33799fd0..be1fa5747 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java
@@ -8,9 +8,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -44,46 +44,46 @@ public final class JsonParser {
@SuppressWarnings("unchecked")
public static Map<String, String> convertToProperties(String s)
- throws JSONException {
+ throws JSONException {
checkNotNull(s, "Input should not be null.");
- JSONObject json = new JSONObject(s);
- Map<String, Object> wm = new HashMap<>();
- Iterator<String> ii = json.keys();
- while (ii.hasNext()) {
- String key1 = ii.next();
- wm.put(key1, json.get(key1));
- }
-
- Map<String, String> mm = new HashMap<>();
-
- while (!wm.isEmpty())
- for (String key : new ArrayList<>(wm.keySet())) {
- Object o = wm.get(key);
- wm.remove(key);
-
- if (o instanceof Boolean || o instanceof Number || o instanceof String) {
- mm.put(key, o.toString());
-
- log.info("Added property: {} : {}", key, o.toString());
- } else if (o instanceof JSONObject) {
- JSONObject jo = (JSONObject) o;
- Iterator<String> i = jo.keys();
- while (i.hasNext()) {
- String key1 = i.next();
- wm.put(key + "." + key1, jo.get(key1));
- }
- } else if (o instanceof JSONArray) {
- JSONArray ja = (JSONArray) o;
- mm.put(key + "_length", String.valueOf(ja.length()));
+ JSONObject json = new JSONObject(s);
+ Map<String, Object> wm = new HashMap<>();
+ Iterator<String> ii = json.keys();
+ while (ii.hasNext()) {
+ String key1 = ii.next();
+ wm.put(key1, json.get(key1));
+ }
+
+ Map<String, String> mm = new HashMap<>();
+
+ while (!wm.isEmpty())
+ for (String key : new ArrayList<>(wm.keySet())) {
+ Object o = wm.get(key);
+ wm.remove(key);
+
+ if (o instanceof Boolean || o instanceof Number || o instanceof String) {
+ mm.put(key, o.toString());
+
+ log.info("Added property: {} : {}", key, o.toString());
+ } else if (o instanceof JSONObject) {
+ JSONObject jo = (JSONObject) o;
+ Iterator<String> i = jo.keys();
+ while (i.hasNext()) {
+ String key1 = i.next();
+ wm.put(key + "." + key1, jo.get(key1));
+ }
+ } else if (o instanceof JSONArray) {
+ JSONArray ja = (JSONArray) o;
+ mm.put(key + "_length", String.valueOf(ja.length()));
- log.info("Added property: {}_length: {}", key, String.valueOf(ja.length()));
+ log.info("Added property: {}_length: {}", key, String.valueOf(ja.length()));
- for (int i = 0; i < ja.length(); i++)
- wm.put(key + '[' + i + ']', ja.get(i));
- }
+ for (int i = 0; i < ja.length(); i++)
+ wm.put(key + '[' + i + ']', ja.get(i));
}
- return mm;
+ }
+ return mm;
}
}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java
index 1ea315162..372d56574 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java
@@ -28,6 +28,16 @@ package org.onap.ccsdk.sli.adaptors.saltstack.model;
* This module implements the APP-C/Saltstack Server interface
* based on the REST API specifications
*/
+
+import com.google.common.base.Strings;
+import org.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.json.JSONObject;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -39,14 +49,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
-import org.onap.ccsdk.sli.core.sli.SvcLogicException;
-import com.google.common.base.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Class that validates and constructs requests sent/received from
@@ -63,6 +65,12 @@ public class SaltstackMessageParser {
private static final String SS_AGENT_PORT_KEY = "Port";
private static final String PASS_KEY = "Password";
private static final String USER_KEY = "User";
+ private static final String CMD_EXEC = "cmd";
+ private static final String IS_SLS_EXEC = "slsExec";
+ private static final String SS_REQ_ID = "Id";
+ private static final String SLS_FILE_LOCATION = "slsFile";
+ private static final String SLS_NAME = "slsName";
+ private static final String MINION_TO_APPLY = "applyTo";
private static final String LOCAL_PARAMETERS_OPT_KEY = "LocalParameters";
private static final String FILE_PARAMETERS_OPT_KEY = "FileParameters";
@@ -78,12 +86,11 @@ public class SaltstackMessageParser {
* Accepts a map of strings and
* a) validates if all parameters are appropriate (else, throws an exception) and
* b) if correct returns a JSON object with appropriate key-value pairs to send to the server.
- *
+ * <p>
* Mandatory parameters, that must be in the supplied information to the Saltstack Adapter
* 1. URL to connect to
* 2. credentials for URL (assume username password for now)
* 3. SaltState name
- *
*/
public JSONObject reqMessage(Map<String, String> params) throws SvcLogicException {
final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SALTSTATE_NAME_KEY, USER_KEY, PASS_KEY};
@@ -113,7 +120,8 @@ public class SaltstackMessageParser {
*/
public String reqPortResult(Map<String, String> params) throws SvcLogicException {
- final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY, PASS_KEY};
+ final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY,
+ PASS_KEY};
for (String key : mandatoryTestParams) {
throwIfMissingMandatoryParam(params, key);
@@ -128,7 +136,8 @@ public class SaltstackMessageParser {
*/
public String reqHostNameResult(Map<String, String> params) throws SvcLogicException {
- final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY, PASS_KEY};
+ final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY,
+ PASS_KEY};
for (String key : mandatoryTestParams) {
throwIfMissingMandatoryParam(params, key);
@@ -139,11 +148,115 @@ public class SaltstackMessageParser {
/**
* Method that validates that the Map has enough information
* to query Saltstack server for a result. If so, it returns
+ * the appropriate request ID.
+ */
+ public String reqId(Map<String, String> params) {
+
+ if (params.get(SaltstackMessageParser.SS_REQ_ID) == null) {
+ return UUID.randomUUID().toString();
+ } else if (params.get(SaltstackMessageParser.SS_REQ_ID).equalsIgnoreCase("")) {
+ return UUID.randomUUID().toString();
+ }
+ return params.get(SaltstackMessageParser.SS_REQ_ID);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate command to execute.
+ */
+ public String reqCmd(Map<String, String> params) throws SvcLogicException {
+
+ final String[] mandatoryTestParams = {CMD_EXEC, IS_SLS_EXEC};
+
+ for (String key : mandatoryTestParams) {
+ throwIfMissingMandatoryParam(params, key);
+ }
+
+ return params.get(SaltstackMessageParser.CMD_EXEC);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate SLS file location to execute.
+ */
+ public String reqSlsFile(Map<String, String> params) throws SvcLogicException {
+
+ final String[] mandatoryTestParams = {SLS_FILE_LOCATION};
+
+ for (String key : mandatoryTestParams) {
+ throwIfMissingMandatoryParam(params, key);
+ }
+
+ return params.get(SaltstackMessageParser.SLS_FILE_LOCATION);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate SLS file location to execute.
+ */
+ public String reqSlsName(Map<String, String> params) throws SvcLogicException {
+
+ final String[] mandatoryTestParams = {SLS_NAME};
+
+ for (String key : mandatoryTestParams) {
+ throwIfMissingMandatoryParam(params, key);
+ }
+ String slsName = params.get(SaltstackMessageParser.SLS_NAME);
+ if(slsName.substring(slsName.lastIndexOf("."), slsName.length()).equalsIgnoreCase(".sls"))
+ return stripExtension(slsName);
+ return slsName;
+ }
+
+ private String stripExtension (String str) {
+ if (str == null) return null;
+ int pos = str.lastIndexOf(".");
+ if (pos == -1) return str;
+ return str.substring(0, pos);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate minions/vnfc to execute the SLS file to.
+ */
+ public String reqApplyToDevices(Map<String, String> params) {
+
+ if (params.get(SaltstackMessageParser.MINION_TO_APPLY) == null) {
+ return "*";
+ } else if (params.get(SaltstackMessageParser.MINION_TO_APPLY).equalsIgnoreCase("")) {
+ return "*";
+ }
+ return params.get(SaltstackMessageParser.MINION_TO_APPLY);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate IsSLSExec true or false.
+ */
+ public boolean reqIsSLSExec(Map<String, String> params) throws SvcLogicException {
+
+ final String[] mandatoryTestParams = {CMD_EXEC, IS_SLS_EXEC};
+
+ for (String key : mandatoryTestParams) {
+ throwIfMissingMandatoryParam(params, key);
+ }
+
+ return params.get(SaltstackMessageParser.IS_SLS_EXEC).equalsIgnoreCase("true");
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
* the appropriate Saltstack server login user name.
*/
public String reqUserNameResult(Map<String, String> params) throws SvcLogicException {
- final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY, PASS_KEY};
+ final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY,
+ PASS_KEY};
for (String key : mandatoryTestParams) {
throwIfMissingMandatoryParam(params, key);
@@ -158,7 +271,8 @@ public class SaltstackMessageParser {
*/
public String reqPasswordResult(Map<String, String> params) throws SvcLogicException {
- final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY, PASS_KEY};
+ final String[] mandatoryTestParams = {SS_AGENT_HOSTNAME_KEY, SS_AGENT_PORT_KEY, USER_KEY,
+ PASS_KEY};
for (String key : mandatoryTestParams) {
throwIfMissingMandatoryParam(params, key);
@@ -170,8 +284,10 @@ public class SaltstackMessageParser {
* This method parses response from the Saltstack Server when we do a post
* and returns an SaltstackResult object.
*/
- public SaltstackResult parseResponse(SvcLogicContext ctx, String pfx, SaltstackResult saltstackResult) {
+ public SaltstackResult parseResponse(SvcLogicContext ctx, String pfx,
+ SaltstackResult saltstackResult, boolean slsExec) {
int code = saltstackResult.getStatusCode();
+ boolean executionStatus = true, retCodeFound = false;
if (code != SaltstackResultCodes.SUCCESS.getValue()) {
return saltstackResult;
}
@@ -184,20 +300,34 @@ public class SaltstackMessageParser {
in.close();
Map<String, String> mm = JsonParser.convertToProperties(str);
if (mm != null) {
- for (Map.Entry<String,String> entry : mm.entrySet()) {
- ctx.setAttribute(pfx + entry.getKey(), entry.getValue());
- LOGGER.info("+++ " + pfx + entry.getKey() + ": [" + entry.getValue() + "]");
+ for (Map.Entry<String, String> entry : mm.entrySet()) {
+ if (entry.getKey().contains("retcode")) {
+ retCodeFound = true;
+ if (!entry.getValue().equalsIgnoreCase("0")) {
+ executionStatus = false;
+ }
+ }
+ ctx.setAttribute(pfx + "." + entry.getKey(), entry.getValue());
+ LOGGER.info("+++ " + pfx + "." + entry.getKey() + ": [" + entry.getValue() + "]");
}
}
- } catch (FileNotFoundException e){
- return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "Error parsing response file = "
- + saltstackResult.getOutputFileName() + ". Error = " + e.getMessage());
+ } catch (FileNotFoundException e) {
+ return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "error parsing response file "
+ + saltstackResult.getOutputFileName() + " : " + e.getMessage());
} catch (JSONException e) {
LOGGER.info("Output not in JSON format");
return putToProperties(ctx, pfx, saltstackResult);
} catch (Exception e) {
- return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "Error parsing response file = "
- + saltstackResult.getOutputFileName() + ". Error = " + e.getMessage());
+ return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "error parsing response file "
+ + saltstackResult.getOutputFileName() + " : " + e.getMessage());
+ }
+ if (slsExec) {
+ if (!retCodeFound)
+ return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(),
+ "error in parsing response Json after SLS file execution in server");
+ if (!executionStatus)
+ return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(),
+ "error in parsing response Json after SLS file execution in server");
}
saltstackResult.setStatusCode(SaltstackResultCodes.FINAL_SUCCESS.getValue());
return saltstackResult;
@@ -222,8 +352,10 @@ public class SaltstackMessageParser {
saltstackResult = new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "Error parsing response file = "
+ saltstackResult.getOutputFileName() + ". Error = " + e.getMessage());
}
+ saltstackResult.setStatusCode(SaltstackResultCodes.FINAL_SUCCESS.getValue());
return saltstackResult;
}
+
/**
* This method parses response from an Saltstack server when we do a GET for a result
* and returns an SaltstackResult object.
@@ -235,14 +367,14 @@ public class SaltstackMessageParser {
try {
JSONObject postResponse = new JSONObject(input);
saltstackResult = parseGetResponseNested(saltstackResult, postResponse);
- } catch (JSONException e) {
+ } catch (Exception e) {
saltstackResult = new SaltstackResult(SaltstackResultCodes.INVALID_COMMAND.getValue(),
- "Error parsing response = " + input + ". Error = " + e.getMessage(), "", -1);
+ "Error parsing response = " + input + ". Error = " + e.getMessage(), "", -1);
}
return saltstackResult;
}
- private SaltstackResult parseGetResponseNested(SaltstackResult saltstackResult, JSONObject postRsp) throws SvcLogicException {
+ private SaltstackResult parseGetResponseNested(SaltstackResult saltstackResult, JSONObject postRsp) throws SvcLogicException {
int codeStatus = postRsp.getInt(STATUS_CODE_KEY);
String messageStatus = postRsp.getString(STATUS_MESSAGE_KEY);
@@ -253,7 +385,7 @@ public class SaltstackMessageParser {
if (!valCode) {
throw new SvcLogicException("Invalid FinalResponse code = " + codeStatus + " received. MUST be one of "
- + SaltstackResultCodes.CODE.getValidCodes(SaltstackResultCodes.FINALRESPONSE.getValue()));
+ + SaltstackResultCodes.CODE.getValidCodes(SaltstackResultCodes.FINALRESPONSE.getValue()));
}
saltstackResult.setStatusCode(codeStatus);
@@ -285,7 +417,7 @@ public class SaltstackMessageParser {
if (subCode != 200 || !message.equals("SUCCESS")) {
finalCode = SaltstackResultCodes.REQ_FAILURE.getValue();
}
- } catch (JSONException e) {
+ } catch (Exception e) {
saltstackResult.setStatusCode(SaltstackResultCodes.INVALID_RESPONSE.getValue());
saltstackResult.setStatusMessage(String.format(
"Error processing response message = %s from host %s", results.getString(host), host));
@@ -312,10 +444,10 @@ public class SaltstackMessageParser {
//@formatter:off
params.entrySet()
- .stream()
- .filter(entry -> optionalParamsSet.contains(entry.getKey()))
- .filter(entry -> !Strings.isNullOrEmpty(entry.getValue()))
- .forEach(entry -> parseOptionalParam(entry, jsonPayload));
+ .stream()
+ .filter(entry -> optionalParamsSet.contains(entry.getKey()))
+ .filter(entry -> !Strings.isNullOrEmpty(entry.getValue()))
+ .forEach(entry -> parseOptionalParam(entry, jsonPayload));
//@formatter:on
}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java
index 058730240..f6ea0b427 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java
@@ -24,10 +24,8 @@
package org.onap.ccsdk.sli.adaptors.saltstack.model;
-import java.io.OutputStream;
-
/**
- * Simple class to store code and message returned by POST/GET to an Saltstack Server
+ * Simple class to store code and message returned by POST/GET to an Saltstack Server
*/
public class SaltstackResult {
@@ -54,44 +52,44 @@ public class SaltstackResult {
sshExitStatus = sshCode;
}
- public void setStatusCode(int code) {
- this.statusCode = code;
- }
-
- public void setStatusMessage(String message) {
- this.statusMessage = message;
- }
-
- public void setResults(String results) {
- this.results = results;
- }
-
void set(int code, String message, String results) {
this.statusCode = code;
this.statusMessage = message;
this.results = results;
}
- public void setOutputFileName (String out) {
- this.out = out;
- }
-
public String getOutputFileName() {
return out;
}
+ public void setOutputFileName(String out) {
+ this.out = out;
+ }
+
public int getStatusCode() {
return this.statusCode;
}
+ public void setStatusCode(int code) {
+ this.statusCode = code;
+ }
+
public String getStatusMessage() {
return this.statusMessage;
}
+ public void setStatusMessage(String message) {
+ this.statusMessage = message;
+ }
+
public String getResults() {
return this.results;
}
+ public void setResults(String results) {
+ this.results = results;
+ }
+
public int getSshExitStatus() {
return sshExitStatus;
}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java
index ab88c212d..32871ff06 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java
@@ -52,6 +52,8 @@ public enum SaltstackResultCodes {
PENDING(100),
REJECTED(101),
FINAL_SUCCESS(200),
+ CHECK_CTX_FOR_CMD_SUCCESS(250),
+ COMMAND_EXEC_FAILED_STATUS(670),
REQ_FAILURE(401),
MESSAGE(1),
CODE(0),
@@ -67,7 +69,9 @@ public enum SaltstackResultCodes {
SaltstackResultCodes(int value) {
this.value = value;
- };
+ }
+
+ ;
public int getValue() {
return value;
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java
index 9737efd35..ecb36fb83 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java
@@ -32,23 +32,21 @@
package org.onap.ccsdk.sli.adaptors.saltstack.model;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.apache.commons.lang.StringUtils;
+import org.json.JSONObject;
+
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.commons.lang.StringUtils;
-import org.json.JSONException;
-import org.json.JSONObject;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
public class SaltstackServerEmulator {
- private final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackServerEmulator.class);
-
- private static final String SALTSTATE_NAME = "SaltStateName";
+ private static final String SALTSTATE_FILE_NAME = "fileName";
private static final String STATUS_CODE = "StatusCode";
private static final String STATUS_MESSAGE = "StatusMessage";
-
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackServerEmulator.class);
private String saltStateName = "test_saltState.yaml";
/**
@@ -62,9 +60,13 @@ public class SaltstackServerEmulator {
try {
if (params.get("Test") == "fail") {
- result = rejectRequest(result, "Must provide a valid Id");
+ result = rejectRequest(result, "Mocked: Fail");
} else {
- result = acceptRequest(result);
+ String fileName = params.get(SALTSTATE_FILE_NAME);
+ if (fileName == null)
+ result = acceptRequest(result, "");
+ else
+ result = acceptRequest(result, fileName);
}
} catch (Exception e) {
logger.error("JSONException caught", e);
@@ -74,41 +76,10 @@ public class SaltstackServerEmulator {
}
/**
- * Method that emulates the response from an Saltstack Server
- * when presented with a request to execute a saltState
- * Returns an saltstack object result. The response code is always the ssh code 200 (i.e connection successful)
- * payload is json string as would be sent back by Saltstack Server
- **/
- //TODO: This class is to be altered completely based on the SALTSTACK server communicaiton.
- public SaltstackResult Connect(Map<String, String> params) {
- SaltstackResult result = new SaltstackResult();
-
- try {
- // Request must be a JSON object
-
- JSONObject message = new JSONObject();
- if (message.isNull("Id")) {
- rejectRequest(result, "Must provide a valid Id");
- } else if (message.isNull(SALTSTATE_NAME)) {
- rejectRequest(result, "Must provide a saltState Name");
- } else if (!message.getString(SALTSTATE_NAME).equals(saltStateName)) {
- rejectRequest(result, "SaltState " + message.getString(SALTSTATE_NAME) + " not found in catalog");
- } else {
- acceptRequest(result);
- }
- } catch (JSONException e) {
- logger.error("JSONException caught", e);
- rejectRequest(result, e.getMessage());
- }
- return result;
- }
-
- /**
* Method to emulate response from an Saltstack
* Server when presented with a GET request
* Returns an saltstack object result. The response code is always the ssh code 200 (i.e connection successful)
* payload is json string as would be sent back by Saltstack Server
- *
**/
public SaltstackResult Execute(String agentUrl) {
@@ -149,9 +120,10 @@ public class SaltstackServerEmulator {
return result;
}
- private SaltstackResult acceptRequest(SaltstackResult result) {
+ private SaltstackResult acceptRequest(SaltstackResult result, String fileName) {
result.setStatusCode(SaltstackResultCodes.SUCCESS.getValue());
result.setStatusMessage("Success");
+ result.setOutputFileName(fileName);
return result;
}
} \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestConnectionBuilder.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestConnectionBuilder.java
new file mode 100644
index 000000000..d9a384141
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestConnectionBuilder.java
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.saltstack.impl.ConnectionBuilder;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class TestConnectionBuilder {
+
+ private final String PENDING = "100";
+ private final String SUCCESS = "400";
+ private String message = "{\"Results\":{\"192.168.1.10\":{\"Id\":\"101\",\"StatusCode\":200,\"StatusMessage\":\"SUCCESS\"}},\"StatusCode\":200,\"StatusMessage\":\"FINISHED\"}";
+
+ private ConnectionBuilder connBuilder;
+ private String TestId;
+ private boolean testMode = true;
+ private Map<String, String> params;
+ private SvcLogicContext svcContext;
+
+
+ @Before
+ public void setup() throws IllegalArgumentException {
+ testMode = true;
+ svcContext = new SvcLogicContext();
+ String HostName = "test";
+ String Port = "10";
+ String User = "test";
+ String Password = "test";
+ connBuilder = new ConnectionBuilder(HostName, Port, User, Password);
+
+ params = new HashMap<>();
+ params.put("AgentUrl", "https://192.168.1.1");
+ params.put("User", "test");
+ params.put("Password", "test");
+ }
+
+ @After
+ public void tearDown() {
+ testMode = false;
+ connBuilder = null;
+ params = null;
+ svcContext = null;
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus255() {
+
+ int exitStatus = 255;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(698, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus1() {
+
+ int exitStatus = 1;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(698, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus5() {
+
+ int exitStatus = 5;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus65() {
+
+ int exitStatus = 65;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus67() {
+
+ int exitStatus = 5;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus73() {
+
+ int exitStatus = 65;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatusUnknown() {
+
+ int exitStatus = 5121;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(699, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatusNoFile() {
+
+ int exitStatus = 65;
+ String errFilePath = "src/test/resource/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestSaltstackAdapterImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestSaltstackAdapterImpl.java
index d7b330387..c8776fb8d 100644
--- a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestSaltstackAdapterImpl.java
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/impl/TestSaltstackAdapterImpl.java
@@ -82,7 +82,7 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "fail");
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("101", status);
}
@@ -96,7 +96,7 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "fail");
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("101", status);
}
@@ -110,7 +110,7 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "fail");
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("101", status);
}
@@ -124,7 +124,7 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "fail");
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("101", status);
}
@@ -138,7 +138,7 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "fail");
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("101", status);
}
@@ -149,24 +149,25 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "fail");
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("101", status);
}
@Test(expected = SvcLogicException.class)
- public void reqExecCommand_shouldSetSuccess() throws SvcLogicException,
+ public void reqExecCommand_NoResponseFile() throws SvcLogicException,
IllegalStateException, IllegalArgumentException {
- params.put("PlaybookName", "test_playbook.yaml");
params.put("HostName", "test");
params.put("Port", "10");
params.put("User", "test");
params.put("Password", "test");
params.put("Test", "success");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
try {
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("400", status);
} catch (NullPointerException e) {
fail(e.getMessage() + " Unknown exception encountered ");
@@ -174,10 +175,9 @@ public class TestSaltstackAdapterImpl {
}
@Test(expected = SvcLogicException.class)
- public void reqExecCommand_shouldSetSuccessWithRetry() throws SvcLogicException,
+ public void reqExecCommand_NoResponseFileWithRetry() throws SvcLogicException,
IllegalStateException, IllegalArgumentException {
- params.put("PlaybookName", "test_playbook.yaml");
params.put("HostName", "test");
params.put("Port", "10");
params.put("User", "test");
@@ -185,10 +185,12 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "success");
params.put("retryDelay", "10");
params.put("retryCount", "10");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
try {
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("400", status);
} catch (NullPointerException e) {
fail(e.getMessage() + " Unknown exception encountered ");
@@ -196,10 +198,9 @@ public class TestSaltstackAdapterImpl {
}
@Test(expected = SvcLogicException.class)
- public void reqExecCommand_shouldSetSuccessWithRetryZero() throws SvcLogicException,
+ public void reqExecCommand_NoResponseFileWithRetryZero() throws SvcLogicException,
IllegalStateException, IllegalArgumentException {
- params.put("PlaybookName", "test_playbook.yaml");
params.put("HostName", "test");
params.put("Port", "10");
params.put("User", "test");
@@ -207,10 +208,12 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "success");
params.put("retryDelay", "0");
params.put("retryCount", "0");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
try {
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("400", status);
} catch (NullPointerException e) {
fail(e.getMessage() + " Unknown exception encountered ");
@@ -218,10 +221,9 @@ public class TestSaltstackAdapterImpl {
}
@Test(expected = SvcLogicException.class)
- public void reqExecCommand_shouldSetSuccessWithNoRetry() throws SvcLogicException,
+ public void reqExecCommand_NoResponseFileWithNoRetry() throws SvcLogicException,
IllegalStateException, IllegalArgumentException {
- params.put("PlaybookName", "test_playbook.yaml");
params.put("HostName", "test");
params.put("Port", "10");
params.put("User", "test");
@@ -229,38 +231,382 @@ public class TestSaltstackAdapterImpl {
params.put("Test", "success");
params.put("retryDelay", "-1");
params.put("retryCount", "-1");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
+
try {
adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.Id");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
assertEquals("400", status);
} catch (NullPointerException e) {
fail(e.getMessage() + " Unknown exception encountered ");
}
}
- @Test
- public void reqExecSLS_shouldSetSuccess() throws IllegalStateException, IllegalArgumentException {
- params.put("Id", "100");
-
- for (String ukey : params.keySet()) {
- System.out.println(String.format("Saltstack Parameter %s = %s", ukey, params.get(ukey)));
- }
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailure() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("cmd", "test");
+ params.put("slsExec", "test");
+ params.put("Test", "fail");
try {
- adapter.reqExecSLS(params, svcContext);
- String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- //assertEquals(SUCCESS, status);
- assertEquals(null, status);
- } catch (SvcLogicException e) {
+ adapter.reqExecCommand(params, svcContext);
String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
- fail(e.getMessage() + " Code = " + status);
- } catch (Exception e) {
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("400", status);
+ } catch (NullPointerException e) {
fail(e.getMessage() + " Unknown exception encountered ");
}
}
@Test
+ public void reqExecCommand_shouldSetSuccessNoSLS() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("250", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessExecSLS() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+ params.put("slsExec", "true");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailExecSLS() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+ params.put("slsExec", "true");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileTxt() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.txt");
+ params.put("Id", "txt");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("250", status);
+ assertEquals(TestId, "txt");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileNoExtension() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test");
+ params.put("Id", "txt");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("250", status);
+ assertEquals(TestId, "txt");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileInvalidJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test-invalid.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("250", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailFileInvalidFile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecCommand(params, svcContext);
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileJsonNoReqID() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.json");
+ params.put("cmd", "test");
+ params.put("slsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("250", status);
+ }
+
+ @Test
+ public void reqExecSLSFile_shouldSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_NoSLSfile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test-none.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_NoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecSLSFile_WithMinionSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+ params.put("applyTo", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithMinionNoSLSfile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test-none.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("applyTo", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithMinionNoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+ params.put("applyTo", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecSLSFile_WithAllMinionSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("cmd", "test");
+ params.put("applyTo", "*");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithAllMinionNoSLSfile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test-none.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("applyTo", "*");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithAllMinionNoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("slsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+ params.put("applyTo", "*");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
public void reqExecLog_shouldSetMessage() throws IllegalStateException, IllegalArgumentException {
params.put("Id", "101");
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/model/TestJsonParser.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/model/TestJsonParser.java
new file mode 100644
index 000000000..ae13da6c8
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/appc/adapter/model/TestJsonParser.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.model;
+
+import org.codehaus.jettison.json.JSONException;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.JsonParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class TestJsonParser {
+
+ private static final Logger log = LoggerFactory.getLogger(TestJsonParser.class);
+
+ @Test
+ public void test() throws SvcLogicException, IOException, JSONException {
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(ClassLoader.getSystemResourceAsStream("test.json"))
+ );
+ StringBuilder b = new StringBuilder();
+ String line;
+ while ((line = in.readLine()) != null)
+ b.append(line).append('\n');
+
+ Map<String, String> mm = JsonParser.convertToProperties(b.toString());
+
+ logProperties(mm);
+
+ in.close();
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNullString() throws SvcLogicException, JSONException {
+ JsonParser.convertToProperties(null);
+ }
+
+ private void logProperties(Map<String, String> mm) {
+ List<String> ll = new ArrayList<>();
+ for (Object o : mm.keySet())
+ ll.add((String) o);
+ Collections.sort(ll);
+ log.info("Properties:");
+ for (String name : ll)
+ log.info("--- {}: {}", name, mm.get(name));
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test
new file mode 100644
index 000000000..dec578bd9
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test
@@ -0,0 +1,30 @@
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos2v-queueing-code = P
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos3-queueing-code = W
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2v-queueing = QueueLimit
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos3-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2v-shaping = Enable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos3-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2-shaping-code = W
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2v-shaping-code = P
+service-configuration-notification-input.ack-final-indicator = Y
+service-configuration-notification-input.response-code = 0
+service-configuration-notification-input.response-message = Plc Activation Failed: Device gblond2005me6 Sync-from Failed. Please check device IP address and NCS setup.
+service-configuration-notification-input.service-information.service-instance-id = TEST7
+service-configuration-notification-input.service-information.service-type = AVPN
+service-configuration-notification-input.svc-request-id = TEST7
+service-data.avpn-ip-port-information.avpn-access-information.access-circuit-id = DHEC.54831.170.ATI
+service-data.avpn-ip-port-information.avpn-access-information.access-interface = _1G
+service-data.avpn-ip-port-information.avpn-access-information.access-speed = 10000
+service-data.avpn-ip-port-information.avpn-access-information.access-speed-units = Kbps
+service-data.avpn-ip-port-information.avpn-access-information.l1-customer-handoff = _1000BASELX
+service-data.avpn-ip-port-information.avpn-access-information.managed-ce = N
+service-data.avpn-ip-port-information.avpn-access-information.vlan-tag-control = _1Q
+service-data.avpn-ip-port-information.clli = LONDENEH
+service-data.avpn-ip-port-information.contracted-port-speed = 10000
+service-data.avpn-ip-port-information.contracted-port-speed-units = Kbps
+service-data.avpn-ip-port-information.endpoint-information.bundle-id = 33
+service-data.avpn-ip-port-information.endpoint-information.interface-string = ae0
+service-data.service-information.service-instance-id = ICORESITE-2751508
+service-data.service-information.service-type = AVPN
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json
new file mode 100644
index 000000000..53158cada
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json
@@ -0,0 +1,29 @@
+"equipment-data": [
+{
+"server-count": "4",
+"max-server-speed": "1600000",
+"number-primary-servers": "2",
+"equipment-id": "Server1",
+"server-model": "Unknown",
+"server-id": "Server1",
+"test-node" : {
+"test-inner-node" : "Test-Value"
+}
+}
+],
+"resource-state": {
+"threshold-value": "1600000",
+"last-added": "1605000",
+"used": "1605000",
+"limit-value": "1920000"
+},
+"resource-rule": {
+"endpoint-position": "VCE-Cust",
+"soft-limit-expression": "0.6 * max-server-speed * number-primary-servers",
+"resource-name": "Bandwidth",
+"service-model": "DUMMY",
+"hard-limit-expression": "max-server-speed * number-primary-servers",
+"equipment-level": "Server"
+},
+"message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity."
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json
new file mode 100644
index 000000000..bc1c10c8d
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json
@@ -0,0 +1,35 @@
+{
+ "minion1": {
+ "retcode": 0,
+ "pkg_|-install_network_packages_|-install_network_packages_|-installed": {
+ "comment": "The following packages were installed/updated: lftp\nThe following packages were already installed: rsync, curl",
+ "name": "install_network_packages",
+ "start_time": "08:47:16.061765",
+ "result": true,
+ "duration": 11086.334,
+ "__run_num__": 0,
+ "__sls__": "nettools",
+ "changes": {
+ "lftp": {
+ "new": "4.6.3a-1build2",
+ "old": ""
+ }
+ },
+ "__id__": "install_network_packages"
+ }
+ },
+ "minion2": {
+ "retcode": 0,
+ "pkg_|-install_network_packages_|-install_network_packages_|-installed": {
+ "comment": "All specified packages are already installed",
+ "name": "curl",
+ "start_time": "08:47:16.152099",
+ "result": true,
+ "duration": 426.493,
+ "__run_num__": 0,
+ "__sls__": "nettools",
+ "changes": {},
+ "__id__": "install_network_packages"
+ }
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json
new file mode 100644
index 000000000..cd76486aa
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json
@@ -0,0 +1,30 @@
+{
+ "equipment-data": [
+ {
+ "server-count": "4",
+ "max-server-speed": "1600000",
+ "number-primary-servers": "2",
+ "equipment-id": "Server1",
+ "server-model": "Unknown",
+ "server-id": "Server1",
+ "test-node" : {
+ "test-inner-node" : "Test-Value"
+ }
+ }
+ ],
+ "resource-state": {
+ "threshold-value": "1600000",
+ "last-added": "1605000",
+ "used": "1605000",
+ "limit-value": "1920000"
+ },
+ "resource-rule": {
+ "endpoint-position": "VCE-Cust",
+ "soft-limit-expression": "0.6 * max-server-speed * number-primary-servers",
+ "resource-name": "Bandwidth",
+ "service-model": "DUMMY",
+ "hard-limit-expression": "max-server-speed * number-primary-servers",
+ "equipment-level": "Server"
+ },
+ "message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity."
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt
new file mode 100644
index 000000000..dec578bd9
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt
@@ -0,0 +1,30 @@
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos2v-queueing-code = P
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos3-queueing-code = W
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2v-queueing = QueueLimit
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos3-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2v-shaping = Enable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos3-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2-shaping-code = W
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2v-shaping-code = P
+service-configuration-notification-input.ack-final-indicator = Y
+service-configuration-notification-input.response-code = 0
+service-configuration-notification-input.response-message = Plc Activation Failed: Device gblond2005me6 Sync-from Failed. Please check device IP address and NCS setup.
+service-configuration-notification-input.service-information.service-instance-id = TEST7
+service-configuration-notification-input.service-information.service-type = AVPN
+service-configuration-notification-input.svc-request-id = TEST7
+service-data.avpn-ip-port-information.avpn-access-information.access-circuit-id = DHEC.54831.170.ATI
+service-data.avpn-ip-port-information.avpn-access-information.access-interface = _1G
+service-data.avpn-ip-port-information.avpn-access-information.access-speed = 10000
+service-data.avpn-ip-port-information.avpn-access-information.access-speed-units = Kbps
+service-data.avpn-ip-port-information.avpn-access-information.l1-customer-handoff = _1000BASELX
+service-data.avpn-ip-port-information.avpn-access-information.managed-ce = N
+service-data.avpn-ip-port-information.avpn-access-information.vlan-tag-control = _1Q
+service-data.avpn-ip-port-information.clli = LONDENEH
+service-data.avpn-ip-port-information.contracted-port-speed = 10000
+service-data.avpn-ip-port-information.contracted-port-speed-units = Kbps
+service-data.avpn-ip-port-information.endpoint-information.bundle-id = 33
+service-data.avpn-ip-port-information.endpoint-information.interface-string = ae0
+service-data.service-information.service-instance-id = ICORESITE-2751508
+service-data.service-information.service-type = AVPN