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