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