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.openecomp.sdnc.uebclient;
24 import java.io.BufferedReader;
25 import java.io.ByteArrayInputStream;
26 import java.io.DataOutputStream;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.FileReader;
31 import java.io.FileWriter;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.InputStreamReader;
35 import java.net.Authenticator;
36 import java.net.HttpURLConnection;
37 import java.net.PasswordAuthentication;
39 import java.nio.file.DirectoryStream;
40 import java.nio.file.Files;
41 import java.nio.file.Path;
42 import java.nio.file.StandardCopyOption;
43 import java.sql.ResultSet;
44 import java.sql.SQLException;
45 import java.text.SimpleDateFormat;
46 import java.util.Date;
47 import java.util.HashMap;
48 import java.util.LinkedList;
49 import java.util.List;
51 import java.util.Properties;
53 import javax.net.ssl.HostnameVerifier;
54 import javax.net.ssl.HttpsURLConnection;
55 import javax.net.ssl.SSLSession;
56 import javax.sql.rowset.CachedRowSet;
57 import javax.xml.parsers.DocumentBuilder;
58 import javax.xml.parsers.DocumentBuilderFactory;
59 import javax.xml.transform.Source;
60 import javax.xml.transform.Transformer;
61 import javax.xml.transform.TransformerFactory;
62 import javax.xml.transform.stream.StreamResult;
63 import javax.xml.transform.stream.StreamSource;
64 import javax.xml.xpath.XPath;
65 import javax.xml.xpath.XPathFactory;
67 import org.apache.commons.codec.binary.Base64;
68 import org.apache.commons.lang3.tuple.Pair;
69 import org.openecomp.sdc.api.IDistributionClient;
70 import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
71 import org.openecomp.sdc.api.consumer.INotificationCallback;
72 import org.openecomp.sdc.api.notification.IArtifactInfo;
73 import org.openecomp.sdc.api.notification.INotificationData;
74 import org.openecomp.sdc.api.notification.IResourceInstance;
75 import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
76 import org.openecomp.sdc.api.results.IDistributionClientResult;
77 import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper;
78 import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException;
79 import org.openecomp.sdc.tosca.parser.impl.SdcPropertyNames;
80 import org.openecomp.sdc.tosca.parser.impl.SdcToscaParserFactory;
81 import org.openecomp.sdc.toscaparser.api.Group;
82 import org.openecomp.sdc.toscaparser.api.Metadata;
83 import org.openecomp.sdc.toscaparser.api.NodeTemplate;
84 import org.openecomp.sdc.utils.ArtifactTypeEnum;
85 import org.openecomp.sdc.utils.DistributionActionResultEnum;
86 import org.openecomp.sdc.utils.DistributionStatusEnum;
87 import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
88 import org.openecomp.sdnc.uebclient.SdncArtifactMap.SdncArtifactType;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
91 import org.w3c.dom.Document;
92 import org.w3c.dom.Element;
93 import org.yaml.snakeyaml.Yaml;
94 import org.yaml.snakeyaml.constructor.Constructor;
96 public class SdncUebCallback implements INotificationCallback {
98 private static final Logger LOG = LoggerFactory
99 .getLogger(SdncUebCallback.class);
101 private static DBResourceManager jdbcDataSource = null;
102 private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
105 private class SdncAuthenticator extends Authenticator {
107 private final String user;
108 private final String passwd;
110 SdncAuthenticator(String user, String passwd) {
112 this.passwd = passwd;
115 protected PasswordAuthentication getPasswordAuthentication() {
116 return new PasswordAuthentication(user, passwd.toCharArray());
121 private class DeployableArtifact {
122 SdncArtifactType type;
123 IArtifactInfo artifactInfo;
127 String artifactVersion;
130 public String getArtifactName() {
136 public String getArtifactVersion() {
137 return artifactVersion;
141 public SdncArtifactType getType() {
147 public IArtifactInfo getArtifactInfo() {
152 public File getFile() {
159 public DeployableArtifact(SdncArtifactType type, String svcName, String resourceName, IArtifactInfo artifactInfo, File file) {
161 this.artifactInfo = artifactInfo;
162 this.svcName = svcName;
163 this.resourceName = resourceName;
164 this.artifactName = artifactInfo.getArtifactName();
165 this.artifactVersion = artifactInfo.getArtifactVersion();
170 public DeployableArtifact(SdncArtifactType type, String svcName, String resourceName, String artifactName, String artifactVersion, File file) {
172 this.artifactInfo = null;
173 this.svcName = svcName;
174 this.resourceName = resourceName;
175 this.artifactName = artifactName;
176 this.artifactVersion = artifactVersion;
182 public String getSvcName() {
188 public String getResourceName() {
194 private final IDistributionClient client;
195 private final SdncUebConfiguration config;
197 private LinkedList<DeployableArtifact> deployList[];
199 private static void setJdbcDataSource() throws IOException {
201 String propPath = null;
202 String propDir = System.getenv(SDNC_CONFIG_DIR);
203 if (propDir == null) {
205 propDir = "/opt/sdnc/data/properties";
207 propPath = propDir + "/dblib.properties";
208 File propFile = new File(propPath);
210 if (!propFile.exists()) {
212 throw new FileNotFoundException(
213 "Missing configuration properties file : "
217 Properties props = new Properties();
218 props.load(new FileInputStream(propFile));
221 jdbcDataSource = DBResourceManager.create(props);
222 } catch(Throwable exc) {
226 if(((DBResourceManager)jdbcDataSource).isActive()){
227 LOG.warn( "DBLIB: JDBC DataSource has been initialized.");
229 LOG.warn( "DBLIB: JDBC DataSource did not initialize successfully.");
233 private static void loadArtifactMap() {
237 public SdncUebCallback(IDistributionClient client, SdncUebConfiguration config) {
238 this.client = client;
239 this.config = config;
244 public void activateCallback(INotificationData data) {
246 LOG.info("Received notification : ("+data.getDistributionID()+","+data.getServiceName()+","+data.getServiceVersion()+
247 ","+data.getServiceDescription() + ")");
249 String incomingDirName = config.getIncomingDir();
250 String archiveDirName = config.getArchiveDir();
252 File incomingDir = null;
253 File archiveDir = null;
255 if (!incomingDir.exists()) {
256 incomingDir.mkdirs();
260 if (!archiveDir.exists()) {
264 // Process service level artifacts
265 List<IArtifactInfo> artifactList = data.getServiceArtifacts();
267 if (artifactList != null) {
269 incomingDir = new File(incomingDirName + "/" + escapeFilename(data.getServiceName()));
270 if (!incomingDir.exists()) {
271 incomingDir.mkdirs();
274 archiveDir = new File(archiveDirName + "/" + escapeFilename(data.getServiceName()));
275 if (!archiveDir.exists()) {
278 for (IArtifactInfo curArtifact : artifactList)
281 LOG.info("Received artifact " + curArtifact.getArtifactName());
283 handleArtifact(data, data.getServiceName(), null, null, curArtifact, incomingDir, archiveDir);
288 // Process resource level artifacts
289 for (IResourceInstance curResource : data.getResources()) {
291 LOG.info("Received resource : "+curResource.getResourceName());
292 artifactList = curResource.getArtifacts();
294 if (artifactList != null) {
296 incomingDir = new File(incomingDirName + "/" + escapeFilename(data.getServiceName()) + "/" + escapeFilename(curResource.getResourceName()));
297 if (!incomingDir.exists()) {
298 incomingDir.mkdirs();
301 archiveDir = new File(archiveDirName + "/" + escapeFilename(data.getServiceName()) + "/" + escapeFilename(curResource.getResourceName()));
302 if (!archiveDir.exists()) {
305 for (IArtifactInfo curArtifact : artifactList)
308 LOG.info("Received artifact " + curArtifact.getArtifactName());
310 handleArtifact(data, data.getServiceName(), curResource.getResourceName(), curResource.getResourceType(), curArtifact, incomingDir, archiveDir);
315 deployDownloadedFiles(incomingDir, archiveDir, data);
321 public void deployDownloadedFiles(File incomingDir, File archiveDir, INotificationData data) {
323 if (incomingDir == null) {
324 incomingDir = new File(config.getIncomingDir());
326 if (!incomingDir.exists()) {
327 incomingDir.mkdirs();
332 if (archiveDir == null) {
333 archiveDir = new File(config.getArchiveDir());
335 if (!archiveDir.exists()) {
340 String curFileName = "";
341 try (DirectoryStream<Path> stream = Files.newDirectoryStream(incomingDir.toPath())) {
342 for (Path file: stream) {
343 curFileName = file.toString();
344 handleSuccessfulDownload(null,null, null, null, file.toFile(), archiveDir);
346 } catch (Exception x) {
347 // IOException can never be thrown by the iteration.
348 // In this snippet, it can only be thrown by newDirectoryStream.
349 LOG.warn("Cannot process spool file "+ curFileName, x);
352 // Deploy scheduled deployments
353 int numPasses = config.getMaxPasses();
355 deployList = new LinkedList[numPasses];
357 for (int i = 0 ; i < numPasses ; i++) {
358 deployList[i] = new LinkedList<DeployableArtifact>();
360 for (int pass = 0 ; pass < config.getMaxPasses() ; pass++) {
362 if (deployList[pass] != null) {
363 while (! deployList[pass].isEmpty()) {
364 DeployableArtifact artifact = deployList[pass].pop();
366 DistributionStatusEnum deployResult = DistributionStatusEnum.DEPLOY_ERROR;
371 deployResult = deploySpoolFile(artifact);
372 } catch (Exception e) {
373 LOG.error("Caught exception trying to deploy file", e);
377 IArtifactInfo artifactInfo = artifact.getArtifactInfo();
379 if ((artifactInfo != null) && (data != null)) {
380 IDistributionClientResult deploymentStatus;
381 deploymentStatus = client.sendDeploymentStatus(buildStatusMessage(
382 client, data, artifactInfo,
391 private void handleArtifact(INotificationData data, String svcName, String resourceName, String resourceType, IArtifactInfo artifact, File incomingDir, File archiveDir) {
394 IDistributionClientDownloadResult downloadResult = client
397 if (downloadResult == null) {
399 handleFailedDownload(data, artifact);
403 byte[] payloadBytes = downloadResult.getArtifactPayload();
405 if (payloadBytes == null) {
406 handleFailedDownload(data, artifact);
410 String payload = new String(payloadBytes);
413 File spoolFile = new File(incomingDir.getAbsolutePath() + "/" + artifact.getArtifactName());
415 boolean writeSucceeded = false;
418 FileWriter spoolFileWriter = new FileWriter(spoolFile);
419 spoolFileWriter.write(payload);
420 spoolFileWriter.close();
421 writeSucceeded = true;
422 } catch (Exception e) {
423 LOG.error("Unable to save downloaded file to spool directory ("+ incomingDir.getAbsolutePath() +")", e);
427 if (writeSucceeded && (downloadResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS)) {
428 handleSuccessfulDownload(data, svcName, resourceName, artifact, spoolFile, archiveDir);
432 handleFailedDownload(data, artifact);
437 private void handleFailedDownload(INotificationData data,
438 IArtifactInfo relevantArtifact) {
439 // Send Download Status
440 IDistributionClientResult sendDownloadStatus = client
441 .sendDownloadStatus(buildStatusMessage(client, data,
442 relevantArtifact, DistributionStatusEnum.DOWNLOAD_ERROR));
445 private void handleSuccessfulDownload(INotificationData data, String svcName, String resourceName,
446 IArtifactInfo artifact, File spoolFile, File archiveDir) {
448 if ((data != null) && (artifact != null)) {
449 // Send Download Status
450 IDistributionClientResult sendDownloadStatus = client
451 .sendDownloadStatus(buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_OK));
454 // If an override file exists, read that instead of the file we just downloaded
455 ArtifactTypeEnum artifactEnum = ArtifactTypeEnum.YANG_XML;
457 boolean toscaYamlType = false;
458 if (artifact != null) {
459 String artifactTypeString = artifact.getArtifactType();
460 if (artifactTypeString.contains("TOSCA_TEMPLATE")) {
461 toscaYamlType = true;
464 if (spoolFile.toString().contains(".yml") || spoolFile.toString().contains(".csar")) {
465 toscaYamlType = true;
468 String overrideFileName = config.getOverrideFile();
469 if ((overrideFileName != null) && (overrideFileName.length() > 0)) {
470 File overrideFile = new File(overrideFileName);
472 if (overrideFile.exists()) {
473 artifactEnum = ArtifactTypeEnum.YANG_XML;
474 spoolFile = overrideFile;
479 if (toscaYamlType == true) {
480 processToscaYaml (data, svcName, resourceName, artifact, spoolFile, archiveDir);
483 Path source = spoolFile.toPath();
484 Path targetDir = archiveDir.toPath();
486 Files.move(source, targetDir.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);
487 } catch (IOException e) {
488 LOG.warn("Could not move "+spoolFile.getAbsolutePath()+" to "+archiveDir.getAbsolutePath(), e);
494 // Process spool file
495 Document spoolDoc = null;
496 File transformedFile = null;
498 // Apply XSLTs and get Doc object
500 if (!spoolFile.isDirectory()) {
501 transformedFile = applyXslts(spoolFile);
503 } catch (Exception e) {
504 LOG.error("Caught exception trying to parse XML file", e);
507 if (transformedFile != null) {
512 DocumentBuilderFactory dbf = DocumentBuilderFactory
514 DocumentBuilder db = dbf.newDocumentBuilder();
516 spoolDoc = db.parse(transformedFile);
517 } catch (Exception e) {
519 "Caught exception trying to parse transformed XML file "
520 + transformedFile.getAbsolutePath(), e);
523 } catch (Exception e) {
524 LOG.error("Caught exception trying to deploy file", e);
529 if (spoolDoc != null) {
531 SdncArtifactType artifactType = analyzeFileType(artifactEnum,
532 spoolFile, spoolDoc);
534 if (artifactType != null) {
536 scheduleDeployment(artifactType, svcName, resourceName, artifact, spoolFile.getName(), transformedFile);
540 // SDNGC-2660 : Move file to archive directory even if it is an unrecognized type so that
541 // we do not keep trying and failing to process it.
543 Path source = spoolFile.toPath();
544 Path targetDir = archiveDir.toPath();
546 Files.move(source, targetDir.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);
547 } catch (IOException e) {
548 LOG.warn("Could not move "+spoolFile.getAbsolutePath()+" to "+archiveDir.getAbsolutePath(), e);
556 private void processToscaYaml(INotificationData data, String svcName, String resourceName,
557 IArtifactInfo artifact, File spoolFile, File archiveDir) {
559 // Use ASDC Dist Client 1.1.5 with TOSCA parsing APIs to extract relevant TOSCA model data
561 // TOSCA data extraction flow 1707:
562 // Use ASDC dist-client to get yaml string - not yet available
563 String model_yaml = null;
564 LOG.info("Process TOSCA YAML file: "+spoolFile.toString());
566 SdcToscaParserFactory factory = SdcToscaParserFactory.getInstance();
567 ISdcCsarHelper sdcCsarHelper = null;
569 sdcCsarHelper = factory.getSdcCsarHelper(spoolFile.getAbsolutePath());
570 } catch (SdcToscaParserException e) {
571 LOG.error("Could not create SDC TOSCA Parser ", e);
576 // Ingest Service Data - 1707
577 Metadata serviceMetadata = sdcCsarHelper.getServiceMetadata();
578 SdncServiceModel serviceModel = new SdncServiceModel(sdcCsarHelper, serviceMetadata);
579 serviceModel.setFilename(spoolFile.toString().substring(spoolFile.toString().lastIndexOf("/")+1)); // will be csar file name
580 serviceModel.setServiceInstanceNamePrefix(SdncBaseModel.extractSubstitutionMappingTypeName(sdcCsarHelper).substring(SdncBaseModel.extractSubstitutionMappingTypeName(sdcCsarHelper).lastIndexOf(".")+1));
583 cleanUpExistingToscaServiceData(serviceModel.getServiceUUID());
584 LOG.info("Call insertToscaData for SERVICE_MODEL serviceUUID = " + serviceModel.getServiceUUID());
585 insertToscaData(serviceModel.getSql(model_yaml));
586 } catch (IOException e) {
587 LOG.error("Could not insert Tosca YAML data into the SERVICE_MODEL table ", e);
592 // Ingest Network (VL) Data - 1707
593 //List<NodeTemplate> vlNodeTemplatesList = sdcCsarHelper.getServiceNodeTemplatesByType("VL");
594 List<NodeTemplate> vlNodeTemplatesList = sdcCsarHelper.getServiceVlList();
596 for (NodeTemplate nodeTemplate : vlNodeTemplatesList) {
597 SdncNodeModel nodeModel = new SdncNodeModel (sdcCsarHelper, nodeTemplate);
598 nodeModel.setServiceUUID(serviceModel.getServiceUUID());
599 nodeModel.setEcompGeneratedNaming(SdncBaseModel.extractBooleanInputDefaultValue(sdcCsarHelper, SdcPropertyNames.PROPERTY_NAME_SERVICENAMING_DEFAULT_ECOMPGENERATEDNAMING));//service_naming#default#ecomp_generated_naming
602 cleanUpExistingToscaData("NETWORK_MODEL", "customization_uuid", nodeModel.getCustomizationUUID());
603 cleanUpExistingToscaData("VPN_BINDINGS", "network_customization_uuid", nodeModel.getCustomizationUUID());
604 LOG.info("Call insertToscaData for NETWORK_MODEL customizationUUID = " + nodeModel.getCustomizationUUID());
605 // using ASDC dist-client use method for get yaml string
606 insertToscaData(nodeModel.getSql(model_yaml));
607 insertToscaData(nodeModel.getVpnBindingsSql());
608 } catch (IOException e) {
609 LOG.error("Could not insert Tosca YAML data into the NETWORK_MODEL table ", e);
613 // Ingest Allotted Resource Data - 1707
614 List<NodeTemplate> arNodeTemplatesList = sdcCsarHelper.getAllottedResources();
616 for (NodeTemplate nodeTemplate : arNodeTemplatesList) {
617 SdncARModel nodeModel = new SdncARModel (sdcCsarHelper, nodeTemplate);
620 cleanUpExistingToscaData("ALLOTTED_RESOURCE_MODEL", "customization_uuid", nodeModel.getCustomizationUUID());
621 LOG.info("Call insertToscaData for ALLOTTED_RESOURCE_MODEL customizationUUID = " + nodeModel.getCustomizationUUID());
622 // using ASDC dist-client use method for get yaml string
623 insertToscaData(nodeModel.getSql("ALLOTTED_RESOURCE_MODEL", model_yaml));
624 } catch (IOException e) {
625 LOG.error("Could not insert Tosca YAML data into the NETWORK_MODEL table ", e);
629 // Ingest Network (VF) Data - 1707
630 //List<NodeTemplate> nodeTemplatesList = sdcCsarHelper.getServiceNodeTemplatesByType("VF");
631 List<NodeTemplate> vfNodeTemplatesList = sdcCsarHelper.getServiceVfList();
633 for (NodeTemplate nodeTemplate : vfNodeTemplatesList) {
634 SdncVFModel vfNodeModel = new SdncVFModel (sdcCsarHelper, nodeTemplate);
637 cleanUpExistingToscaData("VF_MODEL", "customization_uuid", vfNodeModel.getCustomizationUUID()) ;
638 LOG.info("Call insertToscaData for VF_MODEL customizationUUID = " + vfNodeModel.getCustomizationUUID());
639 insertToscaData(vfNodeModel.getSql("VF_MODEL", model_yaml));
640 } catch (IOException e) {
641 LOG.error("Could not insert Tosca YAML data into the VF_MODEL table ", e);
644 // For each VF, insert VF_MODULE_MODEL data
645 List<Group> vfModules = sdcCsarHelper.getVfModulesByVf(vfNodeModel.getCustomizationUUIDNoQuotes());
646 for (Group group : vfModules){
647 SdncVFModuleModel vfModuleModel = new SdncVFModuleModel(sdcCsarHelper, group);
650 cleanUpExistingToscaData("VF_MODULE_MODEL", "customization_uuid", vfModuleModel.getCustomizationUUID());
651 LOG.info("Call insertToscaData for VF_MODULE_MODEL customizationUUID = " + vfModuleModel.getCustomizationUUID());
652 insertToscaData(vfModuleModel.getSql("VF_MODULE_MODEL", model_yaml));
653 } catch (IOException e) {
654 LOG.error("Could not insert Tosca YAML data into the VF_MODULE_MODEL table ", e);
657 // For each VF Module, get the VFC list, insert VF_MODULE_TO_VFC_MAPPING data
658 // List<NodeTemplate> groupMembers = sdcCsarHelper.getMembersOfGroup(group); - old version
659 // For each vfcNode (group member) in the groupMembers list, extract vm_type and vm_count.
660 // Insert vf_module.customizationUUID, vfcNode.customizationUUID and vm_type and vm_count into VF_MODULE_TO_VFC_MAPPING
661 List<NodeTemplate> groupMembers = sdcCsarHelper.getMembersOfVfModule(nodeTemplate, group); // not yet available
662 for (NodeTemplate vfcNode : groupMembers){
663 SdncVFCModel vfcModel = new SdncVFCModel(sdcCsarHelper, vfcNode);
666 cleanUpExistingToscaData("VF_MODULE_TO_VFC_MAPPING", "vf_module_customization_uuid", vfModuleModel.getCustomizationUUID());
667 LOG.info("Call insertToscaData for VF_MODULE_TO_VFC_MAPPING customizationUUID = " + vfModuleModel.getCustomizationUUID());
668 insertToscaData("insert into VF_MODULE_TO_VFC_MAPPING (vf_module_customization_uuid, vfc_customization_uuid, vm_type, vm_count) values (" +
669 vfModuleModel.getCustomizationUUID() + ", " + vfcModel.getCustomizationUUID() + ", \"" + vfcModel.getVmType() + "\", \"" + vfcModel.getVmCount() + "\")");
670 } catch (IOException e) {
671 LOG.error("Could not insert Tosca YAML data into the VF_MODULE_TO_VFC_MAPPING table ", e);
678 // For each VF, insert VFC_MODEL data
679 List<NodeTemplate> vfcNodes = sdcCsarHelper.getVfcListByVf(vfNodeModel.getCustomizationUUIDNoQuotes());
680 for (NodeTemplate vfcNode : vfcNodes){
681 SdncVFCModel vfcModel = new SdncVFCModel(sdcCsarHelper, vfcNode);
684 cleanUpExistingToscaData("VFC_MODEL", "customization_uuid", vfcModel.getCustomizationUUID());
685 LOG.info("Call insertToscaData for VFC_MODEL customizationUUID = " + vfcModel.getCustomizationUUID());
686 insertToscaData(vfcModel.getSql("VFC_MODEL", model_yaml));
687 } catch (IOException e) {
688 LOG.error("Could not insert Tosca YAML data into the VFC_MODEL table ", e);
693 // For each VF, insert VF_TO_NETWORK_ROLE_MAPPING data
694 List<NodeTemplate> cpNodes = sdcCsarHelper.getCpListByVf(vfNodeModel.getCustomizationUUIDNoQuotes());
695 for (NodeTemplate cpNode : cpNodes){
697 // Insert into VF_TO_NETWORK_ROLE_MAPPING vf_customization_uuid and network_role
698 String cpNetworkRole = sdcCsarHelper.getNodeTemplatePropertyLeafValue(cpNode, "network_role_tag");
701 cleanUpExistingToscaData("VF_TO_NETWORK_ROLE_MAPPING", "vf_customization_uuid", vfNodeModel.getCustomizationUUID());
702 LOG.info("Call insertToscaData for VF_TO_NETWORK_ROLE_MAPPING vfCustomizationUUID = " + vfNodeModel.getCustomizationUUID());
703 insertToscaData("insert into VF_TO_NETWORK_ROLE_MAPPING (vf_customization_uuid, network_role) values (" +
704 vfNodeModel.getCustomizationUUID() + ", \"" + cpNetworkRole + "\")");
705 } catch (IOException e) {
706 LOG.error("Could not insert Tosca YAML data into the VF_TO_NETWORK_ROLE_MAPPING table ", e);
709 // Insert VFC_TO_NETWORK_ROLE_MAPPING data
710 Map<String, String> mappingParams = new HashMap<String, String>();
711 //String cpNetworkRoleTag = "\"" + sdcCsarHelper.getNodeTemplatePropertyLeafValue(cpNode, SdcPropertyNames.PROPERTY_NAME_NETWORKROLETAG) + "\"";
712 // extract network_role, network_role_tag and virtual_binding from this cpNode
713 SdncBaseModel.addParameter("network_role", SdncBaseModel.extractValue(sdcCsarHelper, cpNode, "network_role"), mappingParams);
714 SdncBaseModel.addParameter("network_role_tag", SdncBaseModel.extractValue(sdcCsarHelper, cpNode, "network_role_tag"), mappingParams);
715 String virtualBinding = "\"" + SdncBaseModel.extractValue(sdcCsarHelper, cpNode, "requirements#virtualBinding") + "\"";
717 // get list of cpNodes and vfcNodes with matching virtualBinding
718 List<Pair<NodeTemplate, NodeTemplate>> matchList = sdcCsarHelper.getNodeTemplatePairsByReqName(sdcCsarHelper.getCpListByVf(vfNodeModel.getCustomizationUUIDNoQuotes()), sdcCsarHelper.getVfcListByVf(vfNodeModel.getCustomizationUUIDNoQuotes()), virtualBinding);
719 for (Pair<NodeTemplate, NodeTemplate> match : matchList) { // should be 1 match?
721 // extract values from the left "CP" Node
722 SdncBaseModel.addParameter("ipv4_use_dhcp", SdncBaseModel.extractBooleanValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV4SUBNETDEFAULTASSIGNMENTS_DHCPENABLED), mappingParams);
723 //SdncBaseModel.addParameter("ipv4_ip_version", SdncBaseModel.extractValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV4SUBNETDEFAULTASSIGNMENTS_IPVERSION), mappingParams);
724 SdncBaseModel.addParameter("ipv4_ip_version", "dummy_ipv4_vers", mappingParams);
725 SdncBaseModel.addParameter("ipv6_use_dhcp", SdncBaseModel.extractBooleanValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV6SUBNETDEFAULTASSIGNMENTS_DHCPENABLED), mappingParams);
726 //SdncBaseModel.addParameter("ipv6_ip_version", SdncBaseModel.extractValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV6SUBNETDEFAULTASSIGNMENTS_IPVERSION), mappingParams);
727 SdncBaseModel.addParameter("ipv6_ip_version", "dummy_ipv6_vers", mappingParams);
728 //String extcp_subnetpool_id = "\"" + SdncBaseModel.extractValue(sdcCsarHelper, match.getLeft(), SdcPropertyNames.PROPERTY_NAME_SUBNETPOOLID) + "\""; // need path to subnetpoolid
730 // extract values from the right "VFC" Node
731 String vfcCustomizationUuid = "\"" + SdncBaseModel.extractValue(sdcCsarHelper, match.getRight().getMetadata(), "customization_uuid") + "\"";
732 SdncBaseModel.addParameter("vm_type", SdncBaseModel.extractValue(sdcCsarHelper, match.getRight(), SdcPropertyNames.PROPERTY_NAME_VMTYPE), mappingParams);
733 SdncBaseModel.addIntParameter("ipv4_count", SdncBaseModel.extractValue(sdcCsarHelper, match.getRight(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV4SUBNETDEFAULTASSIGNMENTS_MINSUBNETSCOUNT), mappingParams);
734 SdncBaseModel.addIntParameter("ipv6_count", SdncBaseModel.extractValue(sdcCsarHelper, match.getRight(), SdcPropertyNames.PROPERTY_NAME_NETWORKASSIGNMENTS_IPV6SUBNETDEFAULTASSIGNMENTS_MINSUBNETSCOUNT), mappingParams);
737 cleanUpExistingToscaData("VFC_TO_NETWORK_ROLE_MAPPING", "vfc_customization_uuid", vfcCustomizationUuid);
738 LOG.info("Call insertToscaData for VFC_TO_NETWORK_ROLE_MAPPING vfcCustomizationUUID = " + vfcCustomizationUuid);
739 insertToscaData(SdncBaseModel.getSql("VFC_TO_NETWORK_ROLE_MAPPING", "vfc_customization_uuid", vfcCustomizationUuid, "", mappingParams));
740 } catch (IOException e) {
741 LOG.error("Could not insert Tosca YAML data into the VFC_TO_NETWORK_ROLE_MAPPING table ", e);
750 // Close ASDC TOSCA Parser factory - we are done processing this distribution
753 if ((artifact != null) && (data != null)) {
754 LOG.info("Update to SDN-C succeeded");
755 IDistributionClientResult deploymentStatus;
756 deploymentStatus = client.sendDeploymentStatus(buildStatusMessage(
757 client, data, artifact,
758 DistributionStatusEnum.DEPLOY_OK));
763 private void cleanUpExistingToscaData(String tableName, String keyName, String keyValue) throws IOException
766 if (jdbcDataSource == null) {
771 CachedRowSet data = jdbcDataSource.getData("SELECT * from " + tableName + " where " + keyName + " = " + keyValue + ";", null, "");
776 LOG.info("cleanUpExistingToscaData: " + keyValue);
777 jdbcDataSource.writeData("DELETE from " + tableName + " where " + keyName + " = " + keyValue + ";", null, null);
780 } catch (SQLException e) {
781 LOG.error("Could not clean up existing " + tableName + " for " + keyValue, e);
787 private void cleanUpExistingToscaServiceData(String serviceUUID) throws IOException
790 if (jdbcDataSource == null) {
795 CachedRowSet data = jdbcDataSource.getData("SELECT * from SERVICE_MODEL where service_uuid = " + serviceUUID + ";", null, "");
800 LOG.info("cleanUpExistingToscaData: " + serviceUUID);
801 jdbcDataSource.writeData("DELETE from NETWORK_MODEL where service_uuid = " + serviceUUID + ";", null, null);
802 jdbcDataSource.writeData("DELETE from SERVICE_MODEL where service_uuid = " + serviceUUID + ";", null, null);
805 } catch (SQLException e) {
806 LOG.error("Could not clean up existing NETWORK_MODEL and SERVICE_MODEL for service_UUID " + serviceUUID, e);
812 private void insertToscaData(String toscaDataString) throws IOException
814 LOG.debug("insertToscaData: " + toscaDataString);
816 if (jdbcDataSource == null) {
821 jdbcDataSource.writeData(toscaDataString, null, null);
823 } catch (SQLException e) {
824 LOG.error("Could not insert Tosca YAML data into the database ", e);
830 private SdncArtifactType analyzeFileType(ArtifactTypeEnum artifactType, File spoolFile, Document spoolDoc) {
832 if (artifactType != ArtifactTypeEnum.YANG_XML) {
833 LOG.error("Unexpected artifact type - expecting YANG_XML, got "+artifactType);
842 Element root = spoolDoc.getDocumentElement();
844 String rootName = root.getTagName();
846 if (rootName.contains(":")) {
847 String[] rootNameElems = rootName.split(":");
848 rootName = rootNameElems[rootNameElems.length - 1];
851 if (rootName != null) {
852 SdncArtifactType mapEntry = config.getMapping(rootName);
855 if (mapEntry == null) {
857 LOG.error("Unexpected file contents - root tag is "+rootName);
861 LOG.error("Cannot get root tag from file");
865 } catch (Exception e) {
866 LOG.error("Could not parse YANG_XML file "+spoolFile.getName(), e);
871 private void scheduleDeployment(SdncArtifactType type, String svcName, String resourceName, IArtifactInfo artifactInfo, String spoolFileName, File spoolFile) {
873 if (type.getPass() < deployList.length) {
875 if (artifactInfo != null) {
876 LOG.debug("Scheduling "+artifactInfo.getArtifactName()+" version "+artifactInfo.getArtifactVersion()+" for deployment");
878 deployList[type.getPass()].add(new DeployableArtifact(type, svcName, resourceName, artifactInfo, spoolFile));
880 SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS");//dd/MM/yyyy
881 Date now = new Date();
882 String artifactVersion = sdfDate.format(now);
883 LOG.debug("Scheduling "+spoolFileName+" version "+artifactVersion+" for deployment");
884 String artifactName = spoolFileName;
885 if (artifactInfo != null) {
886 artifactName = artifactInfo.getArtifactName();
888 deployList[type.getPass()].add(new DeployableArtifact(type, svcName, resourceName, artifactName, artifactVersion, spoolFile));
891 LOG.info("Pass for type "+type.getTag()+" is "+type.getPass()+" which is not <= "+deployList.length);
896 private DistributionStatusEnum deploySpoolFile(DeployableArtifact artifact) {
898 DistributionStatusEnum deployResult = DistributionStatusEnum.DEPLOY_OK;
900 StringBuffer msgBuffer = new StringBuffer();
903 String namespace = config.getAsdcApiNamespace();
904 if ((namespace == null) || (namespace.length() == 0)) {
905 namespace="com:att:sdnctl:asdcapi";
908 msgBuffer.append("<input xmlns='");
909 msgBuffer.append(namespace);
910 msgBuffer.append("'>\n");
912 String svcName = artifact.getSvcName();
913 String resourceName = artifact.getResourceName();
914 String artifactName = artifact.getArtifactName();
916 if (svcName != null) {
917 if (resourceName != null) {
918 artifactName = svcName + "/" + resourceName + "/" + artifactName;
920 artifactName = svcName + "/" + artifactName;
924 msgBuffer.append("<artifact-name>"+artifactName+"</artifact-name>\n");
925 msgBuffer.append("<artifact-version>"+artifact.getArtifactVersion()+"</artifact-version>\n");
929 BufferedReader rdr = new BufferedReader(new FileReader(artifact.getFile()));
931 String curLine = rdr.readLine();
933 while (curLine != null) {
935 if (!curLine.startsWith("<?")) {
936 msgBuffer.append(curLine+"\n");
938 curLine = rdr.readLine();
942 } catch (Exception e) {
943 LOG.error("Could not process spool file "+artifact.getFile().getName(), e);
944 return(DistributionStatusEnum.DEPLOY_ERROR);
947 msgBuffer.append("</input>\n");
950 byte[] msgBytes = msgBuffer.toString().getBytes();
952 Document results = postRestXml(artifact.getType().getRpcUrl(config.getAsdcApiBaseUrl()), msgBytes);
954 if (results == null) {
956 deployResult = DistributionStatusEnum.DEPLOY_ERROR;
959 XPathFactory xpf = XPathFactory.newInstance();
960 XPath xp = xpf.newXPath();
962 String asdcApiResponseCode = "500";
966 asdcApiResponseCode = xp.evaluate("//asdc-api-response-code[position()=1]/text()", results.getDocumentElement());
967 } catch (Exception e) {
968 LOG.error("Caught exception retrying to evaluate xpath", e);
971 if (asdcApiResponseCode.contains("200")) {
972 LOG.info("Update to SDN-C succeeded");
973 deployResult = DistributionStatusEnum.DEPLOY_OK;
975 LOG.info("Update to SDN-C failed (response code "+asdcApiResponseCode+")");
977 if (asdcApiResponseCode.contains("409")) {
978 deployResult = DistributionStatusEnum.ALREADY_DEPLOYED;
981 deployResult = DistributionStatusEnum.DEPLOY_ERROR;
988 return(deployResult);
995 public static IDistributionStatusMessage buildStatusMessage(
996 final IDistributionClient client, final INotificationData data,
997 final IArtifactInfo relevantArtifact,
998 final DistributionStatusEnum status) {
999 IDistributionStatusMessage statusMessage = new IDistributionStatusMessage() {
1002 public long getTimestamp() {
1003 long currentTimeMillis = System.currentTimeMillis();
1004 return currentTimeMillis;
1008 public DistributionStatusEnum getStatus() {
1013 public String getDistributionID() {
1014 return data.getDistributionID();
1018 public String getConsumerID() {
1019 return client.getConfiguration().getConsumerID();
1023 public String getArtifactURL() {
1024 return relevantArtifact.getArtifactURL();
1027 return statusMessage;
1031 private HttpURLConnection getRestXmlConnection(String urlString, String method) throws IOException
1033 URL sdncUrl = new URL(urlString);
1034 Authenticator.setDefault(new SdncAuthenticator(config.getSdncUser(), config.getSdncPasswd()));
1036 HttpURLConnection conn = (HttpURLConnection) sdncUrl.openConnection();
1038 String authStr = config.getSdncUser()+":"+config.getSdncPasswd();
1039 String encodedAuthStr = new String(Base64.encodeBase64(authStr.getBytes()));
1041 conn.addRequestProperty("Authentication", "Basic "+encodedAuthStr);
1043 conn.setRequestMethod(method);
1044 conn.setRequestProperty("Content-Type", "application/xml");
1045 conn.setRequestProperty("Accept", "application/xml");
1047 conn.setDoInput(true);
1048 conn.setDoOutput(true);
1049 conn.setUseCaches(false);
1055 private Document postRestXml(String urlString, byte[] msgBytes) {
1056 Document response = null;
1059 SdncOdlConnection odlConn = SdncOdlConnection.newInstance(urlString, config.getSdncUser(), config.getSdncPasswd());
1061 String sdncResp = odlConn.send("POST", "application/xml", new String(msgBytes));
1063 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1064 DocumentBuilder db = dbf.newDocumentBuilder();
1067 response = db.parse(new ByteArrayInputStream(sdncResp.getBytes()));
1068 } catch (Exception e) {
1069 LOG.error("Caught exception posting to ODL tier", e);
1076 private File applyXslts(File srcFile) {
1078 Document doc = null;
1081 File inFile = srcFile;
1082 File outFile = null;
1084 String xsltPathList = config.getXsltPathList();
1086 if ((xsltPathList == null) || (xsltPathList.length() == 0)) {
1090 String[] xsltPaths = xsltPathList.split(",");
1092 for (String xsltPath : xsltPaths) {
1095 outFile = File.createTempFile("tmp", "xml");
1096 TransformerFactory factory = TransformerFactory.newInstance();
1097 Source xslt = new StreamSource(new File(xsltPath));
1098 Transformer transformer = factory.newTransformer(xslt);
1099 Source text = new StreamSource(inFile);
1102 transformer.transform(text, new StreamResult(outFile));
1106 } catch (Exception e) {
1107 LOG.error("Caught exception trying to apply XSLT template "+xsltPath, e);
1114 // After transformations, parse transformed XML
1120 private String escapeFilename(String str) {
1121 StringBuffer retval = new StringBuffer();
1123 for (int i = 0 ; i < str.length() ; i++) {
1124 char curchar = str.charAt(i);
1125 if (Character.isJavaIdentifierPart(curchar)) {
1126 retval.append(curchar);
1130 return(retval.toString());