Test Coverage in appc-dg-netconf
[appc.git] / appc-dg / appc-dg-shared / appc-dg-netconf / src / main / java / org / onap / appc / dg / netconf / impl / NetconfClientPluginImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * ================================================================================
9  * Modifications (C) 2019 Ericsson
10  * =============================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  * 
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  * 
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * 
23  * ============LICENSE_END=========================================================
24  */
25
26 package org.onap.appc.dg.netconf.impl;
27
28 import com.att.eelf.configuration.EELFLogger;
29 import com.att.eelf.configuration.EELFManager;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import java.io.IOException;
32 import java.text.DateFormat;
33 import java.text.SimpleDateFormat;
34 import java.util.Date;
35 import java.util.Map;
36 import org.apache.commons.lang.ObjectUtils;
37 import org.apache.commons.lang3.StringUtils;
38 import org.onap.appc.adapter.netconf.NetconfClient;
39 import org.onap.appc.adapter.netconf.NetconfClientFactory;
40 import org.onap.appc.adapter.netconf.NetconfClientType;
41 import org.onap.appc.adapter.netconf.NetconfConnectionDetails;
42 import org.onap.appc.adapter.netconf.NetconfDataAccessService;
43 import org.onap.appc.adapter.netconf.OperationalStateValidator;
44 import org.onap.appc.adapter.netconf.OperationalStateValidatorFactory;
45 import org.onap.appc.adapter.netconf.VnfType;
46 import org.onap.appc.adapter.netconf.util.Constants;
47 import org.onap.appc.dg.netconf.NetconfClientPlugin;
48 import org.onap.appc.exceptions.APPCException;
49 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.FrameworkUtil;
52 import org.osgi.framework.ServiceReference;
53
54
55 public class NetconfClientPluginImpl implements NetconfClientPlugin {
56
57     private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
58     private static ObjectMapper mapper = new ObjectMapper();
59     private static final String NETCONF_CLIENT_FACTORY_NAME = "org.onap.appc.adapter.netconf.NetconfClientFactory";
60     private static final String CONNECTION_DETAILS_PARAM = "connection-details";
61     private static final String ERROR_STR = "Error ";
62     private static final String GET_CONFIG_RESULT_PARAM = "getConfig_Result";
63     private static final String FAILURE_PARAM = "failure";
64     private static final String GET_RUNNING_CONFIG_RESULT_PARAM = "getRunningConfig_Result";
65
66     private NetconfDataAccessService dao;
67     private NetconfClientFactory clientFactory;
68
69     public NetconfClientPluginImpl() {
70         BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
71         ServiceReference<NetconfClientFactory> srefNetconfClientFactory = bctx
72             .getServiceReference(NetconfClientFactory.class);
73         clientFactory = bctx.getService(srefNetconfClientFactory);
74     }
75
76     public void setDao(NetconfDataAccessService dao) {
77         this.dao = dao;
78         this.dao.setSchema(Constants.NETCONF_SCHEMA);
79     }
80
81     public void configure(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
82
83         try {
84             // by default, it uses the jsch Netconf Adapter implementation by calling getNetconfClient(NetconfClientType.SSH).
85             NetconfClient client = clientFactory.getNetconfClient(NetconfClientType.SSH);
86             connect(params, client);
87         } catch (Exception e) {
88             ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage());
89             logger.error(ERROR_STR + e.getMessage());
90             throw e;
91         }
92     }
93
94     private void connect(Map<String, String> params, NetconfClient client) throws APPCException {
95         try {
96             NetconfConnectionDetails connectionDetails = mapper
97                 .readValue(params.get(CONNECTION_DETAILS_PARAM), NetconfConnectionDetails.class);
98             String netconfMessage = params.get("file-content");
99             client.connect(connectionDetails);
100             client.configure(netconfMessage);
101         } catch (IOException e) {
102             logger.error(ERROR_STR + e.getMessage());
103             throw new APPCException(e);
104         } finally {
105             client.disconnect();
106         }
107     }
108
109     @Override
110     public void operationStateValidation(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
111         if (logger.isTraceEnabled()) {
112             logger.trace("Entering to operationStateValidation with params = " + ObjectUtils.toString(params)
113                 + ", SvcLogicContext = " + ObjectUtils.toString(ctx));
114         }
115         try {
116             String paramName = Constants.VNF_TYPE_FIELD_NAME;
117             String vfType = params.get(paramName);
118             validateMandatoryParam(paramName, vfType);
119             VnfType vnfType = VnfType.getVnfType(vfType);
120
121             paramName = Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME;
122             String vnfHostIpAddress = params.get(paramName);
123             validateMandatoryParam(paramName, vnfHostIpAddress);
124
125             //get connectionDetails
126             String connectionDetailsStr = params.get(Constants.CONNECTION_DETAILS_FIELD_NAME);
127             NetconfConnectionDetails connectionDetails =
128                 resolveConnectionDetails(ctx, vnfType, vnfHostIpAddress, connectionDetailsStr);
129
130             if (connectionDetails == null) {
131                 throw new IllegalStateException("missing connectionDetails for VnfType:" + vnfType.name());
132             }
133
134             //get operationsStateNetconfMessage
135             OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory
136                 .getOperationalStateValidator(vnfType);
137             String configurationFileName = operationalStateValidator.getConfigurationFileName();
138             String operationsStateNetconfMessage = null;
139             if (!StringUtils.isEmpty(configurationFileName)) {
140                 operationsStateNetconfMessage = retrieveConfigurationFileContent(configurationFileName);
141             }
142
143             //connect checK Opertaions state and dissconnect
144             NetconfClient client = clientFactory.getNetconfClient(NetconfClientType.SSH);
145             try {
146                 client.connect(connectionDetails);
147                 String response = null;
148                 if (!StringUtils.isEmpty(operationsStateNetconfMessage)) {
149                     response = client.exchangeMessage(operationsStateNetconfMessage);
150                 }
151                 operationalStateValidator.validateResponse(response);
152             } finally {
153                 client.disconnect();
154             }
155         } catch (APPCException e) {
156             logger.error(e.getMessage());
157             ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.toString());
158             throw e;
159         } catch (Exception e) {
160             logger.error(e.toString());
161             ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.toString());
162             throw new APPCException(e);
163         }
164     }
165
166     private NetconfConnectionDetails resolveConnectionDetails(SvcLogicContext ctx, VnfType vnfType,
167         String vnfHostIpAddress, String connectionDetailsStr) throws APPCException, IOException {
168
169         NetconfConnectionDetails connectionDetails;
170         if (StringUtils.isEmpty(connectionDetailsStr)) {
171             connectionDetails = retrieveConnectionDetails(vnfType);
172             connectionDetails.setHost(vnfHostIpAddress);
173             ctx.setAttribute(Constants.CONNECTION_DETAILS_FIELD_NAME, mapper.writeValueAsString(connectionDetails));
174         } else {
175             connectionDetails = mapper.readValue(connectionDetailsStr, NetconfConnectionDetails.class);
176         }
177         return connectionDetails;
178     }
179
180     @Override
181     public void modifyConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
182         this.configure(params, ctx);
183     }
184
185     @Override
186     public void backupConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
187
188         NetconfClient client = null;
189         try {
190             logger.debug("Entered backup to DEVICE_INTERFACE_LOG");
191
192             client = clientFactory.getNetconfClient(NetconfClientType.SSH);
193             //get connection details
194             NetconfConnectionDetails connectionDetails = mapper
195                 .readValue(params.get(CONNECTION_DETAILS_PARAM), NetconfConnectionDetails.class);
196             //connect the client and get configuration
197             client.connect(connectionDetails);
198             String configuration = client.getConfiguration();
199
200             //store configuration in database
201             dao.logDeviceInteraction(null, null, getCurrentDateTime(), configuration);
202
203         } catch (Exception e) {
204             logger.error(ERROR_STR + e.getMessage());
205             ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage());
206             throw new APPCException(e);
207         } finally {
208             //disconnect the client
209             if (client != null) {
210                 client.disconnect();
211             }
212         }
213     }
214
215     @Override
216     public void getConfig(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
217         NetconfClient client = null;
218         String confId = params.get("conf-id");
219         if ("current".equalsIgnoreCase(confId)) {
220             try {
221                 logger.debug("Entered getConfig to DEVICE_INTERFACE_LOG");
222                 //get netconf client to get configuration
223                 BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
224                 ServiceReference sref = bctx.getServiceReference(NETCONF_CLIENT_FACTORY_NAME);
225                 NetconfClientFactory clientFact = (NetconfClientFactory) bctx.getService(sref);
226                 client = clientFact.getNetconfClient(NetconfClientType.SSH);
227                 //get connection details
228                 NetconfConnectionDetails connectionDetails = mapper
229                     .readValue(params.get(CONNECTION_DETAILS_PARAM), NetconfConnectionDetails.class);
230                 //connect the client and get configuration
231                 client.connect(connectionDetails);
232                 String configuration = client.getConfiguration();
233                 if (configuration != null) {
234                     String fullConfig = ctx.getAttribute("fullConfig");
235                     fullConfig = fullConfig == null ? "" : fullConfig;
236                     ctx.setAttribute("fullConfig", fullConfig + configuration);
237
238                     ctx.setAttribute(GET_CONFIG_RESULT_PARAM, "Success");
239                     String entityName = ctx.getAttribute("entity");//VM name
240                     trySetEntityConfiguration(ctx, configuration, entityName);
241                 } else {
242                     ctx.setAttribute(GET_CONFIG_RESULT_PARAM, FAILURE_PARAM);
243                 }
244             } catch (Exception e) {
245                 ctx.setAttribute(GET_CONFIG_RESULT_PARAM, FAILURE_PARAM);
246                 logger.error(ERROR_STR + e.getMessage());
247                 ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage());
248                 throw new APPCException(e);
249             } finally {
250                 //disconnect the client
251                 if (client != null) {
252                     client.disconnect();
253                 }
254             }
255         } else {
256             logger.info("Current Conf id value is not supported");
257         }
258
259     }
260
261     private void trySetEntityConfiguration(SvcLogicContext ctx, String configuration, String entityName) {
262         if (entityName != null) {
263             ctx.setAttribute(entityName + ".Configuration", configuration);
264         }
265     }
266
267
268     @Override
269     public void getRunningConfig(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
270         NetconfClient client = null;
271         try {
272             logger.info("Entered getRunningConfig to DEVICE_INTERFACE_LOG");
273             //get netconf client to get configuration
274             BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
275             ServiceReference sref = bctx.getServiceReference(NETCONF_CLIENT_FACTORY_NAME);
276             NetconfClientFactory clientFact = (NetconfClientFactory) bctx.getService(sref);
277             client = clientFact.getNetconfClient(NetconfClientType.SSH);
278             //get connection details
279             NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
280             connectionDetails.setHost(params.get("host-ip-address"));
281             connectionDetails.setUsername(params.get("user-name"));
282             connectionDetails.setPassword(params.get("password"));
283             connectionDetails.setPort(
284                 !("".equalsIgnoreCase(params.get("port-number"))) ? Integer.parseInt(params.get("port-number"))
285                     : NetconfConnectionDetails.DEFAULT_PORT);
286             //connect the client and get configuration
287             client.connect(connectionDetails);
288             String configuration = client.getConfiguration();
289             if (configuration != null) {
290                 ctx.setAttribute("running-config", configuration);
291
292                 ctx.setAttribute(GET_RUNNING_CONFIG_RESULT_PARAM, "Success");
293             } else {
294                 ctx.setAttribute(GET_RUNNING_CONFIG_RESULT_PARAM, FAILURE_PARAM);
295             }
296         } catch (Exception e) {
297             ctx.setAttribute(GET_RUNNING_CONFIG_RESULT_PARAM, FAILURE_PARAM);
298             logger.error(ERROR_STR + e.getMessage());
299             ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage());
300             throw new APPCException(e);
301         } finally {
302             //disconnect the client
303             if (client != null) {
304                 client.disconnect();
305             }
306         }
307     }
308
309     private String getCurrentDateTime() {
310
311         DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
312         Date date = new Date();
313         return dateFormat.format(date);
314     }
315
316     void validateMandatoryParam(String paramName, String paramValue) {
317         if (StringUtils.isEmpty(paramValue)) {
318             throw new IllegalArgumentException("input " + paramName + " param is empty");
319         }
320     }
321
322     public NetconfConnectionDetails retrieveConnectionDetails(VnfType vnfType) throws APPCException {
323
324         NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
325         if (!dao.retrieveNetconfConnectionDetails(vnfType.getFamilyType().name(), connectionDetails)) {
326             logger.error("Missing configuration for " + vnfType.getFamilyType().name());
327             throw new APPCException("Missing configuration for " + vnfType.getFamilyType().name() + " in "
328                 + Constants.DEVICE_AUTHENTICATION_TABLE_NAME);
329         }
330         return connectionDetails;
331     }
332
333     public String retrieveConfigurationFileContent(String configFileName) {
334         return dao.retrieveConfigFileName(configFileName);
335     }
336 }