diff options
Diffstat (limited to 'sshapi-call-node/provider/src/main')
12 files changed, 1454 insertions, 0 deletions
diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/SshApiCallNode.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/SshApiCallNode.java new file mode 100644 index 000000000..146188fb9 --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/SshApiCallNode.java @@ -0,0 +1,283 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ============================================================================= + * Copyright (C) 2018 Samsung Electronics. All rights + reserved. + * ================================================================================ + * Modifications Copyright © 2018 IBM + * ================================================================================ + * 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.ccsdk.sli.plugins.sshapicall; + +import java.io.ByteArrayOutputStream; +import java.util.Map; + +import org.onap.appc.adapter.ssh.SshAdapter; +import org.onap.appc.adapter.ssh.SshConnection; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.plugins.sshapicall.model.AuthType; +import org.onap.ccsdk.sli.plugins.sshapicall.model.Parameters; +import org.onap.ccsdk.sli.plugins.sshapicall.model.ParseParam; + + +public class SshApiCallNode implements SvcLogicJavaPlugin { + + private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + /** + * Output parameter - SSH command execution status. + */ + private String PARAM_OUT_status = "sshApi.call.node.status"; + + /** + * Output parameter - content of SSH command stdout. + */ + private String PARAM_OUT_stdout = "sshApi.call.node.stdout"; + + /** + * Output parameter - content of SSH command stderr. + */ + private String PARAM_OUT_stderr = "sshApi.call.node.stderr"; + + /** + * Testing parameter - content of mocked SSH. + */ + private boolean PARAM_TEST_MODE = false; + private String PARAM_OUT_MESSAGE = "TestOut"; + + + /** + * Default success status. + */ + private int DEF_SUCCESS_STATUS = 0; + + + + private SshAdapter sshAdapter; + + /** + * Used for jUnit test and testing interface + */ + public SshApiCallNode(boolean mode) { + PARAM_TEST_MODE = mode; + } + + public SshApiCallNode() { + PARAM_TEST_MODE = false; + } + + public void setSshAdapter(SshAdapter sshAdapter) { + this.sshAdapter = sshAdapter; + } + + /** + * Allows Directed Graphs the ability to interact with SSH APIs. + * @param params HashMap<String,String> of parameters passed by the DG to this function + * <table border="1"> + * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead> + * <tbody> + * <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr> + * <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr> + * <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr> + * <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr> + * <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr> + * <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr> + * <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr> + * <tr><td>Cmd</td><td>Mandatory</td><td>ssh command to be executed on the server.</td><td>get post put delete patch</td></tr> + * <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td></tr> + * <tr><td>ResponseType</td><td>Optional</td><td>If we know the response is to be in a specific format (supported are JSON, XML and NONE) </td></tr> + * <tr><td>listName[i]</td><td>Optional</td><td>Used for processing XML responses with repeating elements.</td>vpn-information.vrf-details<td></td></tr> + * <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr> + * <tr><td>AuthType</td><td>Optional</td><td>Type of authentiation to be used BASIC or sshKey based</td><td>true or false</td></tr> + * <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution. + * These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr> + * <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files. + * The SSH Server will utilize this feature to generate files with keys as filenames and values as content. + * This attribute can be used to generate files that a command may require as part of execution.</td></tr> + * </tbody> + * </table> + * Exec remote command over SSH. Return command execution status. + * Command output is written to out or err stream. + * + * @param ctx Reference to context memory + */ + + public void execCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + execSshCommand(params, ctx, false); + } + + private void execSshCommand(Map<String, String> params, SvcLogicContext ctx, boolean withPty) throws SvcLogicException { + ParseParam parser = new ParseParam(); + Parameters p = parser.getParameters(params); + logger.debug("=> Connecting to SSH server..."); + SshConnection sshConnection = null; + int status = -1; + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + String stdoutRes = ""; + String stderrRes = ""; + try { + if (!PARAM_TEST_MODE) { + sshConnection = getSshConnection(p); + sshConnection.connect(); + logger.debug("=> Connected to SSH server..."); + logger.debug("=> Running SSH command..."); + sshConnection.setExecTimeout(p.sshExecTimeout); + if (withPty) { + status = sshConnection.execCommandWithPty(parser.makeCommand(params), stdout); + stderr = stdout; + } + else + status = sshConnection.execCommand(parser.makeCommand(params), stdout, stderr); + stdoutRes = stdout.toString(); + stderrRes = stderr.toString(); + + } else { + if (("true").equalsIgnoreCase(params.get("TestFail"))) + status = 202; + else + status = DEF_SUCCESS_STATUS; + stdoutRes = params.get(PARAM_OUT_MESSAGE); + } + logger.debug("=> executed SSH command"); + + if(status == DEF_SUCCESS_STATUS) { + parser.parseOutput(ctx, stdoutRes); + } + ctx.setAttribute(PARAM_OUT_status, String.format("%01d", status)); + ctx.setAttribute(PARAM_OUT_stdout, stdoutRes); + ctx.setAttribute(PARAM_OUT_stderr, stderrRes); + } catch (Exception e){ + throw new SvcLogicException("Exception in SSH adaptor : " + e.getMessage()); + } finally { + if (sshConnection != null) + sshConnection.disconnect(); + } + } + + private SshConnection getSshConnection(Parameters p) throws SvcLogicException { + if (p.authtype == AuthType.BASIC) + return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshapiUser, p.sshapiPassword); + // This is not supported yet in the API, patch has already been added to APPC + else if (p.authtype == AuthType.KEY){ + throw new SvcLogicException("SSH Key based Auth method not supported"); + } + else if (p.authtype == AuthType.NONE){ + throw new SvcLogicException("SSH Auth type required, BASIC auth in support"); + } + else if (p.authtype == AuthType.UNSPECIFIED){ + if (p.sshapiUser != null && p.sshapiPassword != null) + return sshAdapter.getConnection(p.sshapiUrl, p.sshapiPort, p.sshapiUser, p.sshapiPassword); + else if (p.sshKey != null) + throw new SvcLogicException("SSH Key based Auth method not supported"); + } + throw new SvcLogicException("SSH Auth type required, BASIC auth in support"); + } + + + /** + * Allows Directed Graphs the ability to interact with SSH APIs. + * @param params HashMap<String,String> of parameters passed by the DG to this function + * <table border="1"> + * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead> + * <tbody> + * <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr> + * <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr> + * <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr> + * <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr> + * <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr> + * <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr> + * <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr> + * <tr><td>Cmd</td><td>Mandatory</td><td>ssh command to be executed on the server.</td><td>get post put delete patch</td></tr> + * <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td></tr> + * <tr><td>ResponseType</td><td>Optional</td><td>If we know the response is to be in a specific format (supported are JSON, XML and NONE) </td></tr> + * <tr><td>listName[i]</td><td>Optional</td><td>Used for processing XML responses with repeating elements.</td>vpn-information.vrf-details<td></td></tr> + * <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr> + * <tr><td>AuthType</td><td>Optional</td><td>Type of authentiation to be used BASIC or sshKey based</td><td>true or false</td></tr> + * <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution. + * These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr> + * <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files. + * The SSH Server will utilize this feature to generate files with keys as filenames and values as content. + * This attribute can be used to generate files that a command may require as part of execution.</td></tr> + * </tbody> + * </table> + * Exec remote command over SSH. Return command execution status. + * Command output is written to out or err stream. + * + * @param ctx Reference to context memory + */ + + public void execWithStatusCheck(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + execCommand(params, ctx); + parseResponse(ctx); + } + + private void parseResponse (SvcLogicContext ctx) throws SvcLogicException { + int status = Integer.parseInt(ctx.getAttribute(PARAM_OUT_status)); + if(status != DEF_SUCCESS_STATUS) { + StringBuilder errmsg = new StringBuilder(); + errmsg.append("SSH command returned error status [").append(status).append(']'); + String stderr = ctx.getAttribute(PARAM_OUT_stderr); + if((stderr != null) && !stderr.isEmpty()) { + errmsg.append(". Error: [").append(stderr).append(']'); + } + throw new SvcLogicException(errmsg.toString()); + } + } + + /** + * Allows Directed Graphs the ability to interact with SSH APIs. + * @param params HashMap<String,String> of parameters passed by the DG to this function + * <table border="1"> + * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead> + * <tbody> + * <tr><td>Url</td><td>Mandatory</td><td>url to make the SSH connection request to.</td></tr> + * <tr><td>Port</td><td>Mandatory</td><td>port to make the SSH connection request to.</td></tr> + * <tr><td>User</td><td>Optional</td><td>user name to use for ssh basic authentication</td><td>sdnc_ws</td></tr> + * <tr><td>Password</td><td>Optional</td><td>unencrypted password to use for ssh basic authentication</td><td>plain_password</td></tr> + * <tr><td>SshKey</td><td>Optional</td><td>Consumer SSH key to use for ssh authentication</td><td>plain_key</td></tr> + * <tr><td>ExecTimeout</td><td>Optional</td><td>SSH command execution timeout</td><td>plain_key</td></tr> + * <tr><td>Retry</td><td>Optional</td><td>Make ssh connection with default retry policy</td><td>plain_key</td></tr> + * <tr><td>Cmd</td><td>Mandatory</td><td>ssh command to be executed on the server.</td><td>get post put delete patch</td></tr> + * <tr><td>ResponsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td></tr> + * <tr><td>ResponseType</td><td>Optional</td><td>If we know the response is to be in a specific format (supported are JSON, XML and NONE) </td></tr> + * <tr><td>listName[i]</td><td>Optional</td><td>Used for processing XML responses with repeating elements.</td>vpn-information.vrf-details<td></td></tr> + * <tr><td>ConvertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr> + * <tr><td>AuthType</td><td>Optional</td><td>Type of authentiation to be used BASIC or sshKey based</td><td>true or false</td></tr> + * <tr><td>EnvParameters</td><td>Optional</td><td>A JSON dictionary which should list key value pairs to be passed to the command execution. + * These values would correspond to instance specific parameters that a command may need to execute an action.</td></tr> + * <tr><td>FileParameters</td><td>Optional</td><td>A JSON dictionary where keys are filenames and values are contents of files. + * The SSH Server will utilize this feature to generate files with keys as filenames and values as content. + * This attribute can be used to generate files that a command may require as part of execution.</td></tr> + * </tbody> + * </table> + * Exec remote command over SSH. Return command execution status. + * Command output is written to out or err stream. + * + * @param ctx Reference to context memory + */ + public void execCommandWithPty(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + execSshCommand(params, ctx, true); + } +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/AuthType.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/AuthType.java new file mode 100644 index 000000000..806c80890 --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/AuthType.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.ccsdk.sli.plugins.sshapicall.model; + +public enum AuthType { + NONE, BASIC, KEY, UNSPECIFIED; + + public static AuthType fromString(String s) { + if ("basic".equalsIgnoreCase(s)) + return BASIC; + if ("key".equalsIgnoreCase(s)) + return KEY; + if ("unspecified".equalsIgnoreCase(s)) + return UNSPECIFIED; + if ("none".equalsIgnoreCase(s)) + return NONE; + throw new IllegalArgumentException("Invalid value for format: " + s); + } +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/Format.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/Format.java new file mode 100644 index 000000000..43c3c38d6 --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/Format.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.ccsdk.sli.plugins.sshapicall.model; + +public enum Format { + JSON, XML, NONE; + + public static Format fromString(String s) { + if ("json".equalsIgnoreCase(s)) + return JSON; + if ("xml".equalsIgnoreCase(s)) + return XML; + if ("none".equalsIgnoreCase(s)) + return NONE; + throw new IllegalArgumentException("Invalid value for format: " + s); + } +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/JsonParser.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/JsonParser.java new file mode 100644 index 000000000..3d48a790f --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/JsonParser.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. All rights + * reserved. + * ================================================================================ + * Modifications Copyright © 2018 IBM + * ================================================================================ + * 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.ccsdk.sli.plugins.sshapicall.model; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class JsonParser { + + private static final Logger log = LoggerFactory.getLogger(JsonParser.class); + + private JsonParser() { + // Preventing instantiation of the same. + } + + @SuppressWarnings("unchecked") + public static Map<String, String> convertToProperties(String s) + 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())); + + 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)); + } + } + return mm; + } +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/Parameters.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/Parameters.java new file mode 100644 index 000000000..fa2371e88 --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/Parameters.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.ccsdk.sli.plugins.sshapicall.model; + +import java.util.Set; + +public class Parameters { + public String sshapiUrl; + public int sshapiPort; + public String sshapiUser; + public String sshapiPassword; + public String sshKey; + public long sshExecTimeout; + public String sshFileParameters; + public String sshEnvParameters; + public boolean sshWithRetry; + public String cmd; + public String responsePrefix; + public Format responseType; + + public Set<String> listNameList; + public boolean convertResponse; + public AuthType authtype; +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/ParseParam.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/ParseParam.java new file mode 100644 index 000000000..35c1087d8 --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/ParseParam.java @@ -0,0 +1,275 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. All rights + * reserved. + * ================================================================================ + * Modifications Copyright © 2018 IBM + * ================================================================================ + * 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.ccsdk.sli.plugins.sshapicall.model; + +import com.google.common.base.Strings; +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 org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +public class ParseParam { + private static final Logger log = LoggerFactory.getLogger(ParseParam.class); + /** + * Default SSH command timeout + */ + private long dEF_timeout = 12000; + /** + * Default SSH connection port. + */ + private int dEF_port = 22; + /** + * Default SSH command timeout + */ + private final String FILE_PARAMETERS_OPT_KEY = "FileParameters"; + public final String SSH_ResponsePrefix = "ResponsePrefix"; + /** + * Default SSH connection port. + */ + private final String ENV_PARAMETERS_OPT_KEY = "EnvParameters"; + private Parameters p = new Parameters(); + + public Parameters getParameters(Map<String, String> paramMap) throws SvcLogicException { + p.sshapiUrl = parseParam(paramMap, "Url", true, null); + p.sshapiPort = Integer.parseInt(parseParam(paramMap, "Port", true, Integer.toString(dEF_port))); + p.sshapiUser = parseParam(paramMap, "User", false, null); + p.sshapiPassword = parseParam(paramMap, "Password", false, null); + p.sshKey = parseParam(paramMap, "SshKey", false, null); + p.sshExecTimeout = Long.parseLong(parseParam(paramMap, "ExecTimeout", false, Long.toString(dEF_timeout))); + p.sshWithRetry = Boolean.valueOf(parseParam(paramMap, "Retry", false, "false")); + p.cmd = parseParam(paramMap, "Cmd", true, null); + p.responsePrefix = parseParam(paramMap, SSH_ResponsePrefix, false, null); + p.responseType = Format.fromString(parseParam(paramMap, "ResponseType", false, "none")); + p.listNameList = getListNameList(paramMap); + p.convertResponse = Boolean.valueOf(parseParam(paramMap, "ConvertResponse", false, "true")); + p.authtype = AuthType.fromString(parseParam(paramMap, "AuthType", false, "unspecified")); + + return p; + } + + public String getStringParameters(Map<String, String> paramMap, String paramName) throws SvcLogicException { + return parseParam(paramMap, SSH_ResponsePrefix, false, null); + } + + public void parseOutput (SvcLogicContext ctx, String outMessage) throws SvcLogicException { + if (p.convertResponse) { + if (p.responseType == Format.NONE) { + classifyOutput(ctx, outMessage); + } else if (p.responseType == Format.JSON) { + classifyOutput(ctx, outMessage); + } else if (p.responseType == Format.XML) { + classifyOutput(ctx, outMessage, p.listNameList); + } + } + } + + private void classifyOutput(SvcLogicContext ctx, String outMessage, Set<String> listNameList) throws SvcLogicException { + Map<String, String> mm = XmlParser.convertToProperties(outMessage, p.listNameList); + toCtx (ctx, mm); + } + + private void toCtx (SvcLogicContext ctx, Map<String, String> mm) { + if (mm != null) { + for (Map.Entry<String, String> entry : mm.entrySet()) { + if (p.responsePrefix != null) { + ctx.setAttribute(p.responsePrefix + "." + entry.getKey(), entry.getValue()); + log.info("+++ " + p.responsePrefix + "." + entry.getKey() + ": [" + entry.getValue() + "]"); + } else { + ctx.setAttribute(entry.getKey(), entry.getValue()); + log.info("+++ " + entry.getKey() + ": [" + entry.getValue() + "]"); + } + } + } + } + + private void classifyOutput(SvcLogicContext ctx, String outMessage) throws SvcLogicException { + try { + Map<String, String> mm = JsonParser.convertToProperties(outMessage); + toCtx (ctx, mm); + } catch (org.codehaus.jettison.json.JSONException e) { + log.info("Output not in JSON format"); + putToProperties(ctx, p.responsePrefix); + } catch (Exception e) { + throw new SvcLogicException("error parsing response file"); + } + } + + private void putToProperties(SvcLogicContext ctx, String outMessage) throws SvcLogicException { + + try { + Properties prop = new Properties(); + prop.load(new ByteArrayInputStream(outMessage.getBytes(StandardCharsets.UTF_8))); + for (Object key : prop.keySet()) { + String name = (String) key; + String value = prop.getProperty(name); + if (value != null && value.trim().length() > 0) { + if (p.responsePrefix != null) { + ctx.setAttribute(p.responsePrefix + "." + name, value.trim()); + log.info("+++ " + p.responsePrefix + "." + name + ": [" + value + "]"); + } else { + ctx.setAttribute(name, value.trim()); + log.info("+++ " + name + ": [" + value + "]"); + } + } + } + } catch (Exception e) { + throw new SvcLogicException( "Error parsing response file."); + } + } + + public String makeCommand (Map<String, String> params) { + JSONObject jsonPayload = new JSONObject(); + final String[] optionalTestParams = {ENV_PARAMETERS_OPT_KEY, FILE_PARAMETERS_OPT_KEY}; + parseParam(params, optionalTestParams, jsonPayload); + JSONObject envParams = (JSONObject) jsonPayload.remove(ENV_PARAMETERS_OPT_KEY); + JSONObject fileParams = (JSONObject) jsonPayload.remove(FILE_PARAMETERS_OPT_KEY); + + StringBuilder constructedCommand = new StringBuilder(); + constructedCommand.append(parseFileParam(fileParams)).append(p.cmd).append(" ").append(parseEnvParam(envParams)); + + return constructedCommand.toString(); + } + + private String parseEnvParam(JSONObject envParams) { + StringBuilder envParamBuilder = new StringBuilder(); + if (envParams != null) { + for (Object key : envParams.keySet()) { + if (envParamBuilder.length() > 0) { + envParamBuilder.append(", "); + } + envParamBuilder.append(key + "=" + envParams.get((String) key)); + } + } + return envParamBuilder.toString(); + } + + private String parseFileParam(JSONObject fileParams) { + StringBuilder fileParamBuilder = new StringBuilder(); + if (fileParams != null) { + for (Object key : fileParams.keySet()) { + fileParamBuilder.append("echo -e \"" + fileParams.get((String) key) + "\" > /srv/salt/" + key).append("; "); + } + } + return fileParamBuilder.toString(); + } + + private void parseParam(Map<String, String> params, String[] optionalTestParams, JSONObject jsonPayload) + throws JSONException { + + Set<String> optionalParamsSet = new HashSet<>(); + Collections.addAll(optionalParamsSet, optionalTestParams); + + //@formatter:off + params.entrySet() + .stream() + .filter(entry -> optionalParamsSet.contains(entry.getKey())) + .filter(entry -> !Strings.isNullOrEmpty(entry.getValue())) + .forEach(entry -> parseParam(entry, jsonPayload)); + //@formatter:on + } + + private void parseParam(Map.Entry<String, String> params, JSONObject jsonPayload) + throws JSONException { + String key = params.getKey(); + String payload = params.getValue(); + + switch (key) { + case ENV_PARAMETERS_OPT_KEY: + JSONObject paramsJson = new JSONObject(payload); + jsonPayload.put(key, paramsJson); + break; + + case FILE_PARAMETERS_OPT_KEY: + jsonPayload.put(key, getFilePayload(payload)); + break; + + default: + break; + } + } + + /** + * Return payload with escaped newlines + */ + private JSONObject getFilePayload(String payload) { + String formattedPayload = payload.replace("\n", "\\n").replace("\r", "\\r"); + return new JSONObject(formattedPayload); + } + + private Set<String> getListNameList(Map<String, String> paramMap) { + Set<String> ll = new HashSet<>(); + for (Map.Entry<String,String> entry : paramMap.entrySet()) + if (entry.getKey().startsWith("listName")) + ll.add(entry.getValue()); + return ll; + } + + private String parseParam(Map<String, String> paramMap, String name, boolean required, String def) + throws SvcLogicException { + String s = paramMap.get(name); + + if (s == null || s.trim().length() == 0) { + if (!required) + return def; + throw new SvcLogicException("Parameter " + name + " is required in sshapiCallNode"); + } + + s = s.trim(); + StringBuilder value = new StringBuilder(); + int i = 0; + int i1 = s.indexOf('%'); + while (i1 >= 0) { + int i2 = s.indexOf('%', i1 + 1); + if (i2 < 0) + break; + + String varName = s.substring(i1 + 1, i2); + String varValue = System.getenv(varName); + if (varValue == null) + varValue = "%" + varName + "%"; + + value.append(s.substring(i, i1)); + value.append(varValue); + + i = i2 + 1; + i1 = s.indexOf('%', i); + } + value.append(s.substring(i)); + + log.info("Parameter {}: [{}]", name, value); + return value.toString(); + } +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/XmlJsonUtil.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/XmlJsonUtil.java new file mode 100644 index 000000000..d68fbc6ac --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/XmlJsonUtil.java @@ -0,0 +1,389 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.ccsdk.sli.plugins.sshapicall.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class XmlJsonUtil { + + private static final Logger log = LoggerFactory.getLogger(XmlJsonUtil.class); + + private XmlJsonUtil() { + // Preventing instantiation of the same. + } + + public static String getXml(Map<String, String> varmap, String var) { + boolean escape = true; + if (var.startsWith("'")) { + var = var.substring(1); + escape = false; + } + + Object o = createStructure(varmap, var); + return generateXml(o, 0, escape); + } + + public static String getJson(Map<String, String> varmap, String var) { + boolean escape = true; + if (var.startsWith("'")) { + var = var.substring(1); + escape = false; + } + + boolean quotes = true; + if (var.startsWith("\"")) { + var = var.substring(1); + quotes = false; + } + + Object o = createStructure(varmap, var); + return generateJson(o, escape, quotes); + } + + private static Object createStructure(Map<String, String> flatmap, String var) { + if (flatmap.containsKey(var)) { + if (var.endsWith("_length") || var.endsWith("].key")) + return null; + return flatmap.get(var); + } + + Map<String, Object> mm = new HashMap<>(); + for (String k : flatmap.keySet()) + if (k.startsWith(var + ".")) { + int i1 = k.indexOf('.', var.length() + 1); + int i2 = k.indexOf('[', var.length() + 1); + int i3 = k.length(); + if (i1 > 0 && i1 < i3) + i3 = i1; + if (i2 > 0 && i2 < i3) + i3 = i2; + String k1 = k.substring(var.length() + 1, i3); + String var1 = k.substring(0, i3); + if (!mm.containsKey(k1)) { + Object str = createStructure(flatmap, var1); + if (str != null && (!(str instanceof String) || ((String) str).trim().length() > 0)) + mm.put(k1, str); + } + } + if (!mm.isEmpty()) + return mm; + + boolean arrayFound = false; + for (String k : flatmap.keySet()) + if (k.startsWith(var + "[")) { + arrayFound = true; + break; + } + + if (arrayFound) { + List<Object> ll = new ArrayList<>(); + + int length = Integer.MAX_VALUE; + String lengthStr = flatmap.get(var + "_length"); + if (lengthStr != null) { + try { + length = Integer.parseInt(lengthStr); + } catch (Exception e) { + log.warn("Invalid number for {}_length:{}", var, lengthStr, e); + } + } + + for (int i = 0; i < length; i++) { + Object v = createStructure(flatmap, var + '[' + i + ']'); + if (v == null) + break; + ll.add(v); + } + + if (!ll.isEmpty()) + return ll; + } + + return null; + } + + @SuppressWarnings("unchecked") + private static String generateXml(Object o, int indent, boolean escape) { + if (o == null) + return null; + + if (o instanceof String) + return escape ? escapeXml((String) o) : (String) o;; + + if (o instanceof Map) { + StringBuilder ss = new StringBuilder(); + Map<String, Object> mm = (Map<String, Object>) o; + for (Map.Entry<String, Object> entry: mm.entrySet()) { + Object v = entry.getValue(); + String key = entry.getKey(); + if (v instanceof String) { + String s = escape ? escapeXml((String) v) : (String) v; + ss.append(pad(indent)).append('<').append(key).append('>'); + ss.append(s); + ss.append("</").append(key).append('>').append('\n'); + } else if (v instanceof Map) { + ss.append(pad(indent)).append('<').append(key).append('>').append('\n'); + ss.append(generateXml(v, indent + 1, escape)); + ss.append(pad(indent)).append("</").append(key).append('>').append('\n'); + } else if (v instanceof List) { + List<Object> ll = (List<Object>) v; + for (Object o1 : ll) { + ss.append(pad(indent)).append('<').append(key).append('>').append('\n'); + ss.append(generateXml(o1, indent + 1, escape)); + ss.append(pad(indent)).append("</").append(key).append('>').append('\n'); + } + } + } + return ss.toString(); + } + + return null; + } + + private static String generateJson(Object o, boolean escape, boolean quotes) { + if (o == null) + return null; + + StringBuilder ss = new StringBuilder(); + generateJson(ss, o, 0, false, escape, quotes); + return ss.toString(); + } + + @SuppressWarnings("unchecked") + private static void generateJson(StringBuilder ss, Object o, int indent, boolean padFirst, boolean escape, boolean quotes) { + if (o instanceof String) { + String s = escape ? escapeJson((String) o) : (String) o; + if (padFirst) + ss.append(pad(indent)); + if (quotes) { + ss.append('"').append(s).append('"'); + } else { + ss.append(s); + } + return; + } + + if (o instanceof Map) { + Map<String, Object> mm = (Map<String, Object>) o; + + if (padFirst) + ss.append(pad(indent)); + ss.append("{\n"); + + boolean first = true; + for (Map.Entry<String, Object> entry : mm.entrySet()) { + if (!first) + ss.append(",\n"); + first = false; + Object v = entry.getValue(); + String key = entry.getKey(); + ss.append(pad(indent + 1)).append('"').append(key).append("\": "); + generateJson(ss, v, indent + 1, false, escape, true); + } + + ss.append("\n"); + ss.append(pad(indent)).append('}'); + + return; + } + + if (o instanceof List) { + List<Object> ll = (List<Object>) o; + + if (padFirst) + ss.append(pad(indent)); + ss.append("[\n"); + + boolean first = true; + for (Object o1 : ll) { + if (!first) + ss.append(",\n"); + first = false; + + generateJson(ss, o1, indent + 1, true, escape, quotes); + } + + ss.append("\n"); + ss.append(pad(indent)).append(']'); + } + } + + public static String removeLastCommaJson(String s) { + StringBuilder sb = new StringBuilder(); + int k = 0; + int start = 0; + while (k < s.length()) { + int i11 = s.indexOf('}', k); + int i12 = s.indexOf(']', k); + int i1 = -1; + if (i11 < 0) + i1 = i12; + else if (i12 < 0) + i1 = i11; + else + i1 = i11 < i12 ? i11 : i12; + if (i1 < 0) + break; + + int i2 = s.lastIndexOf(',', i1); + if (i2 < 0) { + k = i1 + 1; + continue; + } + + String between = s.substring(i2 + 1, i1); + if (between.trim().length() > 0) { + k = i1 + 1; + continue; + } + + sb.append(s.substring(start, i2)); + start = i2 + 1; + k = i1 + 1; + } + + sb.append(s.substring(start, s.length())); + + return sb.toString(); + } + + public static String removeEmptyStructJson(String s) { + int k = 0; + while (k < s.length()) { + boolean curly = true; + int i11 = s.indexOf('{', k); + int i12 = s.indexOf('[', k); + int i1 = -1; + if (i11 < 0) { + i1 = i12; + curly = false; + } else if (i12 < 0) + i1 = i11; + else + if (i11 < i12) + i1 = i11; + else { + i1 = i12; + curly = false; + } + + if (i1 >= 0) { + int i2 = curly ? s.indexOf('}', i1) : s.indexOf(']', i1); + if (i2 > 0) { + String value = s.substring(i1 + 1, i2); + if (value.trim().length() == 0) { + int i4 = s.lastIndexOf('\n', i1); + if (i4 < 0) + i4 = 0; + int i5 = s.indexOf('\n', i2); + if (i5 < 0) + i5 = s.length(); + + s = s.substring(0, i4) + s.substring(i5); + k = 0; + } else + k = i1 + 1; + } else + break; + } else + break; + } + + return s; + } + + public static String removeEmptyStructXml(String s) { + int k = 0; + while (k < s.length()) { + int i1 = s.indexOf('<', k); + if (i1 < 0 || i1 == s.length() - 1) + break; + + char c1 = s.charAt(i1 + 1); + if (c1 == '?' || c1 == '!') { + k = i1 + 2; + continue; + } + + int i2 = s.indexOf('>', i1); + if (i2 < 0) { + k = i1 + 1; + continue; + } + + String closingTag = "</" + s.substring(i1 + 1, i2 + 1); + int i3 = s.indexOf(closingTag, i2 + 1); + if (i3 < 0) { + k = i2 + 1; + continue; + } + + String value = s.substring(i2 + 1, i3); + if (value.trim().length() > 0) { + k = i2 + 1; + continue; + } + + int i4 = s.lastIndexOf('\n', i1); + if (i4 < 0) + i4 = 0; + int i5 = s.indexOf('\n', i3); + if (i5 < 0) + i5 = s.length(); + + s = s.substring(0, i4) + s.substring(i5); + k = 0; + } + + return s; + } + + private static String escapeXml(String v) { + String s = v.replaceAll("&", "&"); + s = s.replaceAll("<", "<"); + s = s.replaceAll("'", "'"); + s = s.replaceAll("\"", """); + s = s.replaceAll(">", ">"); + return s; + } + + private static String escapeJson(String v) { + String s = v.replaceAll("\\\\", "\\\\\\\\"); + s = s.replaceAll("\"", "\\\\\""); + return s; + } + + private static String pad(int n) { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < n; i++) + s.append(Character.toString('\t')); + return s.toString(); + } +} diff --git a/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/XmlParser.java b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/XmlParser.java new file mode 100644 index 000000000..6ea770ad9 --- /dev/null +++ b/sshapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/sshapicall/model/XmlParser.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * + * Modifications Copyright © 2018 IBM. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.ccsdk.sli.plugins.sshapicall.model; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public final class XmlParser { + + private static final Logger log = LoggerFactory.getLogger(XmlParser.class); + + private XmlParser() { + // Preventing instantiation of the same. + } + + public static Map<String, String> convertToProperties(String s, Set<String> listNameList) + throws SvcLogicException { + + checkNotNull(s, "Input should not be null."); + + Handler handler = new Handler(listNameList); + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser saxParser = factory.newSAXParser(); + InputStream in = new ByteArrayInputStream(s.getBytes()); + saxParser.parse(in, handler); + } catch (ParserConfigurationException | IOException | SAXException | NumberFormatException e) { + throw new SvcLogicException("Unable to convert XML to properties" + e.getLocalizedMessage(), e); + } + return handler.getProperties(); + } + + private static class Handler extends DefaultHandler { + + private Set<String> listNameList; + + private Map<String, String> properties = new HashMap<>(); + + StringBuilder currentName = new StringBuilder(); + StringBuilder currentValue = new StringBuilder(); + + public Handler(Set<String> listNameList) { + super(); + this.listNameList = listNameList; + if (this.listNameList == null) + this.listNameList = new HashSet<>(); + } + + public Map<String, String> getProperties() { + return properties; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + super.startElement(uri, localName, qName, attributes); + + String name = localName; + if (name == null || name.trim().length() == 0) + name = qName; + int i2 = name.indexOf(':'); + if (i2 >= 0) + name = name.substring(i2 + 1); + + if (currentName.length() > 0) + currentName.append(Character.toString('.')); + currentName.append(name); + + String listName = removeIndexes(currentName.toString()); + + if (listNameList.contains(listName)) { + String n = currentName.toString() + "_length"; + int len = getInt(properties, n); + properties.put(n, String.valueOf(len + 1)); + currentName.append("[").append(len).append("]"); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + super.endElement(uri, localName, qName); + + String name = localName; + if (name == null || name.trim().length() == 0) + name = qName; + int i2 = name.indexOf(':'); + if (i2 >= 0) + name = name.substring(i2 + 1); + + String s = currentValue.toString().trim(); + if (s.length() > 0) { + properties.put(currentName.toString(), s); + + log.info("Added property: {} : {}", currentName, s); + currentValue = new StringBuilder(); + } + + int i1 = currentName.lastIndexOf("." + name); + if (i1 <= 0) + currentName = new StringBuilder(); + else + currentName = new StringBuilder(currentName.substring(0, i1)); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + super.characters(ch, start, length); + + String value = new String(ch, start, length); + currentValue.append(value); + } + + private static int getInt(Map<String, String> mm, String name) { + String s = mm.get(name); + if (s == null) + return 0; + return Integer.parseInt(s); + } + + private String removeIndexes(String currentName) { + StringBuilder b = new StringBuilder(); + boolean add = true; + for (int i = 0; i < currentName.length(); i++) { + char c = currentName.charAt(i); + if (c == '[') + add = false; + else if (c == ']') + add = true; + else if (add) + b.append(Character.toString(c)); + } + return b.toString(); + } + } +} diff --git a/sshapi-call-node/provider/src/main/resources/META-INF/spring/sshapi-call-node-context.xml b/sshapi-call-node/provider/src/main/resources/META-INF/spring/sshapi-call-node-context.xml new file mode 100644 index 000000000..50c9b2aa3 --- /dev/null +++ b/sshapi-call-node/provider/src/main/resources/META-INF/spring/sshapi-call-node-context.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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========================================================= + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> + <property name="locations"> + <list> + <value>file:${SDNC_CONFIG_DIR}/ueb.properties</value> + <value>file:${SDNC_CONFIG_DIR}/dme2.properties</value> + </list> + </property> + <property name="ignoreResourceNotFound" value="true" /> + <property name="ignoreUnresolvablePlaceholders" value="true" /> + </bean> + + <!-- context:property-placeholder location="file:${SDNC_CONFIG_DIR}/ueb.properties" /--> + + <bean id="sshapiCallNode" class="org.onap.ccsdk.sli.plugins.sshapicall.SshApiCallNode"> + <property name="uebServers" value="${servers}" /> + </bean> + +</beans> diff --git a/sshapi-call-node/provider/src/main/resources/META-INF/spring/sshapi-call-node-osgi-context.xml b/sshapi-call-node/provider/src/main/resources/META-INF/spring/sshapi-call-node-osgi-context.xml new file mode 100644 index 000000000..25631d6af --- /dev/null +++ b/sshapi-call-node/provider/src/main/resources/META-INF/spring/sshapi-call-node-osgi-context.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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========================================================= + --> + +<beans:beans xmlns="http://www.springframework.org/schema/osgi" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" + xsi:schemaLocation="http://www.springframework.org/schema/osgi + http://www.springframework.org/schema/osgi/spring-osgi.xsd + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <service ref="sshapiCallNode" interface="org.onap.ccsdk.sli.plugins.sshapicall.SshApiCallNode" /> + +</beans:beans> diff --git a/sshapi-call-node/provider/src/main/resources/OSGI-INF/blueprint/sshapi-call-node-blueprint.xml b/sshapi-call-node/provider/src/main/resources/OSGI-INF/blueprint/sshapi-call-node-blueprint.xml new file mode 100755 index 000000000..7a5424329 --- /dev/null +++ b/sshapi-call-node/provider/src/main/resources/OSGI-INF/blueprint/sshapi-call-node-blueprint.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="sshapiCallNodeProvider" class="org.onap.ccsdk.sli.plugins.sshapicall.SshApiCallNode" /> + + + + <service ref="sshapiCallNodeProvider"> + <interfaces> + <value>org.onap.ccsdk.sli.plugins.sshapicall.SshApiCallNode</value> + </interfaces> + </service> + +</blueprint>
\ No newline at end of file diff --git a/sshapi-call-node/provider/src/main/resources/org/opendaylight/blueprint/sshapi-call-node-blueprint.xml b/sshapi-call-node/provider/src/main/resources/org/opendaylight/blueprint/sshapi-call-node-blueprint.xml new file mode 100755 index 000000000..7a5424329 --- /dev/null +++ b/sshapi-call-node/provider/src/main/resources/org/opendaylight/blueprint/sshapi-call-node-blueprint.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="sshapiCallNodeProvider" class="org.onap.ccsdk.sli.plugins.sshapicall.SshApiCallNode" /> + + + + <service ref="sshapiCallNodeProvider"> + <interfaces> + <value>org.onap.ccsdk.sli.plugins.sshapicall.SshApiCallNode</value> + </interfaces> + </service> + +</blueprint>
\ No newline at end of file |