5f26f512ea8606d79bb30d976a75529c9760553f
[appc.git] / appc-inbound / appc-artifact-handler / provider / src / main / java / org / onap / appc / artifact / handler / node / ArtifactHandlerNode.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * ================================================================================
9  * Modifications Copyright (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.artifact.handler.node;
27
28 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ACTION;
29 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ACTION_LEVEL;
30 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ACTION_LEVEL_VF_MODULE;
31 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ACTION_LEVEL_VM;
32 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ACTION_LEVEL_VNF;
33 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ACTION_LEVEL_VNFC;
34 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_CONTENTS;
35 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_DESRIPTION;
36 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_NAME;
37 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_NAME_CAPABILITY;
38 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_NAME_REFERENCE;
39 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_TYPE;
40 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_UUID;
41 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ARTIFACT_VERSION;
42 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.CAPABILITY;
43 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DB_CONFIG_ACTION_DG;
44 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DB_DEVICE_AUTHENTICATION;
45 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DB_DEVICE_INTERFACE_PROTOCOL;
46 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DB_DOWNLOAD_DG_REFERENCE;
47 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DB_SDC_REFERENCE;
48 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DEVICE_PROTOCOL;
49 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DISTRIBUTION_ID;
50 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DOCUMENT_PARAMETERS;
51 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.DOWNLOAD_DG_REFERENCE;
52 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.FILE_CATEGORY;
53 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.GROUP_NOTATION_TYPE;
54 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.GROUP_NOTATION_VALUE;
55 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.IPADDRESS_V4_OAM_VIP;
56 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.PARAMETER_YANG;
57 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.PD;
58 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.PORT_NUMBER;
59 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.REFERENCE;
60 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.REQUEST_ID;
61 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.REQUEST_INFORMATION;
62 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.RESOURCE_INSTANCE_NAME;
63 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.RESOURCE_NAME;
64 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.RESOURCE_TYPE;
65 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.RESOURCE_UUID;
66 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.RESOURCE_VERSION;
67 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.SERVICE_DESCRIPTION;
68 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.SERVICE_NAME;
69 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.SERVICE_UUID;
70 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.TEMPLATE;
71 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.TEMPLATE_ID;
72 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.TOSCA_MODEL;
73 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.USER_NAME;
74 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VM;
75 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VM_INSTANCE;
76 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNFC;
77 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNFC_FUNCTION_CODE;
78 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNFC_FUNCTION_CODE_LIST;
79 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNFC_INSTANCE;
80 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNFC_TYPE;
81 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNFC_TYPE_LIST;
82 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.VNF_TYPE;
83 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.URL;
84 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.OPENSTACK;
85 import static org.onap.appc.artifact.handler.utils.SdcArtifactHandlerConstants.ANSIBLE;
86 import com.att.eelf.configuration.EELFLogger;
87 import com.att.eelf.configuration.EELFManager;
88 import java.io.ByteArrayOutputStream;
89 import java.io.OutputStream;
90 import java.sql.SQLException;
91 import java.util.Map;
92 import java.util.function.Function;
93 import org.apache.commons.configuration.ConfigurationException;
94 import org.apache.commons.lang.StringUtils;
95 import org.json.JSONArray;
96 import org.json.JSONException;
97 import org.json.JSONObject;
98 import org.onap.appc.artifact.handler.dbservices.DBException;
99 import org.onap.appc.artifact.handler.dbservices.DBService;
100 import org.onap.appc.artifact.handler.utils.ArtifactHandlerProviderUtil;
101 import org.onap.appc.yang.YANGGenerator;
102 import org.onap.appc.yang.impl.YANGGeneratorFactory;
103 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
104 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
105 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
106 import org.onap.sdnc.config.params.transformer.tosca.ArtifactProcessorImpl;
107 import org.onap.sdnc.config.params.transformer.tosca.exceptions.ArtifactProcessorException;
108 import java.util.ArrayList;
109 import java.util.HashMap;
110 import java.util.List;
111
112 public class ArtifactHandlerNode implements SvcLogicJavaPlugin {
113
114     private static final EELFLogger log = EELFManager.getInstance().getLogger(ArtifactHandlerNode.class);
115     private static final String TOSCA_PARAM = "Tosca";
116     private static final String YANG_PARAM = "Yang";
117     private static final String ARTIFACT_LIST_PARAM = "artifact-list";
118     private static final String CONFIGURE_PARAM = "Configure";
119     private static final String CONFIG_SCALE_OUT_PARAM = "ConfigScaleOut";
120     private static final String CONFIG_MODIFY_PARAM = "ConfigModify";
121     private static final String GET_CONFIG = "GetConfig";
122     private static final String POST_EVACUATE = "PostEvacuate";
123     private static final String PRE_EVACUATE = "PreEvacuate";
124     private static final String POST_MIGRATE = "PostMigrate";
125     private static final String PRE_MIGRATE = "PreMigrate";
126     private static final String PRE_REBUILD = "PreRebuild";
127     private static final String POST_REBUILD = "PostRebuild";
128     private static final String STOP_TRAFFIC = "StopTraffic";
129     private static final String CONFIG_SCALE_IN_PARAM = "ConfigScaleIn";
130     
131     public void processArtifact(Map<String, String> inParams, SvcLogicContext ctx) throws ArtifactProcessorException {
132
133         if (inParams == null || inParams.isEmpty()) {
134             return;
135         }
136         String postData = inParams.get("postData");
137         if (StringUtils.isBlank(postData)) {
138             return;
139         }
140         try {
141             log.info("Received request for process Artifact with params: " + inParams.toString());
142             JSONObject input = new JSONObject(postData).getJSONObject("input");
143             storeUpdateSdcArtifacts(input);
144         } catch (Exception e) {
145             log.error("Error when processing artifact", e);
146             throw new ArtifactProcessorException("Error occurred while processing artifact, " + e.getMessage(), e);
147         }
148     }
149
150     private boolean storeUpdateSdcArtifacts(JSONObject postDataJson) throws ArtifactHandlerInternalException {
151         log.info("Starting processing of SDC Artifacts into Handler with Data: " + postDataJson.toString());
152         try {
153             JSONObject requestInfo = (JSONObject) postDataJson.get(REQUEST_INFORMATION);
154             JSONObject documentInfo = (JSONObject) postDataJson.get(DOCUMENT_PARAMETERS);
155             String artifactName = documentInfo.getString(ARTIFACT_NAME);
156
157             if (StringUtils.isBlank(artifactName)) {
158                 throw new ArtifactHandlerInternalException("Missing Artifact Name");
159             }
160
161             if (artifactName.toLowerCase().startsWith(ANSIBLE)) {
162                 validateAnsibleAdminArtifact(documentInfo);
163                 log.info("validateAnsibleAdminArtifact sucessfully done");
164             }
165
166             updateStoreArtifacts(requestInfo, documentInfo);
167
168             if (artifactName.toLowerCase().startsWith(REFERENCE)) {
169                 return storeReferenceData(requestInfo, documentInfo);
170             } else if (artifactName.toLowerCase().startsWith(PD)) {
171                 return createDataForPD(requestInfo, documentInfo);
172             }
173
174         } catch (Exception e) {
175             log.error("Error while processing request with id: "
176                     + ((JSONObject) postDataJson.get(REQUEST_INFORMATION)).getString(REQUEST_ID), e);
177             throw new ArtifactHandlerInternalException("Error while processing request with id: "
178                     + ((JSONObject) postDataJson.get(REQUEST_INFORMATION)).getString(REQUEST_ID)
179                     + ", Exception Message: " + e.getMessage(), e);
180         }
181         return false;
182     }
183
184     public void validateAnsibleAdminArtifact(JSONObject documentInfo) throws ArtifactHandlerInternalException {
185
186         String fn = "ArtifactHandlerNode.validateAnsibleAdminArtifact";
187         String artifactName = documentInfo.getString(ARTIFACT_NAME);
188         log.info(fn + ": Received Admin File Name: " + artifactName
189                 + ", ArtifactContent: " + documentInfo.getString(ARTIFACT_CONTENTS));
190         try {
191             ArtifactHandlerProviderUtil ahpUtil = new ArtifactHandlerProviderUtil();
192             String contentString = ahpUtil.escapeSql(documentInfo.getString(ARTIFACT_CONTENTS));
193             JSONObject artifact = new JSONObject(contentString);
194             JSONArray fqdnList = artifact.getJSONArray("fqdn-list");
195             Map<String, List<String>> artifactMap = new HashMap<>();
196
197             for (int i = 0; i < fqdnList.length(); i++) {
198                 JSONObject fqdn = fqdnList.getJSONObject(i);
199                 List<String> valuesforFQDN = populateValueForFQDN(fqdn);
200                 artifactMap.put(fqdn.getString("vnf-management-server-fqdn"), valuesforFQDN);
201             }
202
203             validateKeyValue(artifactMap);
204
205         } catch (JSONException je) {
206             log.error(fn + " ansible admin artifact content may not be a valid JSON, error message: "
207                     + je.getMessage());
208             throw new ArtifactHandlerInternalException(
209                     "JSON Exception:ansible admin artifact content may not be a valid JSON, error message: "
210                     + je.getMessage(),
211                     je);
212         } catch (ArtifactHandlerInternalException ae) {
213             throw ae;
214         } catch (Exception e) {
215             log.error(fn + "Error while creating Admin data records", e);
216             throw new ArtifactHandlerInternalException(
217                     "Error while processing ansible admin artifact: " + e.getMessage(), e);
218         }
219
220     }
221
222     private void validateKeyValue(Map<String, List<String>> artifactMap) throws ArtifactHandlerInternalException {
223         for (String fqdn1 : artifactMap.keySet()) {
224
225             for (String value : artifactMap.get(fqdn1)) {
226
227                 for (String fqdn2 : artifactMap.keySet()) {
228
229                     if (!fqdn1.equals(fqdn2) && artifactMap.get(fqdn2).contains(value)) {
230                         String msg = "Validation Failure: Ansible Admin artifact has CloudOwner-RegionId-Tenant: "
231                                 + value + " mapped to multiple FQDN: " + fqdn1 + " & " + fqdn2;
232                         log.info(msg);
233                         throw new ArtifactHandlerInternalException(msg);
234                     }
235
236                 }
237             }
238
239         }
240
241     }
242
243     private List<String> populateValueForFQDN(JSONObject fqdn) {
244         log.info("Inside populateValueForFQDN: " + fqdn.getString("vnf-management-server-fqdn"));
245         List<String> valuesforFQDN = new ArrayList<>();
246         JSONArray cloudJsonList = fqdn.getJSONArray("cloud-owner-list");
247         for (int j = 0; j < cloudJsonList.length(); j++) {
248             String cloudOwner = cloudJsonList.getJSONObject(j).getString("cloud-owner");
249             JSONArray regionList = cloudJsonList.getJSONObject(j).getJSONArray("region-id-list");
250
251             for (int i = 0; i < regionList.length(); i++) {
252
253                 String region = regionList.getJSONObject(i).getString("region-id");
254
255                 JSONArray tenantList = regionList.getJSONObject(i).getJSONArray("tenant-id-list");
256
257                 for (int k = 0; k < tenantList.length(); k++) {
258                     String tenant = tenantList.getString(k);
259                     String valueforFQDN = cloudOwner + "-" + region + "-" + tenant;
260                     log.info("valueforFQDN for i " + i + " & j " + j + ": " + valueforFQDN);
261                     valuesforFQDN.add(valueforFQDN);
262                 }
263             }
264         }
265
266         return valuesforFQDN;
267     }
268
269     private boolean createDataForPD(JSONObject requestInfo, JSONObject documentInfo)
270             throws ArtifactHandlerInternalException {
271
272         String fn = "ArtifactHandlerNode.createReferenceDataForPD";
273         String artifactName = documentInfo.getString(ARTIFACT_NAME);
274         log.info(fn + " Received PD File Name: " + artifactName + " and suffix length " + PD.length());
275         try {
276
277             String suffix = artifactName.substring(PD.length());
278             createArtifactRecords(requestInfo, documentInfo, suffix);
279         } catch (Exception e) {
280             log.error("Error while creating PD data records", e);
281             throw new ArtifactHandlerInternalException("Error while creating PD data records", e);
282         }
283         return true;
284     }
285
286     private void createArtifactRecords(JSONObject requestInfo, JSONObject documentInfo, String suffix)
287             throws ArtifactHandlerInternalException {
288
289         try {
290             log.info("Creating Tosca Records and storing into SDC Artifacts");
291             String[] docs = { TOSCA_PARAM, YANG_PARAM };
292             ArtifactHandlerProviderUtil ahpUtil = new ArtifactHandlerProviderUtil();
293             String pdFileContents = documentInfo.getString(ARTIFACT_CONTENTS);
294
295             // Tosca generation
296             OutputStream toscaStream = new ByteArrayOutputStream();
297             String toscaContents;
298             ArtifactProcessorImpl toscaGenerator = getArtifactProcessorImpl();
299             toscaGenerator.generateArtifact(pdFileContents, toscaStream);
300             toscaContents = toscaStream.toString();
301             log.info("Generated Tosca File: " + toscaContents);
302
303             String yangContents = "YANG generation is in Progress";
304             String yangName = null;
305
306             for (String doc : docs) {
307                 documentInfo.put(ARTIFACT_TYPE, doc.concat("Type"));
308                 documentInfo.put(ARTIFACT_DESRIPTION, doc.concat("Model"));
309                 if (doc.equals(TOSCA_PARAM)) {
310                     documentInfo.put(ARTIFACT_CONTENTS, ahpUtil.escapeSql(toscaContents));
311                 } else if (doc.equals(YANG_PARAM)) {
312                     documentInfo.put(ARTIFACT_CONTENTS, ahpUtil.escapeSql(yangContents));
313                 }
314                 documentInfo.put(ARTIFACT_NAME, doc.concat(suffix));
315                 yangName = doc.concat(suffix);
316                 updateStoreArtifacts(requestInfo, documentInfo);
317             }
318
319             String artifactId = getArtifactID(yangName);
320             OutputStream yangStream = new ByteArrayOutputStream();
321             YANGGenerator yangGenerator = YANGGeneratorFactory.getYANGGenerator();
322             yangGenerator.generateYANG(artifactId, toscaContents, yangStream);
323             yangContents = yangStream.toString();
324
325             if (yangContents != null) {
326                 updateYangContents(artifactId, ahpUtil.escapeSql(yangContents));
327             }
328         } catch (Exception e) {
329             log.error("Error while creating artifact records", e);
330             throw new ArtifactHandlerInternalException("Error while creating artifact records", e);
331         }
332
333     }
334
335     private void updateYangContents(String artifactId, String yangContents) throws SvcLogicException {
336         SvcLogicContext context = new SvcLogicContext();
337         DBService dbservice = DBService.initialise();
338         dbservice.updateYangContents(context, artifactId, yangContents);
339     }
340
341     private String getArtifactID(String yangName) throws SvcLogicException {
342         SvcLogicContext context = new SvcLogicContext();
343         DBService dbservice = DBService.initialise();
344         return dbservice.getArtifactID(context, yangName);
345     }
346
347     protected boolean updateStoreArtifacts(JSONObject requestInfo, JSONObject documentInfo)
348             throws SvcLogicException, SQLException {
349         log.info("updateStoreArtifacts started storing of SDC Artifacts");
350
351         SvcLogicContext context = new SvcLogicContext();
352         DBService dbservice = DBService.initialise();
353         ArtifactHandlerProviderUtil ahpUtil = new ArtifactHandlerProviderUtil();
354         int intversion = 0;
355         context.setAttribute("artifact_name", documentInfo.getString(ARTIFACT_NAME));
356         String internalVersion =
357                 dbservice.getInternalVersionNumber(context, documentInfo.getString(ARTIFACT_NAME), null);
358         log.info("Internal Version number received from Database: " + internalVersion);
359         if (internalVersion != null) {
360             intversion = Integer.parseInt(internalVersion);
361             intversion++;
362         }
363         setAttribute(context, documentInfo::getString, SERVICE_UUID);
364         setAttribute(context, documentInfo::getString, DISTRIBUTION_ID);
365         setAttribute(context, documentInfo::getString, SERVICE_NAME);
366         setAttribute(context, documentInfo::getString, SERVICE_DESCRIPTION);
367         setAttribute(context, documentInfo::getString, RESOURCE_UUID);
368         setAttribute(context, documentInfo::getString, RESOURCE_INSTANCE_NAME);
369         setAttribute(context, documentInfo::getString, RESOURCE_VERSION);
370         setAttribute(context, documentInfo::getString, RESOURCE_NAME);
371         setAttribute(context, documentInfo::getString, RESOURCE_TYPE);
372         setAttribute(context, documentInfo::getString, ARTIFACT_UUID);
373         setAttribute(context, documentInfo::getString, ARTIFACT_TYPE);
374         setAttribute(context, documentInfo::getString, ARTIFACT_VERSION);
375         setAttribute(context, documentInfo::getString, ARTIFACT_DESRIPTION);
376         setAttribute(context, documentInfo::getString, ARTIFACT_NAME);
377         setAttribute(context, s -> ahpUtil.escapeSql(documentInfo.getString(s)), ARTIFACT_CONTENTS);
378
379         dbservice.saveArtifacts(context, intversion);
380         return true;
381     }
382
383     public boolean storeReferenceData(JSONObject requestInfo, JSONObject documentInfo)
384             throws ArtifactHandlerInternalException {
385         log.info("Started storing of SDC Artifacts into Handler");
386         try {
387             DBService dbservice = DBService.initialise();
388             ArtifactHandlerProviderUtil ahpUtil = new ArtifactHandlerProviderUtil();
389             String contentString = ahpUtil.escapeSql(documentInfo.getString(ARTIFACT_CONTENTS));
390             String artifactName = ahpUtil.escapeSql(documentInfo.getString(ARTIFACT_NAME));
391             String capabilityArtifactName =
392                     StringUtils.replace(artifactName, ARTIFACT_NAME_REFERENCE, ARTIFACT_NAME_CAPABILITY);
393             JSONObject capabilities = new JSONObject();
394             JSONArray vnfActionList = new JSONArray();
395             JSONArray vfModuleActionList = new JSONArray();
396             JSONArray vnfcActionList = new JSONArray();
397             JSONArray vmActionVnfcFunctionCodesList = new JSONArray();
398             String vnfType = null;
399             JSONObject contentObject = new JSONObject(contentString);
400             JSONArray contentArray = contentObject.getJSONArray("reference_data");
401             boolean storeCapabilityArtifact = true;
402
403             for (int a = 0; a < contentArray.length(); a++) {
404                 JSONObject content = contentArray.getJSONObject(a);
405                 log.info("contentString = " + content.toString());
406                 JSONObject scope = content.getJSONObject("scope");
407                 log.info("scope: " + scope);
408                 SvcLogicContext context = new SvcLogicContext();
409                 vnfType = scope.getString(VNF_TYPE);
410                 setAttribute(context, scope::getString, VNF_TYPE);
411                 setAttribute(context, content::getString, ACTION);
412                 String actionLevel = content.getString(ACTION_LEVEL);
413                 setAttribute(context, content::getString, ACTION_LEVEL);
414                 setAttribute(context, documentInfo::getString, ARTIFACT_TYPE);
415                 processActionLists(content, actionLevel, vnfcActionList, vfModuleActionList, vnfActionList,
416                         vmActionVnfcFunctionCodesList);
417                 JSONArray vnfcTypeList = setVnfcTypeInformation(scope, context);
418                 storeCapabilityArtifact = isCapabilityArtifactNeeded(context);
419
420                 if (content.has(DEVICE_PROTOCOL)) {
421                     setAttribute(context, content::getString, DEVICE_PROTOCOL);
422                 }
423                 if (content.has(USER_NAME)) {
424                     setAttribute(context, content::getString, USER_NAME);
425                 }
426                 if (content.has(PORT_NUMBER)) {
427                     setAttribute(context, content::getString, PORT_NUMBER);
428                 }
429                 if (content.has(URL)) {
430                     setAttribute(context, content::getString, URL);
431                 }
432                 processArtifactList(content, dbservice, context, vnfcTypeList);
433                 processConfigTypeActions(content, dbservice, context);
434                 dbservice.processDeviceAuthentication(context,
435                         dbservice.isArtifactUpdateRequired(context, DB_DEVICE_AUTHENTICATION));
436
437                 String actionProtocol = tryGetProtocol(content);
438                 if (!StringUtils.equalsIgnoreCase(actionProtocol, OPENSTACK)) {
439                     populateProtocolReference(dbservice, content);
440                 }
441                 context.setAttribute(VNFC_TYPE, null);
442                 if (content.has(VM) && content.get(VM) instanceof JSONArray) {
443                     processVmList(content, context, dbservice);
444                 }
445             }
446             if (storeCapabilityArtifact) {
447                 capabilities.put("vnf", vnfActionList);
448                 capabilities.put("vf-module", vfModuleActionList);
449                 capabilities.put("vnfc", vnfcActionList);
450                 capabilities.put("vm", vmActionVnfcFunctionCodesList);
451                 processAndStoreCapabilitiesArtifact(dbservice, documentInfo, capabilities, capabilityArtifactName,
452                         vnfType);
453             }
454
455         } catch (Exception e) {
456
457             log.error("Error while storing reference data", e);
458             throw new ArtifactHandlerInternalException("Error while storing reference data", e);
459         }
460
461         return true;
462     }
463
464     public boolean isCapabilityArtifactNeeded(SvcLogicContext context) {
465         String vnfcType = context.getAttribute(VNFC_TYPE);
466         if (StringUtils.isNotBlank(vnfcType)) {
467             log.info("No capability Artifact for this reference data as it is at VNFC level!!");
468             return false;
469         } else {
470             return true;
471         }
472     }
473
474     public JSONArray setVnfcTypeInformation(JSONObject scope, SvcLogicContext context) {
475         JSONArray vnfcTypeList = null;
476         if (scope.has(VNFC_TYPE) && !scope.isNull(VNFC_TYPE)) {
477             String vnfcTypeScope = scope.getString(VNFC_TYPE);
478             if (StringUtils.isNotBlank(vnfcTypeScope)) {
479                 setAttribute(context, scope::getString, VNFC_TYPE);
480                 log.info("VNFC type has been set for this reference artifact!! " + vnfcTypeScope);
481             } else {
482                 context.setAttribute(VNFC_TYPE, null);
483             }
484         } else {
485             context.setAttribute(VNFC_TYPE, null);
486         }
487         if (scope.has(VNFC_TYPE_LIST) && !scope.isNull(VNFC_TYPE_LIST)
488                 && scope.get(VNFC_TYPE_LIST) instanceof JSONArray) {
489             vnfcTypeList = scope.getJSONArray(VNFC_TYPE_LIST);
490             log.info("VNFC TYPE LIST found for this artifact!! " + vnfcTypeList.toString());
491         }
492         return vnfcTypeList;
493     }
494
495     public void processActionLists(JSONObject content, String actionLevel, JSONArray vnfcActionList,
496             JSONArray vfModuleActionList, JSONArray vnfActionList, JSONArray vmActionVnfcFunctionCodesList) {
497         if (validateActionLevel(actionLevel, ACTION_LEVEL_VNFC)) {
498             vnfcActionList.put(content.getString(ACTION));
499         }
500         if (validateActionLevel(actionLevel, ACTION_LEVEL_VF_MODULE)) {
501             vfModuleActionList.put(content.getString(ACTION));
502         }
503         if (validateActionLevel(actionLevel, ACTION_LEVEL_VNF)) {
504             vnfActionList.put(content.getString(ACTION));
505         }
506         if (validateActionLevel(actionLevel, ACTION_LEVEL_VM)) {
507             if (content.has(VNFC_FUNCTION_CODE_LIST)
508                     && !content.isNull(VNFC_FUNCTION_CODE_LIST)
509                     && content.get(VNFC_FUNCTION_CODE_LIST) instanceof JSONArray) {
510                 log.info("Found vnfc-function-code-list!!");
511                 JSONArray vnfcList = content.getJSONArray(VNFC_FUNCTION_CODE_LIST);
512                 JSONObject obj = new JSONObject();
513                 obj.put(content.getString(ACTION), vnfcList);
514                 vmActionVnfcFunctionCodesList.put(obj);
515             } else {
516                 log.info("Not getting JSONArray for VNFC FUNCTION CODES");
517             }
518         }
519
520     }
521
522     private boolean validateActionLevel(String actionLevel, String actionLevelVnfc) {
523         return null != actionLevel && actionLevel.equalsIgnoreCase(actionLevelVnfc);
524     }
525
526     public void processArtifactList(JSONObject content, DBService dbservice, SvcLogicContext context,
527             JSONArray vnfcTypeList)
528             throws ArtifactHandlerInternalException {
529
530         try {
531             if (content.has(ARTIFACT_LIST_PARAM) && content.get(ARTIFACT_LIST_PARAM) instanceof JSONArray) {
532                 JSONArray artifactLists = (JSONArray) content.get(ARTIFACT_LIST_PARAM);
533                 JSONArray templateIdList = null;
534                 if (content.has("template-id-list") && null != content.get("template-id-list")
535                         && content.get("template-id-list") instanceof JSONArray) {
536                     templateIdList = content.getJSONArray("template-id-list");
537                 }
538                 doProcessArtifactList(dbservice, context, artifactLists, templateIdList, vnfcTypeList);
539             }
540         } catch (Exception e) {
541             log.error("An error occurred when processing artifact list", e);
542             throw new ArtifactHandlerInternalException(e);
543         }
544     }
545
546     private void doProcessArtifactList(DBService dbservice, SvcLogicContext context, JSONArray artifactLists,
547             JSONArray templateIdList, JSONArray vnfcTypeList)
548             throws SvcLogicException, SQLException, ConfigurationException, DBException {
549         boolean pdFile = false;
550         int modelInd = 0;
551         int vnfcRefInd = 0;
552
553         for (int i = 0; i < artifactLists.length(); i++) {
554             String suffix = null;
555             String model = null;
556             JSONObject artifact = (JSONObject) artifactLists.get(i);
557             log.info("artifact is " + artifact);
558
559             // Get Model details
560             if (null != templateIdList && i > 0 && i % 2 == 0) { // Should this be changed to 3
561                 modelInd++; // to account for 3 artifacts
562             }
563             if (null != vnfcTypeList && i > 0 && i % 3 == 0) {
564                 // TDP 517180 - CD tool has made changes to send 3 artifacts instead of 2
565                 vnfcRefInd++;
566             }
567             setAttribute(context, artifact::getString, ARTIFACT_NAME);
568             context.setAttribute(FILE_CATEGORY, artifact.getString(ARTIFACT_TYPE));
569
570             if (artifact.getString(ARTIFACT_NAME) != null
571                     && artifact.getString(ARTIFACT_NAME).toLowerCase().startsWith(PD)) {
572
573                 suffix = artifact.getString(ARTIFACT_NAME).substring(PD.length());
574                 pdFile = true;
575             }
576             log.info("Artifact-type = " + context.getAttribute(FILE_CATEGORY));
577             log.info("Artifact-name = " + context.getAttribute(ARTIFACT_NAME));
578
579             if (null != templateIdList && modelInd < templateIdList.length()) {
580                 model = templateIdList.getString(modelInd);
581                 log.info("Model is ::: " + model + ", modelInd = " + modelInd);
582             }
583             if (null != vnfcTypeList && vnfcRefInd < vnfcTypeList.length()) {
584                 String vnfcType = vnfcTypeList.getString(vnfcRefInd);
585                 if (StringUtils.isNotBlank(vnfcType)) {
586                     context.setAttribute(VNFC_TYPE, vnfcType);
587                 }
588                 log.info("Setting vnfc type from vnfc-type-list :: " + vnfcType);
589             }
590             if (StringUtils.isNotBlank(model)) {
591                 dbservice.processSdcReferences(context,
592                         dbservice.isArtifactUpdateRequired(context, DB_SDC_REFERENCE, model),
593                         model);
594             } else {
595                 dbservice.processSdcReferences(context, dbservice.isArtifactUpdateRequired(context, DB_SDC_REFERENCE));
596             }
597
598             cleanArtifactInstanceData(context);
599             // Moving this into the for loop to account for mulitple artifact sets with pds
600             if (pdFile) {
601                 log.info("Sending information related to pdfile Artifact");
602                 tryUpdateContext(dbservice, context, pdFile, suffix, model);
603                 pdFile = false; // set to false after processing yang and Tosca
604             }
605         }
606     }
607
608     private void tryUpdateContext(DBService dbservice, SvcLogicContext context, boolean pdFile, String suffix,
609             String model)
610             throws SvcLogicException, SQLException, ConfigurationException, DBException {
611         if (pdFile) {
612             context.setAttribute(ARTIFACT_NAME, "Tosca".concat(suffix));
613             context.setAttribute(FILE_CATEGORY, TOSCA_MODEL);
614             dbservice.processSdcReferences(context,
615                     dbservice.isArtifactUpdateRequired(context, DB_SDC_REFERENCE, model), model);
616             context.setAttribute(ARTIFACT_NAME, "Yang".concat(suffix));
617             context.setAttribute(FILE_CATEGORY, PARAMETER_YANG);
618             dbservice.processSdcReferences(context,
619                     dbservice.isArtifactUpdateRequired(context, DB_SDC_REFERENCE, model), model);
620         }
621     }
622
623     public void processConfigTypeActions(JSONObject content, DBService dbservice, SvcLogicContext context)
624             throws ArtifactHandlerInternalException {
625
626         try {
627             if (contentsActionEquals(content, CONFIGURE_PARAM)
628                     || contentsActionEquals(content, CONFIG_MODIFY_PARAM)
629                     || contentsActionEquals(content, CONFIG_SCALE_OUT_PARAM)
630                     || contentsActionEquals(content, CONFIG_SCALE_IN_PARAM)
631                     || contentsActionEquals(content, GET_CONFIG)
632                     || contentsActionEquals(content, POST_EVACUATE)
633                     || contentsActionEquals(content, PRE_EVACUATE)
634                     || contentsActionEquals(content, POST_MIGRATE)
635                     || contentsActionEquals(content, PRE_MIGRATE)
636                     || contentsActionEquals(content, POST_REBUILD)
637                     || contentsActionEquals(content, PRE_REBUILD)
638                     || contentsActionEquals(content, STOP_TRAFFIC)
639                     ) {
640
641                 if (content.has(DOWNLOAD_DG_REFERENCE) && content.getString(DOWNLOAD_DG_REFERENCE).length() > 0) {
642
643                     setAttribute(context, content::getString, DOWNLOAD_DG_REFERENCE);
644                     dbservice.processDownloadDgReference(context,
645                             dbservice.isArtifactUpdateRequired(context, DB_DOWNLOAD_DG_REFERENCE));
646                 }
647                 if (StringUtils.isBlank(context.getAttribute(DOWNLOAD_DG_REFERENCE))) {
648                     context.setAttribute(DOWNLOAD_DG_REFERENCE, dbservice.getDownLoadDGReference(context));
649                 }
650                 dbservice.processConfigActionDg(context,
651                         dbservice.isArtifactUpdateRequired(context, DB_CONFIG_ACTION_DG));
652
653                 tryProcessInterfaceProtocol(content, dbservice, context);
654             }
655         } catch (Exception e) {
656             log.error("An error occurred when processing config type actions", e);
657             throw new ArtifactHandlerInternalException(e);
658         }
659     }
660
661     private void tryProcessInterfaceProtocol(JSONObject content, DBService dbservice, SvcLogicContext context)
662             throws SvcLogicException, SQLException, ConfigurationException, DBException {
663
664         if (contentsActionEquals(content, CONFIGURE_PARAM) || contentsActionEquals(content, CONFIG_SCALE_OUT_PARAM)
665                 || contentsActionEquals(content, CONFIG_SCALE_IN_PARAM)) {
666             boolean isUpdateRequired = dbservice.isArtifactUpdateRequired(context, DB_DEVICE_INTERFACE_PROTOCOL);
667             if (contentsActionEquals(content, CONFIGURE_PARAM) || (contentsActionEquals(content, CONFIG_SCALE_OUT_PARAM)
668                     || contentsActionEquals(content, CONFIG_SCALE_IN_PARAM)
669                         && !isUpdateRequired)) {
670
671                 dbservice.processDeviceInterfaceProtocol(context, isUpdateRequired);
672             }
673         }
674     }
675
676     private boolean contentsActionEquals(JSONObject content, String action) {
677         return content.getString(ACTION).equals(action);
678     }
679
680     public void processVmList(JSONObject content, SvcLogicContext context, DBService dbservice)
681             throws SvcLogicException {
682         JSONArray vmList = (JSONArray) content.get(VM);
683         dbservice.cleanUpVnfcReferencesForVnf(context);
684         for (int i = 0; i < vmList.length(); i++) {
685             JSONObject vmInstance = (JSONObject) vmList.get(i);
686             setAttribute(context, s -> String.valueOf(vmInstance.getInt(s)), VM_INSTANCE);
687             log.info("VALUE = " + context.getAttribute(VM_INSTANCE));
688             String templateId = vmInstance.optString(TEMPLATE_ID);
689             trySetContext(context, vmInstance, templateId);
690             if (vmInstance.get(VNFC) instanceof JSONArray) {
691                 JSONArray vnfcInstanceList = (JSONArray) vmInstance.get(VNFC);
692                 for (int k = 0; k < vnfcInstanceList.length(); k++) {
693                     JSONObject vnfcInstance = (JSONObject) vnfcInstanceList.get(k);
694
695                     setAttribute(context, s -> String.valueOf(vnfcInstance.getInt(s)), VNFC_INSTANCE);
696                     setAttribute(context, vnfcInstance::getString, VNFC_TYPE);
697                     setAttribute(context, vnfcInstance::getString, VNFC_FUNCTION_CODE);
698                     resolveContext(context, vnfcInstance);
699                     tryProcessVnfcReference(content, context, dbservice);
700                     cleanVnfcInstance(context);
701                 }
702                 context.setAttribute(VM_INSTANCE, null);
703                 context.setAttribute(TEMPLATE_ID, null);
704             }
705         }
706     }
707
708     private void trySetContext(SvcLogicContext context, JSONObject vmInstance, String templateId) {
709         if (StringUtils.isNotBlank(templateId)) {
710             setAttribute(context, vmInstance::optString, TEMPLATE_ID);
711         }
712     }
713
714     private void tryProcessVnfcReference(JSONObject content, SvcLogicContext context, DBService dbservice)
715             throws SvcLogicException {
716         if (content.getString(ACTION).equals(CONFIGURE_PARAM)
717                 || content.getString(ACTION).equals(CONFIG_SCALE_OUT_PARAM)
718                 || content.getString(ACTION).equals(CONFIG_SCALE_IN_PARAM)) {
719
720             dbservice.processVnfcReference(context, false);
721         }
722     }
723
724     private void resolveContext(SvcLogicContext context, JSONObject vnfcInstance) {
725         if (vnfcInstance.has(IPADDRESS_V4_OAM_VIP)) {
726             setAttribute(context, vnfcInstance::getString, IPADDRESS_V4_OAM_VIP);
727         }
728         if (vnfcInstance.has(GROUP_NOTATION_TYPE)) {
729             setAttribute(context, vnfcInstance::getString, GROUP_NOTATION_TYPE);
730         }
731         if (vnfcInstance.has(GROUP_NOTATION_VALUE)) {
732             setAttribute(context, vnfcInstance::getString, GROUP_NOTATION_VALUE);
733         }
734     }
735
736     private void cleanArtifactInstanceData(SvcLogicContext context) {
737         context.setAttribute(ARTIFACT_NAME, null);
738         context.setAttribute(FILE_CATEGORY, null);
739     }
740
741     private void cleanVnfcInstance(SvcLogicContext context) {
742
743         context.setAttribute(VNFC_INSTANCE, null);
744         context.setAttribute(VNFC_TYPE, null);
745         context.setAttribute(VNFC_FUNCTION_CODE, null);
746         context.setAttribute(IPADDRESS_V4_OAM_VIP, null);
747         context.setAttribute(GROUP_NOTATION_TYPE, null);
748         context.setAttribute(GROUP_NOTATION_VALUE, null);
749
750     }
751
752     private void processAndStoreCapabilitiesArtifact(DBService dbService, JSONObject documentInfo,
753             JSONObject capabilities, String capabilityArtifactName, String vnfType)
754             throws ArtifactHandlerInternalException {
755
756         log.info("Begin-->processAndStoreCapabilitiesArtifact");
757
758         try {
759             JSONObject newCapabilitiesObject = new JSONObject();
760             newCapabilitiesObject.put("capabilities", capabilities);
761             SvcLogicContext context = new SvcLogicContext();
762             context.setAttribute(ARTIFACT_NAME, capabilityArtifactName);
763             context.setAttribute(FILE_CATEGORY, CAPABILITY);
764             context.setAttribute(ACTION, null);
765             context.setAttribute(VNFC_TYPE, null);
766             context.setAttribute(ARTIFACT_TYPE, null);
767             context.setAttribute(VNF_TYPE, vnfType);
768             context.setAttribute(ARTIFACT_CONTENTS, newCapabilitiesObject.toString());
769             dbService.processSdcReferences(context, dbService.isArtifactUpdateRequired(context, DB_SDC_REFERENCE));
770             int intVersion = 0;
771             String internalVersion =
772                     dbService.getInternalVersionNumber(context, context.getAttribute(ARTIFACT_NAME), null);
773             log.info("Internal Version number received from Database: " + internalVersion);
774             if (internalVersion != null) {
775                 intVersion = Integer.parseInt(internalVersion) + 1;
776             }
777             setAttribute(context, documentInfo::getString, SERVICE_UUID);
778             setAttribute(context, documentInfo::getString, DISTRIBUTION_ID);
779             setAttribute(context, documentInfo::getString, SERVICE_NAME);
780             setAttribute(context, documentInfo::getString, SERVICE_DESCRIPTION);
781             setAttribute(context, documentInfo::getString, RESOURCE_UUID);
782             setAttribute(context, documentInfo::getString, RESOURCE_INSTANCE_NAME);
783             setAttribute(context, documentInfo::getString, RESOURCE_VERSION);
784             setAttribute(context, documentInfo::getString, RESOURCE_TYPE);
785             setAttribute(context, documentInfo::getString, ARTIFACT_UUID);
786             setAttribute(context, documentInfo::getString, ARTIFACT_VERSION);
787             setAttribute(context, documentInfo::getString, ARTIFACT_DESRIPTION);
788             dbService.saveArtifacts(context, intVersion);
789         } catch (Exception e) {
790             log.error("Error saving capabilities artifact to DB", e);
791             throw new ArtifactHandlerInternalException("Error saving capabilities artifact to DB", e);
792         } finally {
793             log.info("End-->processAndStoreCapabilitiesArtifact");
794         }
795     }
796
797     private void setAttribute(SvcLogicContext context, Function<String, String> value, String key) {
798         context.setAttribute(key, value.apply(key));
799     }
800
801     private void populateProtocolReference(DBService dbservice, JSONObject content)
802             throws ArtifactHandlerInternalException {
803         log.info("Begin-->populateProtocolReference");
804         try {
805             SvcLogicContext context = new SvcLogicContext();
806             JSONObject scope = content.getJSONObject("scope");
807             String vnfType = tryGetVnfType(scope);
808             String protocol = tryGetProtocol(content);
809             String action = tryGetAction(content);
810             String actionLevel = tryGetActionLevel(content);
811             String template = tryGetTemplate(content);
812
813             boolean isUpdateNeeded = dbservice.isProtocolReferenceUpdateRequired(context, vnfType, protocol, action,
814                     actionLevel, template);
815             if (isUpdateNeeded) {
816                 dbservice.updateProtocolReference(context, vnfType, protocol, action, actionLevel, template);
817             } else {
818                 dbservice.insertProtocolReference(context, vnfType, protocol, action, actionLevel, template);
819             }
820         } catch (Exception e) {
821             log.error("Error inserting record into protocolReference", e);
822             throw new ArtifactHandlerInternalException("Error inserting record into protocolReference", e);
823         } finally {
824             log.info("End-->populateProtocolReference");
825         }
826     }
827
828     private String tryGetVnfType(JSONObject scope) {
829         if (scope.has(VNF_TYPE) && !scope.isNull(VNF_TYPE)) {
830             return scope.getString(VNF_TYPE);
831         }
832         return null;
833     }
834
835     private String tryGetProtocol(JSONObject content) {
836         if (content.has(DEVICE_PROTOCOL)) {
837             return content.getString(DEVICE_PROTOCOL);
838         }
839         return null;
840     }
841
842     private String tryGetAction(JSONObject content) {
843         if (content.has(ACTION)) {
844             return content.getString(ACTION);
845         }
846         return null;
847     }
848
849     private String tryGetActionLevel(JSONObject content) {
850         if (content.has(ACTION_LEVEL)) {
851             return content.getString(ACTION_LEVEL);
852         }
853         return null;
854     }
855
856     private String tryGetTemplate(JSONObject content) {
857         if (content.has(TEMPLATE) && !content.isNull(TEMPLATE)) {
858             return content.getString(TEMPLATE);
859         }
860         return null;
861     }
862
863     protected ArtifactProcessorImpl getArtifactProcessorImpl() {
864         return new ArtifactProcessorImpl();
865     }
866 }