2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.sli.northbound.uebclient;
24 import java.io.BufferedReader;
25 import java.io.ByteArrayInputStream;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileReader;
30 import java.io.FileWriter;
31 import java.io.IOException;
32 import java.net.Authenticator;
33 import java.net.HttpURLConnection;
34 import java.net.PasswordAuthentication;
36 import java.nio.file.DirectoryStream;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.StandardCopyOption;
40 import java.sql.SQLException;
41 import java.text.SimpleDateFormat;
42 import java.util.Date;
43 import java.util.HashMap;
44 import java.util.LinkedList;
45 import java.util.List;
47 import java.util.Properties;
49 import javax.sql.rowset.CachedRowSet;
50 import javax.xml.parsers.DocumentBuilder;
51 import javax.xml.parsers.DocumentBuilderFactory;
52 import javax.xml.transform.Source;
53 import javax.xml.transform.Transformer;
54 import javax.xml.transform.TransformerFactory;
55 import javax.xml.transform.stream.StreamResult;
56 import javax.xml.transform.stream.StreamSource;
57 import javax.xml.xpath.XPath;
58 import javax.xml.xpath.XPathFactory;
60 import org.apache.commons.codec.binary.Base64;
61 import org.apache.commons.lang3.tuple.Pair;
62 import org.onap.ccsdk.sli.core.dblib.DBResourceManager;
63 import org.onap.ccsdk.sli.northbound.uebclient.SdncArtifactMap.SdncArtifactType;
64 import org.openecomp.sdc.api.IDistributionClient;
65 import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
66 import org.openecomp.sdc.api.consumer.INotificationCallback;
67 import org.openecomp.sdc.api.notification.IArtifactInfo;
68 import org.openecomp.sdc.api.notification.INotificationData;
69 import org.openecomp.sdc.api.notification.IResourceInstance;
70 import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
71 import org.openecomp.sdc.api.results.IDistributionClientResult;
72 import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper;
73 import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException;
74 import org.openecomp.sdc.tosca.parser.impl.SdcPropertyNames;
75 import org.openecomp.sdc.tosca.parser.impl.SdcToscaParserFactory;
76 import org.openecomp.sdc.toscaparser.api.Group;
77 import org.openecomp.sdc.toscaparser.api.Metadata;
78 import org.openecomp.sdc.toscaparser.api.NodeTemplate;
79 import org.openecomp.sdc.utils.ArtifactTypeEnum;
80 import org.openecomp.sdc.utils.DistributionActionResultEnum;
81 import org.openecomp.sdc.utils.DistributionStatusEnum;
82 import org.slf4j.Logger;
83 import org.slf4j.LoggerFactory;
84 import org.w3c.dom.Document;
85 import org.w3c.dom.Element;
87 public class SdncUebCallback implements INotificationCallback {
89 private static final Logger LOG = LoggerFactory
90 .getLogger(SdncUebCallback.class);
92 private static DBResourceManager jdbcDataSource = null;
93 private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
96 private class SdncAuthenticator extends Authenticator {
98 private final String user;
99 private final String passwd;
101 SdncAuthenticator(String user, String passwd) {
103 this.passwd = passwd;
106 protected PasswordAuthentication getPasswordAuthentication() {
107 return new PasswordAuthentication(user, passwd.toCharArray());
112 private class DeployableArtifact {
113 SdncArtifactType type;
114 IArtifactInfo artifactInfo;
118 String artifactVersion;
121 public String getArtifactName() {
127 public String getArtifactVersion() {
128 return artifactVersion;
132 public SdncArtifactType getType() {
138 public IArtifactInfo getArtifactInfo() {
143 public File getFile() {
150 public DeployableArtifact(SdncArtifactType type, String svcName, String resourceName, IArtifactInfo artifactInfo, File file) {
152 this.artifactInfo = artifactInfo;
153 this.svcName = svcName;
154 this.resourceName = resourceName;
155 this.artifactName = artifactInfo.getArtifactName();
156 this.artifactVersion = artifactInfo.getArtifactVersion();
161 public DeployableArtifact(SdncArtifactType type, String svcName, String resourceName, String artifactName, String artifactVersion, File file) {
163 this.artifactInfo = null;
164 this.svcName = svcName;
165 this.resourceName = resourceName;
166 this.artifactName = artifactName;
167 this.artifactVersion = artifactVersion;
173 public String getSvcName() {
179 public String getResourceName() {
185 private final IDistributionClient client;
186 private final SdncUebConfiguration config;
188 private LinkedList<DeployableArtifact> deployList[];
190 private static void setJdbcDataSource() throws IOException {
193 String propDir = System.getenv(SDNC_CONFIG_DIR);
194 if (propDir == null) {
195 propDir = "/opt/sdnc/data/properties";
197 propPath = propDir + "/dblib.properties";
198 File propFile = new File(propPath);
200 if (!propFile.exists()) {
202 throw new FileNotFoundException(
203 "Missing configuration properties file : "
207 Properties props = new Properties();
208 props.load(new FileInputStream(propFile));
210 jdbcDataSource = new DBResourceManager(props);
212 if(jdbcDataSource.isActive()){
213 LOG.warn( "DBLIB: JDBC DataSource has been initialized.");
215 LOG.warn( "DBLIB: JDBC DataSource did not initialize successfully.");
219 private static void loadArtifactMap() {
223 public SdncUebCallback(IDistributionClient client, SdncUebConfiguration config) {
224 this.client = client;
225 this.config = config;
230 public void activateCallback(INotificationData data) {
232 LOG.info("Received notification : ("+data.getDistributionID()+","+data.getServiceName()+","+data.getServiceVersion()+
233 ","+data.getServiceDescription() + ")");
235 String incomingDirName = config.getIncomingDir();
236 String archiveDirName = config.getArchiveDir();
238 File incomingDir = null;
239 File archiveDir = null;
241 // Process service level artifacts
242 List<IArtifactInfo> artifactList = data.getServiceArtifacts();
244 if (artifactList != null) {
246 incomingDir = new File(incomingDirName + "/" + escapeFilename(data.getServiceName()));
247 if (!incomingDir.exists()) {
248 incomingDir.mkdirs();
251 archiveDir = new File(archiveDirName + "/" + escapeFilename(data.getServiceName()));
252 if (!archiveDir.exists()) {
255 for (IArtifactInfo curArtifact : artifactList)
258 LOG.info("Received artifact " + curArtifact.getArtifactName());
260 handleArtifact(data, data.getServiceName(), null, null, curArtifact, incomingDir, archiveDir);
265 // Process resource level artifacts
266 for (IResourceInstance curResource : data.getResources()) {
268 LOG.info("Received resource : "+curResource.getResourceName());
269 artifactList = curResource.getArtifacts();
271 if (artifactList != null) {
273 incomingDir = new File(incomingDirName + "/" + escapeFilename(data.getServiceName()) + "/"
274 + escapeFilename(curResource.getResourceName()));
275 if (!incomingDir.exists()) {
276 incomingDir.mkdirs();
279 archiveDir = new File(archiveDirName + "/" + escapeFilename(data.getServiceName()) + "/"
280 + escapeFilename(curResource.getResourceName()));
281 if (!archiveDir.exists()) {
284 for (IArtifactInfo curArtifact : artifactList)
287 LOG.info("Received artifact " + curArtifact.getArtifactName());
289 handleArtifact(data, data.getServiceName(), curResource.getResourceName(), curResource.getResourceType(), curArtifact, incomingDir, archiveDir);
294 deployDownloadedFiles(incomingDir, archiveDir, data);
298 public void deployDownloadedFiles(File incomingDir, File archiveDir, INotificationData data) {
300 if (incomingDir == null) {
301 incomingDir = new File(config.getIncomingDir());
303 if (!incomingDir.exists()) {
304 incomingDir.mkdirs();
309 if (archiveDir == null) {
310 archiveDir = new File(config.getArchiveDir());
312 if (!archiveDir.exists()) {
317 String curFileName = "";
318 try (DirectoryStream<Path> stream = Files.newDirectoryStream(incomingDir.toPath())) {
319 for (Path file: stream) {
320 curFileName = file.toString();
321 handleSuccessfulDownload(null,null, null, null, file.toFile(), archiveDir);
323 } catch (Exception x) {
324 // IOException can never be thrown by the iteration.
325 // In this snippet, it can only be thrown by newDirectoryStream.
326 LOG.warn("Cannot process spool file {}", curFileName, x);
329 // Deploy scheduled deployments
330 int numPasses = config.getMaxPasses();
332 deployList = new LinkedList[numPasses];
334 for (int i = 0 ; i < numPasses ; i++) {
335 deployList[i] = new LinkedList<>();
337 for (int pass = 0 ; pass < config.getMaxPasses() ; pass++) {
339 if (deployList[pass] != null) {
340 while (! deployList[pass].isEmpty()) {
341 DeployableArtifact artifact = deployList[pass].pop();
343 DistributionStatusEnum deployResult = DistributionStatusEnum.DEPLOY_ERROR;
348 deployResult = deploySpoolFile(artifact);
349 } catch (Exception e) {
350 LOG.error("Caught exception trying to deploy file", e);
354 IArtifactInfo artifactInfo = artifact.getArtifactInfo();
356 if ((artifactInfo != null) && (data != null)) {
357 IDistributionClientResult deploymentStatus;
358 deploymentStatus = client.sendDeploymentStatus(buildStatusMessage(
359 client, data, artifactInfo,
368 private void handleArtifact(INotificationData data, String svcName, String resourceName, String resourceType,
369 IArtifactInfo artifact, File incomingDir, File archiveDir) {
372 IDistributionClientDownloadResult downloadResult = client.download(artifact);
374 if (downloadResult == null) {
376 handleFailedDownload(data, artifact);
380 byte[] payloadBytes = downloadResult.getArtifactPayload();
382 if (payloadBytes == null) {
383 handleFailedDownload(data, artifact);
387 String payload = new String(payloadBytes);
390 File spoolFile = new File(incomingDir.getAbsolutePath() + "/" + artifact.getArtifactName());
392 boolean writeSucceeded = false;
394 try (FileWriter spoolFileWriter = new FileWriter(spoolFile)) {
395 spoolFileWriter.write(payload);
396 spoolFileWriter.close();
397 writeSucceeded = true;
398 } catch (Exception e) {
399 LOG.error("Unable to save downloaded file to spool directory ("+ incomingDir.getAbsolutePath() +")", e);
403 if (writeSucceeded && (downloadResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS)) {
404 handleSuccessfulDownload(data, svcName, resourceName, artifact, spoolFile, archiveDir);
406 handleFailedDownload(data, artifact);
411 private void handleFailedDownload(INotificationData data,
412 IArtifactInfo relevantArtifact) {
413 // Send Download Status
414 IDistributionClientResult sendDownloadStatus = client
415 .sendDownloadStatus(buildStatusMessage(client, data,
416 relevantArtifact, DistributionStatusEnum.DOWNLOAD_ERROR));
419 private void handleSuccessfulDownload(INotificationData data, String svcName, String resourceName,
420 IArtifactInfo artifact, File spoolFile, File archiveDir) {
422 if ((data != null) && (artifact != null)) {
423 // Send Download Status
424 IDistributionClientResult sendDownloadStatus = client
425 .sendDownloadStatus(buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_OK));
428 // If an override file exists, read that instead of the file we just downloaded
429 ArtifactTypeEnum artifactEnum = ArtifactTypeEnum.YANG_XML;
431 boolean toscaYamlType = false;
432 if (artifact != null) {
433 String artifactTypeString = artifact.getArtifactType();
434 if (artifactTypeString.contains("TOSCA_TEMPLATE")) {
435 toscaYamlType = true;
438 if (spoolFile.toString().contains(".yml") || spoolFile.toString().contains(".csar")) {
439 toscaYamlType = true;
442 String overrideFileName = config.getOverrideFile();
443 if ((overrideFileName != null) && (overrideFileName.length() > 0)) {
444 File overrideFile = new File(overrideFileName);
446 if (overrideFile.exists()) {
447 artifactEnum = ArtifactTypeEnum.YANG_XML;
448 spoolFile = overrideFile;
454 processToscaYaml (data, svcName, resourceName, artifact, spoolFile, archiveDir);
457 Path source = spoolFile.toPath();
458 Path targetDir = archiveDir.toPath();
460 Files.move(source, targetDir.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);
461 } catch (IOException e) {
462 LOG.warn("Could not move "+spoolFile.getAbsolutePath()+" to "+archiveDir.getAbsolutePath(), e);
468 // Process spool file
469 Document spoolDoc = null;
470 File transformedFile = null;
472 // Apply XSLTs and get Doc object
474 if (!spoolFile.isDirectory()) {
475 transformedFile = applyXslts(spoolFile);
477 } catch (Exception e) {
478 LOG.error("Caught exception trying to parse XML file", e);
481 if (transformedFile != null) {
483 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
484 DocumentBuilder db = dbf.newDocumentBuilder();
486 spoolDoc = db.parse(transformedFile);
487 } catch (Exception e) {
488 LOG.error("Caught exception trying to parse transformed XML file {}",
489 transformedFile.getAbsolutePath(), e);
494 if (spoolDoc != null) {
496 SdncArtifactType artifactType = analyzeFileType(artifactEnum, spoolFile, spoolDoc);
498 if (artifactType != null) {
500 scheduleDeployment(artifactType, svcName, resourceName, artifact, spoolFile.getName(), transformedFile);
504 // SDNGC-2660 : Move file to archive directory even if it is an unrecognized type so that
505 // we do not keep trying and failing to process it.
507 Path source = spoolFile.toPath();
508 Path targetDir = archiveDir.toPath();
510 Files.move(source, targetDir.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);
511 } catch (IOException e) {
512 LOG.warn("Could not move "+spoolFile.getAbsolutePath()+" to "+archiveDir.getAbsolutePath(), e);
520 private void processToscaYaml(INotificationData data, String svcName, String resourceName,
521 IArtifactInfo artifact, File spoolFile, File archiveDir) {
523 // Use ASDC Dist Client 1.1.5 with TOSCA parsing APIs to extract relevant TOSCA model data
525 // TOSCA data extraction flow 1707:
526 // Use ASDC dist-client to get yaml string - not yet available
527 String model_yaml = null;
528 LOG.info("Process TOSCA YAML file: "+spoolFile.toString());
530 SdcToscaParserFactory factory = SdcToscaParserFactory.getInstance();
531 ISdcCsarHelper sdcCsarHelper = null;
533 sdcCsarHelper = factory.getSdcCsarHelper(spoolFile.getAbsolutePath());
534 } catch (SdcToscaParserException e) {
535 LOG.error("Could not create SDC TOSCA Parser ", e);
540 // Ingest Service Data - 1707
541 Metadata serviceMetadata = sdcCsarHelper.getServiceMetadata();
542 SdncServiceModel serviceModel = new SdncServiceModel(sdcCsarHelper, serviceMetadata);
543 serviceModel.setFilename(spoolFile.toString().substring(spoolFile
544 .toString().lastIndexOf('/')+1)); // will be csar file name
545 serviceModel.setServiceInstanceNamePrefix(SdncBaseModel.extractSubstitutionMappingTypeName(sdcCsarHelper).substring(SdncBaseModel.extractSubstitutionMappingTypeName(sdcCsarHelper).lastIndexOf(".")+1));
548 cleanUpExistingToscaServiceData(serviceModel.getServiceUUID());
549 LOG.info("Call insertToscaData for SERVICE_MODEL serviceUUID = " + serviceModel.getServiceUUID());
550 insertToscaData(serviceModel.getSql(model_yaml));
551 } catch (IOException e) {
552 LOG.error("Could not insert Tosca YAML data into the SERVICE_MODEL table ", e);
557 // Ingest Network (VL) Data - 1707
558 //List<NodeTemplate> vlNodeTemplatesList = sdcCsarHelper.getServiceNodeTemplatesByType("VL");
559 List<NodeTemplate> vlNodeTemplatesList = sdcCsarHelper.getServiceVlList();
561 for (NodeTemplate nodeTemplate : vlNodeTemplatesList) {
562 SdncNodeModel nodeModel = new SdncNodeModel (sdcCsarHelper, nodeTemplate);
563 nodeModel.setServiceUUID(serviceModel.getServiceUUID());
564 nodeModel.setEcompGeneratedNaming(SdncBaseModel.extractBooleanInputDefaultValue(sdcCsarHelper, SdcPropertyNames.PROPERTY_NAME_SERVICENAMING_DEFAULT_ECOMPGENERATEDNAMING));//service_naming#default#ecomp_generated_naming
567 cleanUpExistingToscaData("NETWORK_MODEL", "customization_uuid", nodeModel.getCustomizationUUID());
568 cleanUpExistingToscaData("VPN_BINDINGS", "network_customization_uuid", nodeModel.getCustomizationUUID());
569 LOG.info("Call insertToscaData for NETWORK_MODEL customizationUUID = " + nodeModel.getCustomizationUUID());
570 // using ASDC dist-client use method for get yaml string
571 insertToscaData(nodeModel.getSql(model_yaml));
572 insertToscaData(nodeModel.getVpnBindingsSql());
573 } catch (IOException e) {
574 LOG.error("Could not insert Tosca YAML data into the NETWORK_MODEL table ", e);
578 // Ingest Allotted Resource Data - 1707
579 List<NodeTemplate> arNodeTemplatesList = sdcCsarHelper.getAllottedResources();
581 for (NodeTemplate nodeTemplate : arNodeTemplatesList) {
582 SdncARModel nodeModel = new SdncARModel (sdcCsarHelper, nodeTemplate);
585 cleanUpExistingToscaData("ALLOTTED_RESOURCE_MODEL", "customization_uuid", nodeModel.getCustomizationUUID());
586 LOG.info("Call insertToscaData for ALLOTTED_RESOURCE_MODEL customizationUUID = " + nodeModel.getCustomizationUUID());
587 // using ASDC dist-client use method for get yaml string
588 insertToscaData(nodeModel.getSql("ALLOTTED_RESOURCE_MODEL", model_yaml));
589 } catch (IOException e) {
590 LOG.error("Could not insert Tosca YAML data into the NETWORK_MODEL table ", e);
594 // Ingest Network (VF) Data - 1707
595 //List<NodeTemplate> nodeTemplatesList = sdcCsarHelper.getServiceNodeTemplatesByType("VF");
596 List<NodeTemplate> vfNodeTemplatesList = sdcCsarHelper.getServiceVfList();
598 for (NodeTemplate nodeTemplate : vfNodeTemplatesList) {
599 SdncVFModel vfNodeModel = new SdncVFModel (sdcCsarHelper, nodeTemplate);
602 cleanUpExistingToscaData("VF_MODEL", "customization_uuid", vfNodeModel.getCustomizationUUID()) ;
603 LOG.info("Call insertToscaData for VF_MODEL customizationUUID = " + vfNodeModel.getCustomizationUUID());
604 insertToscaData(vfNodeModel.getSql("VF_MODEL", model_yaml));
605 } catch (IOException e) {
606 LOG.error("Could not insert Tosca YAML data into the VF_MODEL table ", e);
609 // For each VF, insert VF_MODULE_MODEL data
610 List<Group> vfModules = sdcCsarHelper.getVfModulesByVf(vfNodeModel.getCustomizationUUIDNoQuotes());
611 for (Group group : vfModules){
612 SdncVFModuleModel vfModuleModel = new SdncVFModuleModel(sdcCsarHelper, group);
615 cleanUpExistingToscaData("VF_MODULE_MODEL", "customization_uuid", vfModuleModel.getCustomizationUUID());
616 LOG.info("Call insertToscaData for VF_MODULE_MODEL customizationUUID = " + vfModuleModel.getCustomizationUUID());
617 insertToscaData(vfModuleModel.getSql("VF_MODULE_MODEL", model_yaml));
618 } catch (IOException e) {
619 LOG.error("Could not insert Tosca YAML data into the VF_MODULE_MODEL table ", e);
622 // For each VF Module, get the VFC list, insert VF_MODULE_TO_VFC_MAPPING data
623 // List<NodeTemplate> groupMembers = sdcCsarHelper.getMembersOfGroup(group); - old version
624 // For each vfcNode (group member) in the groupMembers list, extract vm_type and vm_count.
625 // Insert vf_module.customizationUUID, vfcNode.customizationUUID and vm_type and vm_count into VF_MODULE_TO_VFC_MAPPING
626 List<NodeTemplate> groupMembers = sdcCsarHelper.getMembersOfVfModule(nodeTemplate, group); // not yet available
627 for (NodeTemplate vfcNode : groupMembers){
628 SdncVFCModel vfcModel = new SdncVFCModel(sdcCsarHelper, vfcNode);
631 cleanUpExistingToscaData("VF_MODULE_TO_VFC_MAPPING", "vf_module_customization_uuid", vfModuleModel.getCustomizationUUID());
632 LOG.info("Call insertToscaData for VF_MODULE_TO_VFC_MAPPING customizationUUID = " + vfModuleModel.getCustomizationUUID());
633 insertToscaData("insert into VF_MODULE_TO_VFC_MAPPING (vf_module_customization_uuid, vfc_customization_uuid, vm_type, vm_count) values (" +
634 vfModuleModel.getCustomizationUUID() + ", " + vfcModel.getCustomizationUUID() + ", \"" + vfcModel.getVmType() + "\", \"" + vfcModel.getVmCount() + "\")");
635 } catch (IOException e) {
636 LOG.error("Could not insert Tosca YAML data into the VF_MODULE_TO_VFC_MAPPING table ", e);
643 // For each VF, insert VFC_MODEL data
644 List<NodeTemplate> vfcNodes = sdcCsarHelper.getVfcListByVf(vfNodeModel.getCustomizationUUIDNoQuotes());
645 for (NodeTemplate vfcNode : vfcNodes){
646 SdncVFCModel vfcModel = new SdncVFCModel(sdcCsarHelper, vfcNode);
649 cleanUpExistingToscaData("VFC_MODEL", "customization_uuid", vfcModel.getCustomizationUUID());
650 LOG.info("Call insertToscaData for VFC_MODEL customizationUUID = " + vfcModel.getCustomizationUUID());
651 insertToscaData(vfcModel.getSql("VFC_MODEL", model_yaml));
652 } catch (IOException e) {
653 LOG.error("Could not insert Tosca YAML data into the VFC_MODEL table ", e);
658 // For each VF, insert VF_TO_NETWORK_ROLE_MAPPING data
659 List<NodeTemplate> cpNodes = sdcCsarHelper.getCpListByVf(vfNodeModel.getCustomizationUUIDNoQuotes());
660 for (NodeTemplate cpNode : cpNodes){
662 // Insert into VF_TO_NETWORK_ROLE_MAPPING vf_customization_uuid and network_role
663 String cpNetworkRole = sdcCsarHelper.getNodeTemplatePropertyLeafValue(cpNode, "network_role_tag");
666 cleanUpExistingToscaData("VF_TO_NETWORK_ROLE_MAPPING", "vf_customization_uuid", vfNodeModel.getCustomizationUUID());
667 LOG.info("Call insertToscaData for VF_TO_NETWORK_ROLE_MAPPING vfCustomizationUUID = " + vfNodeModel.getCustomizationUUID());
668 insertToscaData("insert into VF_TO_NETWORK_ROLE_MAPPING (vf_customization_uuid, network_role) values (" +
669 vfNodeModel.getCustomizationUUID() + ", \"" + cpNetworkRole + "\")");
670 } catch (IOException e) {
671 LOG.error("Could not insert Tosca YAML data into the VF_TO_NETWORK_ROLE_MAPPING table ", e);
674 // Insert VFC_TO_NETWORK_ROLE_MAPPING data
675 Map<String, String> mappingParams = new HashMap<>();
676 //String cpNetworkRoleTag = "\"" + sdcCsarHelper.getNodeTemplatePropertyLeafValue(cpNode, SdcPropertyNames.PROPERTY_NAME_NETWORKROLETAG) + "\"";
677 // extract network_role, network_role_tag and virtual_binding from this cpNode
678 SdncBaseModel.addParameter("network_role", SdncBaseModel.extractValue(sdcCsarHelper, cpNode, "network_role"), mappingParams);
679 SdncBaseModel.addParameter("network_role_tag", SdncBaseModel.extractValue(sdcCsarHelper, cpNode, "network_role_tag"), mappingParams);
680 String virtualBinding = "\"" + SdncBaseModel.extractValue(sdcCsarHelper, cpNode, "requirements#virtualBinding") + "\"";
682 // get list of cpNodes and vfcNodes with matching virtualBinding
683 List<Pair<NodeTemplate, NodeTemplate>> matchList = sdcCsarHelper.getNodeTemplatePairsByReqName(sdcCsarHelper.getCpListByVf(vfNodeModel.getCustomizationUUIDNoQuotes()), sdcCsarHelper.getVfcListByVf(vfNodeModel.getCustomizationUUIDNoQuotes()), virtualBinding);
684 for (Pair<NodeTemplate, NodeTemplate> match : matchList) { // should be 1 match?
686 // extract values from the left "CP" Node
687 SdncBaseModel.addParameter("ipv4_use_dhcp", SdncBaseModel.extractBooleanValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV4SUBNETDEFAULTASSIGNMENTS_DHCPENABLED), mappingParams);
688 //SdncBaseModel.addParameter("ipv4_ip_version", SdncBaseModel.extractValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV4SUBNETDEFAULTASSIGNMENTS_IPVERSION), mappingParams);
689 SdncBaseModel.addParameter("ipv4_ip_version", "dummy_ipv4_vers", mappingParams);
690 SdncBaseModel.addParameter("ipv6_use_dhcp", SdncBaseModel.extractBooleanValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV6SUBNETDEFAULTASSIGNMENTS_DHCPENABLED), mappingParams);
691 //SdncBaseModel.addParameter("ipv6_ip_version", SdncBaseModel.extractValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV6SUBNETDEFAULTASSIGNMENTS_IPVERSION), mappingParams);
692 SdncBaseModel.addParameter("ipv6_ip_version", "dummy_ipv6_vers", mappingParams);
693 //String extcp_subnetpool_id = "\"" + SdncBaseModel.extractValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_SUBNETPOOLID) + "\""; // need path to subnetpoolid
695 // extract values from the right "VFC" Node
696 String vfcCustomizationUuid = "\"" + SdncBaseModel.extractValue(sdcCsarHelper, match.getRight().getMetadata(), "customization_uuid") + "\"";
697 SdncBaseModel.addParameter("vm_type", SdncBaseModel.extractValue(sdcCsarHelper, match.getRight(), SdcPropertyNames.PROPERTY_NAME_VMTYPE), mappingParams);
698 SdncBaseModel.addIntParameter("ipv4_count", SdncBaseModel.extractValue(sdcCsarHelper, match.getRight(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV4SUBNETDEFAULTASSIGNMENTS_MINSUBNETSCOUNT), mappingParams);
699 SdncBaseModel.addIntParameter("ipv6_count", SdncBaseModel.extractValue(sdcCsarHelper, match.getRight(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV6SUBNETDEFAULTASSIGNMENTS_MINSUBNETSCOUNT), mappingParams);
702 cleanUpExistingToscaData("VFC_TO_NETWORK_ROLE_MAPPING", "vfc_customization_uuid", vfcCustomizationUuid);
703 LOG.info("Call insertToscaData for VFC_TO_NETWORK_ROLE_MAPPING vfcCustomizationUUID = " + vfcCustomizationUuid);
704 insertToscaData(SdncBaseModel.getSql("VFC_TO_NETWORK_ROLE_MAPPING", "vfc_customization_uuid", vfcCustomizationUuid, "", mappingParams));
705 } catch (IOException e) {
706 LOG.error("Could not insert Tosca YAML data into the VFC_TO_NETWORK_ROLE_MAPPING table ", e);
715 // Close ASDC TOSCA Parser factory - we are done processing this distribution
718 if ((artifact != null) && (data != null)) {
719 LOG.info("Update to SDN-C succeeded");
720 IDistributionClientResult deploymentStatus;
721 deploymentStatus = client.sendDeploymentStatus(buildStatusMessage(
722 client, data, artifact,
723 DistributionStatusEnum.DEPLOY_OK));
728 private void cleanUpExistingToscaData(String tableName, String keyName, String keyValue) throws IOException
731 if (jdbcDataSource == null) {
736 CachedRowSet data = jdbcDataSource.getData("SELECT * from " + tableName + " where " + keyName + " = " + keyValue + ";", null, "");
741 LOG.info("cleanUpExistingToscaData: " + keyValue);
742 jdbcDataSource.writeData("DELETE from " + tableName + " where " + keyName + " = " + keyValue + ";", null, null);
745 } catch (SQLException e) {
746 LOG.error("Could not clean up existing " + tableName + " for " + keyValue, e);
752 private void cleanUpExistingToscaServiceData(String serviceUUID) throws IOException
755 if (jdbcDataSource == null) {
760 CachedRowSet data = jdbcDataSource.getData("SELECT * from SERVICE_MODEL where service_uuid = " + serviceUUID + ";", null, "");
765 LOG.info("cleanUpExistingToscaData: " + serviceUUID);
766 jdbcDataSource.writeData("DELETE from NETWORK_MODEL where service_uuid = " + serviceUUID + ";", null, null);
767 jdbcDataSource.writeData("DELETE from SERVICE_MODEL where service_uuid = " + serviceUUID + ";", null, null);
770 } catch (SQLException e) {
771 LOG.error("Could not clean up existing NETWORK_MODEL and SERVICE_MODEL for service_UUID " + serviceUUID, e);
777 private void insertToscaData(String toscaDataString) throws IOException
779 LOG.debug("insertToscaData: " + toscaDataString);
781 if (jdbcDataSource == null) {
786 jdbcDataSource.writeData(toscaDataString, null, null);
788 } catch (SQLException e) {
789 LOG.error("Could not insert Tosca YAML data into the database ", e);
795 private SdncArtifactType analyzeFileType(ArtifactTypeEnum artifactType, File spoolFile, Document spoolDoc) {
797 if (artifactType != ArtifactTypeEnum.YANG_XML) {
798 LOG.error("Unexpected artifact type - expecting YANG_XML, got "+artifactType);
807 Element root = spoolDoc.getDocumentElement();
809 String rootName = root.getTagName();
811 if (rootName.contains(":")) {
812 String[] rootNameElems = rootName.split(":");
813 rootName = rootNameElems[rootNameElems.length - 1];
816 if (rootName != null) {
817 SdncArtifactType mapEntry = config.getMapping(rootName);
820 if (mapEntry == null) {
822 LOG.error("Unexpected file contents - root tag is "+rootName);
826 LOG.error("Cannot get root tag from file");
830 } catch (Exception e) {
831 LOG.error("Could not parse YANG_XML file "+spoolFile.getName(), e);
836 private void scheduleDeployment(SdncArtifactType type, String svcName, String resourceName, IArtifactInfo artifactInfo, String spoolFileName, File spoolFile) {
838 if (type.getPass() < deployList.length) {
840 if (artifactInfo != null) {
841 LOG.debug("Scheduling "+artifactInfo.getArtifactName()+" version "+artifactInfo.getArtifactVersion()+" for deployment");
843 deployList[type.getPass()].add(new DeployableArtifact(type, svcName, resourceName, artifactInfo, spoolFile));
845 SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS");//dd/MM/yyyy
846 Date now = new Date();
847 String artifactVersion = sdfDate.format(now);
848 LOG.debug("Scheduling "+spoolFileName+" version "+artifactVersion+" for deployment");
849 deployList[type.getPass()].add(new DeployableArtifact(type, svcName, resourceName, spoolFileName,
850 artifactVersion, spoolFile));
853 LOG.info("Pass for type "+type.getTag()+" is "+type.getPass()+" which is not <= "+deployList.length);
858 private DistributionStatusEnum deploySpoolFile(DeployableArtifact artifact) {
860 DistributionStatusEnum deployResult = DistributionStatusEnum.DEPLOY_OK;
862 StringBuffer msgBuffer = new StringBuffer();
865 String namespace = config.getAsdcApiNamespace();
866 if ((namespace == null) || (namespace.length() == 0)) {
867 namespace="com:att:sdnctl:asdcapi";
870 msgBuffer.append("<input xmlns='");
871 msgBuffer.append(namespace);
872 msgBuffer.append("'>\n");
874 String svcName = artifact.getSvcName();
875 String resourceName = artifact.getResourceName();
876 String artifactName = artifact.getArtifactName();
878 if (svcName != null) {
879 if (resourceName != null) {
880 artifactName = svcName + "/" + resourceName + "/" + artifactName;
882 artifactName = svcName + "/" + artifactName;
886 msgBuffer.append("<artifact-name>"+artifactName+"</artifact-name>\n");
887 msgBuffer.append("<artifact-version>"+artifact.getArtifactVersion()+"</artifact-version>\n");
890 try (BufferedReader rdr = new BufferedReader(new FileReader(artifact.getFile()))){
891 String curLine = rdr.readLine();
892 while (curLine != null) {
894 if (!curLine.startsWith("<?")) {
895 msgBuffer.append(curLine+"\n");
897 curLine = rdr.readLine();
899 } catch (Exception e) {
900 LOG.error("Could not process spool file "+artifact.getFile().getName(), e);
901 return(DistributionStatusEnum.DEPLOY_ERROR);
904 msgBuffer.append("</input>\n");
907 byte[] msgBytes = msgBuffer.toString().getBytes();
909 Document results = postRestXml(artifact.getType().getRpcUrl(config.getAsdcApiBaseUrl()), msgBytes);
911 if (results == null) {
913 deployResult = DistributionStatusEnum.DEPLOY_ERROR;
916 XPathFactory xpf = XPathFactory.newInstance();
917 XPath xp = xpf.newXPath();
919 String asdcApiResponseCode = "500";
923 asdcApiResponseCode = xp.evaluate("//asdc-api-response-code[position()=1]/text()", results.getDocumentElement());
924 } catch (Exception e) {
925 LOG.error("Caught exception retrying to evaluate xpath", e);
928 if (asdcApiResponseCode.contains("200")) {
929 LOG.info("Update to SDN-C succeeded");
930 deployResult = DistributionStatusEnum.DEPLOY_OK;
932 LOG.info("Update to SDN-C failed (response code "+asdcApiResponseCode+")");
934 if (asdcApiResponseCode.contains("409")) {
935 deployResult = DistributionStatusEnum.ALREADY_DEPLOYED;
938 deployResult = DistributionStatusEnum.DEPLOY_ERROR;
945 return(deployResult);
952 public static IDistributionStatusMessage buildStatusMessage(
953 final IDistributionClient client, final INotificationData data,
954 final IArtifactInfo relevantArtifact,
955 final DistributionStatusEnum status) {
956 IDistributionStatusMessage statusMessage = new IDistributionStatusMessage() {
959 public long getTimestamp() {
960 return System.currentTimeMillis();
964 public DistributionStatusEnum getStatus() {
969 public String getDistributionID() {
970 return data.getDistributionID();
974 public String getConsumerID() {
975 return client.getConfiguration().getConsumerID();
979 public String getArtifactURL() {
980 return relevantArtifact.getArtifactURL();
983 return statusMessage;
987 private HttpURLConnection getRestXmlConnection(String urlString, String method) throws IOException
989 URL sdncUrl = new URL(urlString);
990 Authenticator.setDefault(new SdncAuthenticator(config.getSdncUser(), config.getSdncPasswd()));
992 HttpURLConnection conn = (HttpURLConnection) sdncUrl.openConnection();
994 String authStr = config.getSdncUser()+":"+config.getSdncPasswd();
995 String encodedAuthStr = new String(Base64.encodeBase64(authStr.getBytes()));
997 conn.addRequestProperty("Authentication", "Basic "+encodedAuthStr);
999 conn.setRequestMethod(method);
1000 conn.setRequestProperty("Content-Type", "application/xml");
1001 conn.setRequestProperty("Accept", "application/xml");
1003 conn.setDoInput(true);
1004 conn.setDoOutput(true);
1005 conn.setUseCaches(false);
1011 private Document postRestXml(String urlString, byte[] msgBytes) {
1012 Document response = null;
1015 SdncOdlConnection odlConn = SdncOdlConnection.newInstance(urlString, config.getSdncUser(), config.getSdncPasswd());
1017 String sdncResp = odlConn.send("POST", "application/xml", new String(msgBytes));
1019 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1020 DocumentBuilder db = dbf.newDocumentBuilder();
1023 response = db.parse(new ByteArrayInputStream(sdncResp.getBytes()));
1024 } catch (Exception e) {
1025 LOG.error("Caught exception posting to ODL tier", e);
1032 private File applyXslts(File srcFile) {
1036 File inFile = srcFile;
1037 File outFile = null;
1039 String xsltPathList = config.getXsltPathList();
1041 if ((xsltPathList == null) || (xsltPathList.length() == 0)) {
1045 String[] xsltPaths = xsltPathList.split(",");
1047 for (String xsltPath : xsltPaths) {
1050 outFile = File.createTempFile("tmp", "xml");
1051 TransformerFactory factory = TransformerFactory.newInstance();
1052 Source xslt = new StreamSource(new File(xsltPath));
1053 Transformer transformer = factory.newTransformer(xslt);
1054 Source text = new StreamSource(inFile);
1057 transformer.transform(text, new StreamResult(outFile));
1061 } catch (Exception e) {
1062 LOG.error("Caught exception trying to apply XSLT template "+xsltPath, e);
1069 // After transformations, parse transformed XML
1075 private String escapeFilename(String str) {
1076 StringBuffer retval = new StringBuffer();
1078 for (int i = 0 ; i < str.length() ; i++) {
1079 char curchar = str.charAt(i);
1080 if (Character.isJavaIdentifierPart(curchar)) {
1081 retval.append(curchar);
1085 return(retval.toString());