ConfigComponentAdaptor sonar fixes part 2
[appc.git] / appc-config / appc-config-adaptor / provider / src / main / java / org / onap / appc / ccadaptor / ConfigComponentAdaptor.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * =============================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.appc.ccadaptor;
24
25 import com.att.eelf.configuration.EELFLogger;
26 import com.att.eelf.configuration.EELFManager;
27 import com.sun.jersey.api.client.Client;
28 import com.sun.jersey.api.client.ClientResponse;
29 import com.sun.jersey.api.client.WebResource;
30 import com.sun.jersey.core.util.Base64;
31 import java.io.BufferedReader;
32 import java.io.ByteArrayInputStream;
33 import java.io.FileReader;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.InputStreamReader;
37 import java.io.UncheckedIOException;
38 import java.net.HttpURLConnection;
39 import java.util.HashMap;
40 import java.util.Map;
41 import java.util.Map.Entry;
42 import java.util.NoSuchElementException;
43 import java.util.Properties;
44 import java.util.StringTokenizer;
45 import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
46 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
47
48 public class ConfigComponentAdaptor implements SvcLogicAdaptor {
49
50     private static final EELFLogger log = EELFManager.getInstance().getLogger(ConfigComponentAdaptor.class);
51
52     private static final String ACTION_PARAM = "action";
53     private static final String ACTION_PREPARE = "prepare";
54     private static final String ACTION_ACTIVATE = "activate";
55
56     private static final String KEY_PUT = "put";
57     private static final String KEY_GET = "get";
58     private static final String KEY_CLI = "cli";
59     private static final String KEY_ESCAPE_SQL = "escapeSql";
60     private static final String KEY_XML_DOWNLOAD = "xml-download";
61     private static final String KEY_XML_GET_RUNNING_CONF = "xml-getrunningconfig";
62     private static final String KEY_DOWNLOAD_CLI_CONFIG = "DownloadCliConfig";
63     private static final String KEY_GET_CLI_RUNNING_CONFIG = "GetCliRunningConfig";
64
65     private static final String OPERATION_CREATE = "create";
66     private static final String OPERATION_CHANGE = "change";
67     private static final String OPERATION_SCALE = "scale";
68
69     static final String USERNAME_PARAM = "User_name";
70     static final String PASSWORD_PARAM = "Password";
71     static final String HOST_IP_PARAM = "Host_ip_address";
72     static final String PORT_NUMBER_PARAM = "Port_number";
73     static final String GET_CONFIG_TEMPLATE_PARAM = "Get_config_template";
74
75     private static final String CLI_OUTPUT_PARAM = "cliOutput";
76     private static final String REQUEST_ID_PARAM = "request-id";
77     private static final String CALLBACK_URL_PARAM = "callback-url";
78     private static final String EQUIPMENT_NAME_PARAM = "equipment-name";
79
80     private static final String XML_BUILDING_ERR_STR = "Error building the XML request: ";
81     private static final String TEMPLATE_ERR_STR = "Template error: Matching \"}\" not found";
82     private static final String SSH_JCRAFT_WRAPPER_ERR_STR = "Exception occurred while using sshJcraftWrapper";
83     private static final String PROMPT_STR = "]]>]]>";
84     private static final String RESPONSE_STR = "response=\n{}\n";
85
86     private static final String SERVICE_INSTANCE_ID_ATTR = "service-data.service-information.service-instance-id";
87     private static final String SVC_REQUEST_ID_ATTR = "service-data.appc-request-header.svc-request-id";
88
89     private static final String RPC_REPLY_END_TAG = "</rpc-reply>";
90     private static final String BASE_REQUEST = "BASE";
91
92     private String configUrl;
93     private String configUser;
94     private String configPassword;
95     private String auditUrl;
96     private String auditUser;
97     private String auditPassword;
98     private String configCallbackUrl;
99     private String auditCallbackUrl;
100
101     public ConfigComponentAdaptor(Properties props) {
102         if (props != null) {
103             configUrl = props.getProperty("configComponent.url", "");
104             configUser = props.getProperty("configComponent.user", "");
105             configPassword = props.getProperty("configComponent.passwd", "");
106             auditUrl = props.getProperty("auditComponent.url", "");
107             auditUser = props.getProperty("auditComponent.user", "");
108             auditPassword = props.getProperty("auditComponent.passwd", "");
109             configCallbackUrl = props.getProperty("service-configuration-notification-url", "");
110             auditCallbackUrl = props.getProperty("audit-configuration-notification-url", "");
111         }
112     }
113
114     @Override
115     public ConfigStatus configure(String key, Map<String, String> parameters, SvcLogicContext ctx) {
116         HttpResponse r = new HttpResponse();
117         r.code = 200;
118         log.debug("ConfigComponentAdaptor.configure - key = " + key);
119         log.debug("key = {}", key);
120         log.debug("Parameters:");
121         for (Entry<String, String> paramEntrySet : parameters.entrySet()) {
122             log.debug("    {} = {}", paramEntrySet.getKey(), paramEntrySet.getValue());
123         }
124
125         String parmval = parameters.get("config-component-configUrl");
126         if (!nullOrEmpty(parmval)) {
127             log.debug("Overwriting URL with {}", parmval);
128             configUrl = parmval;
129         }
130
131         parmval = parameters.get("config-component-configPassword");
132         if (!nullOrEmpty(parmval)) {
133             log.debug("Overwriting configPassword with {}", parmval);
134             configPassword = parmval;
135         }
136
137         parmval = parameters.get("config-component-configUser");
138         if (!nullOrEmpty(parmval)) {
139             log.debug("Overwriting configUser id with {}", parmval);
140             configUser = parmval;
141         }
142
143         String action = parameters.get(ACTION_PARAM);
144
145         String chg = ctx.getAttribute(
146             "service-data.vnf-config-parameters-list.vnf-config-parameters[0].update-configuration[0].block-key-name");
147         if (chg != null && areEqual(action, ACTION_PREPARE)) {
148             return prepare(ctx, "CHANGE", OPERATION_CHANGE);
149         }
150         if (chg != null && areEqual(action, ACTION_ACTIVATE)) {
151             return activate(ctx, true);
152         }
153
154         String scale = ctx.getAttribute(
155             "service-data.vnf-config-parameters-list.vnf-config-parameters[0].scale-configuration[0].network-type");
156         if (scale != null && areEqual(action, ACTION_PREPARE)) {
157             return prepare(ctx, "CHANGE", OPERATION_SCALE);
158         }
159         if (scale != null && areEqual(action, ACTION_ACTIVATE)) {
160             return activate(ctx, true);
161         }
162
163         if (areEqual(action, ACTION_PREPARE)) {
164             return prepare(ctx, BASE_REQUEST, OPERATION_CREATE);
165         }
166         if (areEqual(action, ACTION_ACTIVATE)) {
167             return activate(ctx, false);
168         }
169
170         if ("backup".equalsIgnoreCase(action)) {
171             return prepare(ctx, "BACKUP", "backup");
172         }
173         if ("restorebackup".equalsIgnoreCase(action)) {
174             return prepare(ctx, "RESTOREBACKUP", "restorebackup");
175         }
176         if ("deletebackup".equalsIgnoreCase(action)) {
177             return prepare(ctx, "DELETEBACKUP", "deletebackup");
178         }
179         if ("audit".equalsIgnoreCase(action)) {
180             return audit(ctx, "FULL");
181         }
182         if ("getrunningconfig".equalsIgnoreCase(action)) {
183             return audit(ctx, "RUNNING");
184         }
185
186         if ((key.equals(KEY_PUT)) || (key.equals(KEY_GET))) {
187             String loginId = parameters.get("loginId");
188             String host = parameters.get("host");
189             String password = parameters.get("password");
190             password = EncryptionTool.getInstance().decrypt(password);
191             String fullPathFileName = parameters.get("fullPathFileName");
192
193             SshJcraftWrapper sshJcraftWrapper = new SshJcraftWrapper();
194             log.debug("SCP: SshJcraftWrapper has been instantiated");
195
196             try {
197                 if (key.equals(KEY_PUT)) {
198                     String data = parameters.get("data");
199                     log.debug("Command is for put: Length of data is: {}", data.length());
200                     InputStream is = new ByteArrayInputStream(data.getBytes());
201                     log.debug("SCP: Doing a put: fullPathFileName={}", fullPathFileName);
202                     sshJcraftWrapper.put(is, fullPathFileName, host, loginId, password);
203                     trySleepFor(1000L * 180);
204                 } else {  // Must be a get
205                     log.debug("SCP: Doing a get: fullPathFileName={}", fullPathFileName);
206                     String response = sshJcraftWrapper.get(fullPathFileName, host, loginId, password);
207                     log.debug("Got the response and putting into the ctx object");
208                     ctx.setAttribute("fileContents", response);
209                     log.debug("SCP: Closing the SFTP connection");
210                 }
211                 return setResponseStatus(ctx, r);
212             } catch (IOException e) {
213                 log.error(SSH_JCRAFT_WRAPPER_ERR_STR, e);
214                 r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
215                 r.message = e.getMessage();
216                 return setResponseStatus(ctx, r);
217             }
218         }
219         if (key.equals(KEY_CLI)) {
220             String loginId = parameters.get("loginId");
221             String host = parameters.get("host");
222             String password = parameters.get("password");
223             password = EncryptionTool.getInstance().decrypt(password);
224             String portNumber = parameters.get("portNumber");
225             SshJcraftWrapper sshJcraftWrapper = new SshJcraftWrapper();
226             try {
227                 log.debug("CLI: Attempting to login: host={} loginId={} password={} portNumber={}", host, loginId,
228                     password, portNumber);
229                 sshJcraftWrapper.connect(host, loginId, password); //what about portNum?
230
231                 log.debug("Sending 'sdc'");
232                 sshJcraftWrapper.send("sdc", ":");
233                 log.debug("Sending 1");
234                 sshJcraftWrapper.send("1", ":");
235                 log.debug("Sending 1, the second time");
236                 sshJcraftWrapper.send("1", "#");
237                 log.debug("Sending paging-options disable");
238                 sshJcraftWrapper.send("paging-options disable", "#");
239                 log.debug("Sending show config");
240                 String response = sshJcraftWrapper.send("show config", "#");
241
242                 log.debug("response is now:'{}'", response);
243                 log.debug("Populating the ctx object with the response");
244                 ctx.setAttribute(CLI_OUTPUT_PARAM, response);
245                 sshJcraftWrapper.closeConnection();
246                 r.code = 200;
247                 return setResponseStatus(ctx, r);
248             } catch (IOException e) {
249                 log.error(SSH_JCRAFT_WRAPPER_ERR_STR, e);
250                 sshJcraftWrapper.closeConnection();
251                 r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
252                 r.message = e.getMessage();
253                 return setResponseStatus(ctx, r);
254             }
255         }
256         if (key.equals(KEY_ESCAPE_SQL)) {
257             String data = parameters.get("artifactContents");
258             log.debug("ConfigComponentAdaptor.configure - escapeSql");
259             data = escapeMySql(data);
260             ctx.setAttribute("escapedData", data);
261             return setResponseStatus(ctx, r);
262         }
263         if (key.equals(KEY_GET_CLI_RUNNING_CONFIG)) {
264             log.debug("key was: " + KEY_GET_CLI_RUNNING_CONFIG);
265             String username = parameters.get(USERNAME_PARAM);
266             String hostIpAddress = parameters.get(HOST_IP_PARAM);
267             String password = parameters.get(PASSWORD_PARAM);
268             password = EncryptionTool.getInstance().decrypt(password);
269             String portNumber = parameters.get(PORT_NUMBER_PARAM);
270             String getConfigTemplate = parameters.get(GET_CONFIG_TEMPLATE_PARAM);
271             SshJcraftWrapper sshJcraftWrapper = new SshJcraftWrapper();
272             log.debug("GetCliRunningConfig: sshJcraftWrapper was instantiated");
273             try {
274                 log.debug("GetCliRunningConfig: Attempting to login: Host_ip_address=" + hostIpAddress + " User_name="
275                     + username + " Password=" + password + " Port_number=" + portNumber);
276
277                 boolean showConfigFlag = false;
278                 sshJcraftWrapper
279                     .connect(hostIpAddress, username, password, "", 30000, Integer.parseInt(portNumber));
280                 log.debug("GetCliRunningConfig: On the VNF device");
281                 StringTokenizer st = new StringTokenizer(getConfigTemplate, "\n");
282                 String command = null;
283
284                 StringBuilder cliResponse = new StringBuilder();
285
286                 // shouldn't this be used somewhere?
287                 StringBuilder response = new StringBuilder();
288
289                 try {
290                     while (st.hasMoreTokens()) {
291                         String line = st.nextToken();
292                         log.debug("line={}", line);
293                         if (line.contains("Request:")) {
294                             log.debug("Found a Request line: line={}", line);
295                             command = getStringBetweenQuotes(line);
296                             log.debug("Sending command={}", command);
297                             sshJcraftWrapper.send(command);
298                             log.debug("command has been sent");
299                             if (line.contains("show config")) {
300                                 showConfigFlag = true;
301                                 log.debug("GetCliRunningConfig: GetCliRunningConfig: setting 'showConfigFlag' to true");
302                             }
303                         }
304                         if (line.contains("Response: Ends_With")) {
305                             log.debug("Found a Response line: line={}", line);
306                             String delemeter = getStringBetweenQuotes(line);
307                             log.debug("The delemeter={}", delemeter);
308                             String tmpResponse = sshJcraftWrapper.receiveUntil(delemeter, 120 * 1000, command);
309                             response.append(tmpResponse);
310                             if (showConfigFlag) {
311                                 showConfigFlag = false;
312                                 StringTokenizer st2 = new StringTokenizer(tmpResponse, "\n");
313                                 while (st2.hasMoreTokens()) {
314                                     String line2 = st2.nextToken();
315                                     if (!line2.contains("#")) {
316                                         cliResponse.append(line2).append('\n');
317                                     }
318                                 }
319                             }
320                         }
321                     }
322                 } catch (NoSuchElementException e) {
323                     log.error(e.getMessage(), e);
324                 }
325                 log.debug("CliResponse=\n{}", cliResponse.toString());
326                 ctx.setAttribute(CLI_OUTPUT_PARAM, cliResponse.toString());
327                 sshJcraftWrapper.closeConnection();
328                 r.code = 200;
329                 return setResponseStatus(ctx, r);
330             } catch (IOException e) {
331                 log.error(SSH_JCRAFT_WRAPPER_ERR_STR, e);
332                 sshJcraftWrapper.closeConnection();
333                 r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
334                 r.message = e.getMessage();
335                 return setResponseStatus(ctx, r);
336             }
337         }
338         if (key.equals(KEY_XML_DOWNLOAD)) {
339             log.debug("key was: " + KEY_XML_DOWNLOAD);
340             String userName = parameters.get(USERNAME_PARAM);
341             String hostIpAddress = parameters.get(HOST_IP_PARAM);
342             String password = parameters.get(PASSWORD_PARAM);
343             password = EncryptionTool.getInstance().decrypt(password);
344             String portNumber = parameters.get(PORT_NUMBER_PARAM);
345             String contents = parameters.get("Contents");
346             String netconfHelloCmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n  <capabilities>\n   <capability>urn:ietf:params:netconf:base:1.0</capability>\n  <capability>urn:com:ericsson:ebase:1.1.0</capability> </capabilities>\n </hello>";
347             String terminateConnectionCmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n  <rpc message-id=\"terminateConnection\" xmlns:netconf=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n <close-session/> \n </rpc>\n ]]>]]>";
348             String commitCmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <rpc> <commit/> </rpc>\n ]]>]]>";
349
350             log.debug("xml-download: User_name={} Host_ip_address={} Password={} Port_number={}", userName,
351                 hostIpAddress, password, portNumber);
352             SshJcraftWrapper sshJcraftWrapper = new SshJcraftWrapper();
353             try {
354                 // what about prompt "]]>]]>"?
355                 sshJcraftWrapper
356                     .connect(hostIpAddress, userName, password, 30000, Integer.parseInt(portNumber), "netconf");
357
358                 netconfHelloCmd += PROMPT_STR;
359                 log.debug("Sending the hello command");
360                 sshJcraftWrapper.send(netconfHelloCmd);
361                 String response;
362                 log.debug("Sending xmlCmd cmd");
363                 String messageId = "1";
364                 messageId = "\"" + messageId + "\"";
365                 String loadConfigurationString =
366                     "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id="
367                         + messageId
368                         + "> <edit-config> <target> <candidate /> </target> <default-operation>merge</default-operation> <config xmlns:xc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
369                         + contents + "</config> </edit-config> </rpc>";
370                 loadConfigurationString = loadConfigurationString + PROMPT_STR;
371                 sshJcraftWrapper.send(loadConfigurationString);
372                 log.debug("After sending loadConfigurationString");
373                 response = sshJcraftWrapper.receiveUntil(RPC_REPLY_END_TAG, 600000, "");
374                 if (response.contains("rpc-error")) {
375                     log.debug("Error from device: Response from device had 'rpc-error'");
376                     log.debug(RESPONSE_STR, response);
377                     r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
378                     r.message = response;
379                 } else {
380                     log.debug(":LoadConfiguration was a success, sending commit cmd");
381                     sshJcraftWrapper.send(commitCmd);
382                     log.debug(":After sending commitCmd");
383                     response = sshJcraftWrapper.receiveUntil(RPC_REPLY_END_TAG, 180000, "");
384                     handleRpcError(r, response);
385                 }
386                 sshJcraftWrapper.send(terminateConnectionCmd);
387                 sshJcraftWrapper.closeConnection();
388                 return setResponseStatus(ctx, r);
389             } catch (Exception e) {
390                 log.error("Caught an Exception", e);
391                 sshJcraftWrapper.closeConnection();
392                 r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
393                 r.message = e.getMessage();
394                 log.debug("Returning error message");
395                 return setResponseStatus(ctx, r);
396             }
397         }
398         if (key.equals(KEY_XML_GET_RUNNING_CONF)) {
399             log.debug("key was: : xml-getrunningconfig");
400             String xmlGetRunningConfigCmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">  <get-config> <source> <running /> </source> </get-config> </rpc>\n";
401             String hostIpAddress = parameters.get(HOST_IP_PARAM);
402             String username = parameters.get(USERNAME_PARAM);
403             String password = parameters.get(PASSWORD_PARAM);
404             password = EncryptionTool.getInstance().decrypt(password);
405             String portNumber = parameters.get(PORT_NUMBER_PARAM);
406             String netconfHelloCmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n  <capabilities>\n   <capability>urn:ietf:params:netconf:base:1.0</capability>\n <capability>urn:com:ericsson:ebase:1.1.0</capability> </capabilities>\n </hello>";
407             String terminateConnectionCmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n  <rpc message-id=\"terminateConnection\" xmlns:netconf=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n <close-session/> \n </rpc>\n ]]>]]>";
408             log.debug("xml-getrunningconfig: User_name={} Host_ip_address={} Password={} Port_number={}", username,
409                 hostIpAddress, password, portNumber);
410             SshJcraftWrapper sshJcraftWrapper = new SshJcraftWrapper();
411             try {
412
413                 sshJcraftWrapper
414                     .connect(hostIpAddress, username, password, 30000, Integer.parseInt(portNumber),
415                         "netconf"); //What about prompt "]]>]]>" here?
416                 netconfHelloCmd += PROMPT_STR;
417                 log.debug(":Sending the hello command");
418                 sshJcraftWrapper.send(netconfHelloCmd);
419                 String response;
420                 log.debug("Sending get running config command");
421                 sshJcraftWrapper.send(xmlGetRunningConfigCmd + "]]>]]>\n");
422                 response = sshJcraftWrapper.receiveUntil(RPC_REPLY_END_TAG, 180000, "");
423                 log.debug("Response from getRunningconfigCmd={}", response);
424                 response = trimResponse(response);
425                 ctx.setAttribute("xmlRunningConfigOutput", response);
426                 sshJcraftWrapper.send(terminateConnectionCmd);
427                 sshJcraftWrapper.closeConnection();
428                 r.code = 200;
429                 return setResponseStatus(ctx, r);
430             } catch (Exception e) {
431                 log.error("Caught an Exception", e);
432                 sshJcraftWrapper.closeConnection();
433                 r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
434                 r.message = e.getMessage();
435                 log.debug("Returning error message");
436                 return setResponseStatus(ctx, r);
437             }
438         }
439         if (key.equals(KEY_DOWNLOAD_CLI_CONFIG)) {
440             log.debug("key was: DownloadCliConfig: ");
441             String username = parameters.get(USERNAME_PARAM);
442             String hostIpAddress = parameters.get(HOST_IP_PARAM);
443             String password = parameters.get(PASSWORD_PARAM);
444             password = EncryptionTool.getInstance().decrypt(password);
445             String portNumber = parameters.get(PORT_NUMBER_PARAM);
446             String downloadConfigTemplate = parameters.get("Download_config_template");
447             String configContents = parameters.get("Config_contents");
448             log.debug("Contents of the 'Config_contents' are: {}", configContents);
449             SshJcraftWrapper sshJcraftWrapper = new SshJcraftWrapper();
450             log.debug("DownloadCliConfig: sshJcraftWrapper was instantiated");
451             int timeout = 4 * 60 * 1000;
452             try {
453                 log.debug("DownloadCliConfig: Attempting to login: Host_ip_address=" + hostIpAddress + " User_name="
454                     + username + " Password=" + password + " Port_number=" + portNumber);
455
456                 StringBuilder cliResponse = new StringBuilder();
457
458                 // shouldn't this be used somewhere?
459                 StringBuilder response = new StringBuilder();
460
461                 sshJcraftWrapper
462                     .connect(hostIpAddress, username, password, "", 30000, Integer.parseInt(portNumber));
463                 log.debug("DownloadCliConfig: On the VNF device");
464                 StringTokenizer st = new StringTokenizer(downloadConfigTemplate, "\n");
465                 String command = null;
466                 String executeConfigContentsDelimiter;
467                 try {
468                     while (st.hasMoreTokens()) {
469                         String line = st.nextToken();
470                         log.debug("line={}", line);
471                         if (line.contains("Request:")) {
472                             log.debug("Found a Request line: line={}", line);
473                             command = getStringBetweenQuotes(line);
474                             log.debug("Sending command={}", command);
475                             sshJcraftWrapper.send(command);
476                             log.debug("command has been sent");
477                         } else if ((line.contains("Response: Ends_With")) && (
478                             !line.contains("Execute_config_contents Response: Ends_With"))) {
479                             log.debug("Found a Response line: line={}", line);
480                             String delimiter = getStringBetweenQuotes(line);
481                             log.debug("The delimiter={}", delimiter);
482                             String tmpResponse = sshJcraftWrapper.receiveUntil(delimiter, timeout, command);
483                             response.append(tmpResponse);
484                             cliResponse.append(tmpResponse);
485                         } else if (line.contains("Execute_config_contents Response: Ends_With")) {
486                             log.debug("Found a 'Execute_config_contents Response:' line={}", line);
487                             executeConfigContentsDelimiter = getStringBetweenQuotes(line);
488                             log.debug("executeConfigContentsDelemeter={}", executeConfigContentsDelimiter);
489                             StringTokenizer st2 = new StringTokenizer(configContents, "\n");
490                             while (st2.hasMoreTokens()) {
491                                 String cmd = st2.nextToken();
492                                 log.debug("Config_contents: cmd={}", cmd);
493                                 sshJcraftWrapper.send(cmd);
494                                 String tmpResponse = sshJcraftWrapper
495                                     .receiveUntil(executeConfigContentsDelimiter, timeout, command);
496                                 cliResponse.append(tmpResponse);
497                             }
498                         }
499                     }
500                 } catch (NoSuchElementException e) {
501                     log.error(e.getMessage(), e);
502                 }
503                 sshJcraftWrapper.closeConnection();
504                 log.debug(":Escaping all the single and double quotes in the response");
505
506                 String escapedCliResponse = cliResponse
507                     .toString()
508                     .replaceAll("\"", "\\\\\"")
509                     .replaceAll("\'", "\\\\'");
510
511                 log.debug("CliResponse=\n{}" + escapedCliResponse);
512                 ctx.setAttribute(CLI_OUTPUT_PARAM, escapedCliResponse);
513                 r.code = 200;
514                 return setResponseStatus(ctx, r);
515             } catch (IOException e) {
516                 log.error(e.getMessage() + e);
517                 sshJcraftWrapper.closeConnection();
518                 r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
519                 r.message = e.getMessage();
520                 log.debug("DownloadCliConfig: Returning error message");
521                 return setResponseStatus(ctx, r);
522             }
523         }
524         log.debug("Unsupported action - {}", action);
525         return ConfigStatus.FAILURE;
526     }
527
528     private boolean areEqual(String action, String actionPrepare) {
529         return action != null && action.equalsIgnoreCase(actionPrepare);
530     }
531
532     private boolean nullOrEmpty(String parmval) {
533         return parmval != null && parmval.length() > 0;
534     }
535
536     private void handleRpcError(HttpResponse r, String response) {
537         if (response.contains("rpc-error")) {
538             log.debug("Error from device: Response from device had 'rpc-error'");
539             log.debug(RESPONSE_STR, response);
540             r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
541             r.message = response;
542         } else {
543             log.debug(":Looks like a success");
544             log.debug(RESPONSE_STR, response);
545             r.code = 200;
546         }
547     }
548
549     private void trySleepFor(long length) {
550         try {
551             log.debug("Sleeping for 180 seconds....");
552             Thread.sleep(length);
553             log.debug("Woke up....");
554         } catch (InterruptedException ee) {
555             log.error("Sleep interrupted", ee);
556             Thread.currentThread().interrupt();
557         }
558     }
559
560     private ConfigStatus prepare(SvcLogicContext ctx, String requestType, String operation) {
561         String templateName = requestType.equals(BASE_REQUEST) ? "/config-base.xml" : "/config-data.xml";
562         String ndTemplate = expandRepeats(ctx, readFile(templateName), 1);
563         String nd = buildNetworkData2(ctx, ndTemplate, operation);
564
565         String reqTemplate = readFile("/config-request.xml");
566         Map<String, String> param = new HashMap<>();
567         param.put(REQUEST_ID_PARAM, ctx.getAttribute(SVC_REQUEST_ID_ATTR));
568         param.put("request-type", requestType);
569         param.put(CALLBACK_URL_PARAM, configCallbackUrl);
570         if (operation.equals(OPERATION_CREATE) || operation.equals(OPERATION_CHANGE)
571             || operation.equals(OPERATION_SCALE)) {
572             param.put(ACTION_PARAM, "GenerateOnly");
573         }
574         param.put(EQUIPMENT_NAME_PARAM, ctx.getAttribute(SERVICE_INSTANCE_ID_ATTR));
575         param.put("equipment-ip-address", ctx.getAttribute("service-data.vnf-config-information.vnf-host-ip-address"));
576         param.put("vendor", ctx.getAttribute("service-data.vnf-config-information.vendor"));
577         param.put("network-data", nd);
578
579         String req;
580         try {
581             req = buildXmlRequest(param, reqTemplate);
582         } catch (Exception e) {
583             log.error(XML_BUILDING_ERR_STR, e);
584
585             HttpResponse r = new HttpResponse();
586             r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
587             r.message = e.getMessage();
588             return setResponseStatus(ctx, r);
589         }
590
591         HttpResponse r = sendXmlRequest(req, configUrl, configUser, configPassword);
592         return setResponseStatus(ctx, r);
593     }
594
595     private ConfigStatus activate(SvcLogicContext ctx, boolean change) {
596         String reqTemplate = readFile("/config-request.xml");
597         Map<String, String> param = new HashMap<>();
598         param.put(REQUEST_ID_PARAM, ctx.getAttribute(SVC_REQUEST_ID_ATTR));
599         param.put(CALLBACK_URL_PARAM, configCallbackUrl);
600         param.put(ACTION_PARAM, change ? "DownloadChange" : "DownloadBase");
601         param.put(EQUIPMENT_NAME_PARAM, ctx.getAttribute(SERVICE_INSTANCE_ID_ATTR));
602
603         String req;
604         try {
605             req = buildXmlRequest(param, reqTemplate);
606         } catch (Exception e) {
607             log.error(XML_BUILDING_ERR_STR, e);
608
609             HttpResponse r = new HttpResponse();
610             r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
611             r.message = e.getMessage();
612             return setResponseStatus(ctx, r);
613         }
614
615         HttpResponse r = sendXmlRequest(req, configUrl, configUser, configPassword);
616         return setResponseStatus(ctx, r);
617     }
618
619     private ConfigStatus audit(SvcLogicContext ctx, String auditLevel) {
620         String reqTemplate = readFile("/audit-request.xml");
621         Map<String, String> param = new HashMap<>();
622         param.put(REQUEST_ID_PARAM, ctx.getAttribute(SVC_REQUEST_ID_ATTR));
623         param.put(CALLBACK_URL_PARAM, auditCallbackUrl);
624         param.put(EQUIPMENT_NAME_PARAM, ctx.getAttribute(SERVICE_INSTANCE_ID_ATTR));
625         param.put("audit-level", auditLevel);
626         String req;
627
628         try {
629             req = buildXmlRequest(param, reqTemplate);
630         } catch (Exception e) {
631             log.error(XML_BUILDING_ERR_STR, e);
632
633             HttpResponse r = new HttpResponse();
634             r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
635             r.message = e.getMessage();
636             return setResponseStatus(ctx, r);
637         }
638
639         HttpResponse r = sendXmlRequest(req, auditUrl, auditUser, auditPassword);
640         return setResponseStatus(ctx, r);
641     }
642
643     @Override
644     public ConfigStatus activate(String key, SvcLogicContext ctx) {
645         return ConfigStatus.SUCCESS;
646     }
647
648     @Override
649     public ConfigStatus deactivate(String key, SvcLogicContext ctx) {
650         return ConfigStatus.SUCCESS;
651     }
652
653     private String escapeMySql(String input) {
654         if (input == null) {
655             return null;
656         }
657
658         return input
659             .replace("\\", "\\\\")
660             .replace("\'", "\\'");
661     }
662
663     private String readFile(String fileName) {
664         InputStream is = getClass().getResourceAsStream(fileName);
665         InputStreamReader isr = new InputStreamReader(is);
666         BufferedReader in = new BufferedReader(isr);
667         StringBuilder builder = new StringBuilder();
668         try {
669             String s = in.readLine();
670             while (s != null) {
671                 builder.append(s).append('\n');
672                 s = in.readLine();
673             }
674         } catch (IOException e) {
675             throw new UncheckedIOException("Error reading " + fileName, e);
676         } finally {
677             try {
678                 in.close();
679             } catch (Exception e) {
680                 log.warn("Could not close BufferedReader", e);
681             }
682             try {
683                 isr.close();
684             } catch (Exception e) {
685                 log.warn("Could not close InputStreamReader", e);
686             }
687             try {
688                 is.close();
689             } catch (Exception e) {
690                 log.warn("Could not close InputStream", e);
691             }
692         }
693         return builder.toString();
694     }
695
696     private String buildXmlRequest(Map<String, String> param, String template) {
697         StringBuilder ss = new StringBuilder();
698         int i = 0;
699         while (i < template.length()) {
700             int i1 = template.indexOf("${", i);
701             if (i1 < 0) {
702                 ss.append(template.substring(i));
703                 break;
704             }
705
706             int i2 = template.indexOf('}', i1 + 2);
707             if (i2 < 0) {
708                 throw new TemplateException(TEMPLATE_ERR_STR);
709             }
710
711             String var1 = template.substring(i1 + 2, i2);
712             String value1 = param.get(var1);
713             if (emptyOrNull(value1)) {
714                 // delete the whole element (line)
715                 int i3 = template.lastIndexOf('\n', i1);
716                 if (i3 < 0) {
717                     i3 = 0;
718                 }
719                 int i4 = template.indexOf('\n', i1);
720                 if (i4 < 0) {
721                     i4 = template.length();
722                 }
723
724                 if (i < i3) {
725                     ss.append(template.substring(i, i3));
726                 }
727                 i = i4;
728             } else {
729                 ss.append(template.substring(i, i1)).append(value1);
730                 i = i2 + 1;
731             }
732         }
733
734         return ss.toString();
735     }
736
737     private String buildNetworkData2(SvcLogicContext ctx, String template, String operation) {
738         log.info("Building XML started");
739         long t1 = System.currentTimeMillis();
740
741         Map<String, String> mm = new HashMap<>();
742         for (String s : ctx.getAttributeKeySet()) {
743             mm.put(s, ctx.getAttribute(s));
744         }
745         mm.put("operation", operation);
746
747         StringBuilder ss = new StringBuilder();
748         int i = 0;
749         while (i < template.length()) {
750             int i1 = template.indexOf("${", i);
751             if (i1 < 0) {
752                 ss.append(template.substring(i));
753                 break;
754             }
755
756             int i2 = template.indexOf('}', i1 + 2);
757             if (i2 < 0) {
758                 throw new TemplateException(TEMPLATE_ERR_STR);
759             }
760
761             String var1 = template.substring(i1 + 2, i2);
762             String value1 = XmlUtil.getXml(mm, var1);
763             if (emptyOrNull(value1)) {
764                 int i3 = template.lastIndexOf('\n', i1);
765                 if (i3 < 0) {
766                     i3 = 0;
767                 }
768                 int i4 = template.indexOf('\n', i1);
769                 if (i4 < 0) {
770                     i4 = template.length();
771                 }
772
773                 if (i < i3) {
774                     ss.append(template.substring(i, i3));
775                 }
776                 i = i4;
777             } else {
778                 ss.append(template.substring(i, i1)).append(value1);
779                 i = i2 + 1;
780             }
781         }
782
783         long t2 = System.currentTimeMillis();
784         log.info("Building XML completed. Time: " + (t2 - t1));
785
786         return ss.toString();
787     }
788
789     private boolean emptyOrNull(String value1) {
790         return value1 == null || value1.trim().length() == 0;
791     }
792
793     private String expandRepeats(SvcLogicContext ctx, String template, int level) {
794         StringBuilder newTemplate = new StringBuilder();
795         int k = 0;
796         while (k < template.length()) {
797             int i1 = template.indexOf("${repeat:", k);
798             if (i1 < 0) {
799                 newTemplate.append(template.substring(k));
800                 break;
801             }
802
803             int i2 = template.indexOf(':', i1 + 9);
804             if (i2 < 0) {
805                 throw new TemplateException(
806                     "Template error: Context variable name followed by \":\" is required after repeat");
807             }
808
809             // Find the closing "}", store in i3
810             int i3 = findLastBracketIndex(template, i2);
811
812             String var1 = template.substring(i1 + 9, i2);
813             String value1 = ctx.getAttribute(var1);
814             log.info("     " + var1 + ": " + value1);
815             int n = tryParseValue(value1);
816
817             newTemplate.append(template.substring(k, i1));
818
819             String rpt = template.substring(i2 + 1, i3);
820
821             for (int ii = 0; ii < n; ii++) {
822                 String ss = rpt.replaceAll("\\[\\$\\{" + level + "\\}\\]", "[" + ii + "]");
823                 newTemplate.append(ss);
824             }
825             k = i3 + 1;
826         }
827
828         if (k == 0) {
829             return newTemplate.toString();
830         }
831         return expandRepeats(ctx, newTemplate.toString(), level + 1);
832     }
833
834     private int findLastBracketIndex(String template, int i2) {
835         int i3 = -1;
836         int i = i2;
837         int nn = 1;
838         while (nn > 0 && i < template.length()) {
839             i3 = template.indexOf('}', i);
840             if (i3 < 0) {
841                 throw new TemplateException(TEMPLATE_ERR_STR);
842             }
843             int i32 = template.indexOf('{', i);
844             if (i32 >= 0 && i32 < i3) {
845                 nn++;
846                 i = i32 + 1;
847             } else {
848                 nn--;
849                 i = i3 + 1;
850             }
851         }
852         return i3;
853     }
854
855     private int tryParseValue(String value1) {
856         int n;
857         try {
858             n = Integer.parseInt(value1);
859         } catch (Exception e) {
860             log.error("Failed to parse value. Using default (0).", e);
861             n = 0;
862         }
863         return n;
864     }
865
866     private HttpResponse sendXmlRequest(String xmlRequest, String url, String user, String password) {
867         try {
868             Client client = Client.create();
869             client.setConnectTimeout(5000);
870             WebResource webResource = client.resource(url);
871
872             log.info("SENDING...............");
873             log.info(xmlRequest);
874
875             String authString = user + ":" + password;
876             byte[] authEncBytes = Base64.encode(authString);
877             String authStringEnc = new String(authEncBytes);
878             authString = "Basic " + authStringEnc;
879
880             ClientResponse response =
881                 webResource.header("Authorization", authString).accept("UTF-8").type("application/xml").post(
882                     ClientResponse.class, xmlRequest);
883
884             int code = response.getStatus();
885             String message = null;
886
887             log.info("RESPONSE...............");
888             log.info("HTTP response code: " + code);
889             log.info("HTTP response message: " + message);
890             log.info("");
891
892             HttpResponse r = new HttpResponse();
893             r.code = code;
894             r.message = message;
895             return r;
896
897         } catch (Exception e) {
898             log.error("Error sending the request: ", e);
899
900             HttpResponse r = new HttpResponse();
901             r.code = HttpURLConnection.HTTP_INTERNAL_ERROR;
902             r.message = e.getMessage();
903             return r;
904         }
905     }
906
907     private static class HttpResponse {
908
909         public int code;
910         public String message;
911     }
912
913     private ConfigStatus setResponseStatus(SvcLogicContext ctx, HttpResponse r) {
914         ctx.setAttribute("error-code", String.valueOf(r.code));
915         ctx.setAttribute("error-message", r.message);
916
917         return r.code > 299 ? ConfigStatus.FAILURE : ConfigStatus.SUCCESS;
918     }
919
920     private String getStringBetweenQuotes(String string) {
921         log.debug("string=" + string);
922         String retString;
923         int start = string.indexOf('\"');
924         int end = string.lastIndexOf('\"');
925         retString = string.substring(start + 1, end);
926         log.debug("retString=" + retString);
927         return retString;
928     }
929
930     public static String _readFile(String fileName) {
931         StringBuilder builder = new StringBuilder();
932         String line;
933         try {
934             BufferedReader in = new BufferedReader(new FileReader(fileName));
935             while ((line = in.readLine()) != null) {
936                 builder.append(line).append('\n');
937             }
938             in.close();
939         } catch (IOException e) {
940             log.error("Caught an IOException in method readFile()", e);
941         }
942         return builder.toString();
943     }
944
945     private String trimResponse(String response) {
946         StringTokenizer line = new StringTokenizer(response, "\n");
947         StringBuilder builder = new StringBuilder();
948         boolean captureText = false;
949         while (line.hasMoreTokens()) {
950             String token = line.nextToken();
951             if (token.contains("<configuration xmlns=")) {
952                 captureText = true;
953             }
954             if (captureText) {
955                 builder.append(token).append('\n');
956             }
957             if (token.contains("</configuration>")) {
958                 captureText = false;
959             }
960         }
961         return builder.toString();
962     }
963
964     public static void main(String[] args) throws Exception {
965         Properties props = null;
966         log.info("*************************Hello*****************************");
967         ConfigComponentAdaptor cca = new ConfigComponentAdaptor(props);
968         String getConfigTemplate = _readFile("/home/userID/data/Get_config_template");
969         String key = "GetCliRunningConfig";
970         Map<String, String> parameters = new HashMap<>();
971         parameters.put(HOST_IP_PARAM, "000.00.000.00");
972         parameters.put(USERNAME_PARAM, "root");
973         parameters.put(PASSWORD_PARAM, "!bootstrap");
974         parameters.put(PORT_NUMBER_PARAM, "22");
975         parameters.put(GET_CONFIG_TEMPLATE_PARAM, getConfigTemplate);
976         SvcLogicContext ctx = null;
977         log.info("*************************TRACE 1*****************************");
978         cca.configure(key, parameters, ctx);
979     }
980 }