Fix vFW Distrobution 88/85088/1
authorSmokowski, Steve (ss835w) <ss835w@us.att.com>
Thu, 11 Apr 2019 16:09:04 +0000 (12:09 -0400)
committerSmokowski, Steve (ss835w) <ss835w@us.att.com>
Thu, 11 Apr 2019 16:11:04 +0000 (12:11 -0400)
Missing check to not reprocess service

Issue-ID: SO-1674

Change-Id: I152c61fb726eb8979eb30c8dcb5f4eed05fc4b8b
Signed-off-by: Smokowski, Steve (ss835w) <ss835w@us.att.com>
12 files changed:
asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCController.java
asdc-controller/src/main/java/org/onap/so/asdc/client/test/emulators/ArtifactInfoImpl.java
asdc-controller/src/main/java/org/onap/so/asdc/client/test/emulators/NotificationDataImpl.java
asdc-controller/src/main/java/org/onap/so/asdc/client/test/emulators/ResourceInfoImpl.java
asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java
asdc-controller/src/test/java/org/onap/so/asdc/client/test/rest/ASDCRestInterfaceTest.java
asdc-controller/src/test/resources/resource-examples/vFW/base_vfw.env [new file with mode: 0644]
asdc-controller/src/test/resources/resource-examples/vFW/base_vfw.yaml [new file with mode: 0644]
asdc-controller/src/test/resources/resource-examples/vFW/notification.json [new file with mode: 0644]
asdc-controller/src/test/resources/resource-examples/vFW/service-Vfw.csar [new file with mode: 0644]
asdc-controller/src/test/resources/resource-examples/vFW/vfw1f52feb055020_modules.json [new file with mode: 0644]
asdc-controller/src/test/resources/schema.sql

index 57e9c17..f2e875f 100644 (file)
@@ -655,6 +655,7 @@ public class ASDCController {
         // For each artifact, create a structure describing the VFModule in a ordered flat level
         ResourceStructure resourceStructure = null;
         String msoConfigPath = getMsoConfigPath();
+        boolean hasVFResource = false;
         ToscaResourceStructure toscaResourceStructure = new ToscaResourceStructure(msoConfigPath);
         boolean deploySuccessful = true;
         String errorMessage = null;
@@ -697,7 +698,7 @@ public class ASDCController {
                                 + resourceStructure.getResourceInstance().getResourceUUID());
 
                         if ("VF".equals(resourceType) && !"Allotted Resource".equalsIgnoreCase(category)) {
-
+                            hasVFResource = true;
                             for (IArtifactInfo artifact : resource.getArtifacts()) {
                                 IDistributionClientDownloadResult resultArtifact =
                                         this.downloadTheArtifact(artifact, iNotif.getDistributionID());
@@ -730,16 +731,19 @@ public class ASDCController {
                     logger.error("Exception occurred", e);
                 }
 
-                // Deploy VF resource and artifacts
-                logger.debug("Preparing to deploy Service: {}", iNotif.getServiceUUID());
-                try {
-                    this.deployResourceStructure(resourceStructure, toscaResourceStructure);
-                } catch (ArtifactInstallerException e) {
-                    deploySuccessful = false;
-                    errorMessage = e.getMessage();
-                    logger.error("Exception occurred", e);
-                }
+                if (!hasVFResource) {
+
+                    logger.debug("No resources found for Service: " + iNotif.getServiceUUID());
 
+                    logger.debug("Preparing to deploy Service: {}", iNotif.getServiceUUID());
+                    try {
+                        this.deployResourceStructure(resourceStructure, toscaResourceStructure);
+                    } catch (ArtifactInstallerException e) {
+                        deploySuccessful = false;
+                        errorMessage = e.getMessage();
+                        logger.error("Exception occurred", e);
+                    }
+                }
                 this.sendCsarDeployNotification(iNotif, resourceStructure, toscaResourceStructure, deploySuccessful,
                         errorMessage);
             }
index b3618a8..f4cfb13 100644 (file)
@@ -23,9 +23,11 @@ package org.onap.so.asdc.client.test.emulators;
 import java.util.ArrayList;
 import java.util.List;
 import org.onap.sdc.api.notification.IArtifactInfo;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class ArtifactInfoImpl implements IArtifactInfo {
 
     private String artifactName;
index f8d7bb0..c61306f 100644 (file)
@@ -29,12 +29,14 @@ import org.onap.sdc.api.notification.INotificationData;
 import org.onap.sdc.api.notification.IResourceInstance;
 import org.springframework.stereotype.Component;
 import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
 
 @Component
 @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE,
         setterVisibility = Visibility.NONE)
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class NotificationDataImpl implements INotificationData {
 
     @JsonProperty("distributionID")
index 9159761..62d11ff 100644 (file)
@@ -27,7 +27,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.onap.sdc.api.notification.IArtifactInfo;
 import org.onap.sdc.api.notification.IResourceInstance;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class ResourceInfoImpl implements IResourceInstance {
     public ResourceInfoImpl() {}
 
index e61aafa..f3a4958 100644 (file)
@@ -261,7 +261,7 @@ public class ToscaResourceInstaller {
         try {
             Service existingService =
                     serviceRepo.findOneByModelUUID(vfResourceStructure.getNotification().getServiceUUID());
-            if (existingService != null && serviceDeployed == false)
+            if (existingService != null && !serviceDeployed)
                 status = true;
             if (status) {
                 logger.info(vfResourceStructure.getResourceInstance().getResourceInstanceName(),
@@ -387,12 +387,11 @@ public class ToscaResourceInstaller {
         List<ASDCElementInfo> artifactListForLogging = new ArrayList<>();
         try {
             createToscaCsar(toscaResourceStruct);
-            Service service = createService(toscaResourceStruct, vfResourceStruct);
+            createService(toscaResourceStruct, vfResourceStruct);
+            Service service = toscaResourceStruct.getCatalogService();
             List<NodeTemplate> vfNodeTemplatesList = toscaResourceStruct.getSdcCsarHelper().getServiceVfList();
 
-
             for (NodeTemplate nodeTemplate : vfNodeTemplatesList) {
-
                 Metadata metadata = nodeTemplate.getMetaData();
                 String serviceType = toscaResourceStruct.getCatalogService().getServiceType();
                 String vfCustomizationCategory = toscaResourceStruct.getSdcCsarHelper()
@@ -402,7 +401,6 @@ public class ToscaResourceInstaller {
             }
 
             processResourceSequence(toscaResourceStruct, service);
-            processVFResources(toscaResourceStruct, service, vfResourceStructure);
             List<NodeTemplate> allottedResourceList = toscaResourceStruct.getSdcCsarHelper().getAllottedResources();
             processAllottedResources(toscaResourceStruct, service, allottedResourceList);
             processNetworks(toscaResourceStruct, service);
@@ -410,7 +408,7 @@ public class ToscaResourceInstaller {
             processNetworkCollections(toscaResourceStruct, service);
             // Process Service Proxy & Configuration
             processServiceProxyAndConfiguration(toscaResourceStruct, service);
-
+            logger.info("Saving Service: {} ", service.getModelName());
             serviceRepo.save(service);
 
             WatchdogComponentDistributionStatus status = new WatchdogComponentDistributionStatus(
@@ -763,48 +761,6 @@ public class ToscaResourceInstaller {
     }
 
 
-    protected void processVFResources(ToscaResourceStructure toscaResourceStruct, Service service,
-            VfResourceStructure vfResourceStructure) throws Exception {
-        logger.debug("processVFResources");
-
-        List<NodeTemplate> vfNodeTemplatesList = toscaResourceStruct.getSdcCsarHelper().getServiceVfList();
-        // String servicecategory = toscaResourceStruct.getCatalogService().getCategory();
-        // String serviceType = toscaResourceStruct.getCatalogService().getServiceType();
-
-        for (NodeTemplate nodeTemplate : vfNodeTemplatesList) {
-            Metadata metadata = nodeTemplate.getMetaData();
-            String vfCustomizationCategory = metadata.getValue(SdcPropertyNames.PROPERTY_NAME_CATEGORY);
-            logger.debug("VF Category is : " + vfCustomizationCategory);
-
-            // Do not treat Allotted Resources as VNF resources
-            if (ALLOTTED_RESOURCE.equalsIgnoreCase(vfCustomizationCategory)) {
-                continue;
-            }
-
-            String vfCustomizationUUID = metadata.getValue(SdcPropertyNames.PROPERTY_NAME_CUSTOMIZATIONUUID);
-            logger.debug("VFCustomizationUUID=" + vfCustomizationUUID);
-
-            IResourceInstance vfNotificationResource = vfResourceStructure.getResourceInstance();
-
-            // Make sure the VF ResourceCustomizationUUID from the notification and tosca
-            // customizations match before comparing their VF Modules UUID's
-            logger.debug("Checking if Notification VF ResourceCustomizationUUID: "
-                    + vfNotificationResource.getResourceCustomizationUUID() + " matches Tosca VF Customization UUID: "
-                    + vfCustomizationUUID);
-
-            if (vfCustomizationUUID.equals(vfNotificationResource.getResourceCustomizationUUID())) {
-                logger.debug("vfCustomizationUUID: " + vfCustomizationUUID
-                        + " matches vfNotificationResource CustomizationUUID");
-
-                processVfModules(toscaResourceStruct, vfResourceStructure, service, nodeTemplate, metadata,
-                        vfCustomizationCategory);
-            } else {
-                logger.debug("Notification VF ResourceCustomizationUUID: "
-                        + vfNotificationResource.getResourceCustomizationUUID() + " doesn't match "
-                        + "Tosca VF Customization UUID: " + vfCustomizationUUID);
-            }
-        }
-    }
 
     /**
      * This is used to process the PNF specific resource, including resource and resource_customization.
index 815f419..2e5ad13 100644 (file)
@@ -42,6 +42,7 @@ import org.onap.so.asdc.client.test.emulators.DistributionClientEmulator;
 import org.onap.so.asdc.client.test.emulators.NotificationDataImpl;
 import org.onap.so.db.catalog.beans.AllottedResource;
 import org.onap.so.db.catalog.beans.AllottedResourceCustomization;
+import org.onap.so.db.catalog.beans.Service;
 import org.onap.so.db.catalog.data.repository.AllottedResourceRepository;
 import org.onap.so.db.catalog.data.repository.NetworkResourceRepository;
 import org.onap.so.db.catalog.data.repository.ServiceRepository;
@@ -138,6 +139,42 @@ public class ASDCRestInterfaceTest extends BaseTest {
                 .ignoring("0x1.allotedResourceCustomization.created"));
     }
 
+    @Test
+    @Transactional
+    public void test_VFW_Distrobution() throws Exception {
+
+        wireMockServer.stubFor(post(urlPathMatching("/aai/.*"))
+                .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json")));
+
+        ObjectMapper mapper = new ObjectMapper();
+        NotificationDataImpl request = mapper.readValue(
+                new File("src/test/resources/resource-examples/vFW/notification.json"), NotificationDataImpl.class);
+        headers.add("resource-location", "src/test/resources/resource-examples/vFW/");
+        HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
+
+        ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("test/treatNotification/v1"),
+                HttpMethod.POST, entity, String.class);
+
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusCode().value());
+
+        Service expectedService = new Service();
+        expectedService.setDescription("catalog service description");
+        expectedService.setModelInvariantUUID("3164f9ff-d7e7-4813-ab32-6be7e1cacb18");
+        expectedService.setModelName("vFW 2019-04-10 21:53:05");
+        expectedService.setModelUUID("e16e4ed9-3429-423a-bc3c-1389ae91491c");
+        expectedService.setModelVersion("1.0");
+
+
+
+        Service actualService = serviceRepo.findOneByModelUUID("e16e4ed9-3429-423a-bc3c-1389ae91491c");
+
+
+        if (actualService == null)
+            throw new Exception("No Allotted Resource Written to database");
+
+        assertEquals(expectedService.getModelName(), actualService.getModelName());
+    }
+
     @Test
     public void invokeASDCStatusDataNullTest() {
         String request = "";
diff --git a/asdc-controller/src/test/resources/resource-examples/vFW/base_vfw.env b/asdc-controller/src/test/resources/resource-examples/vFW/base_vfw.env
new file mode 100644 (file)
index 0000000..f490db5
--- /dev/null
@@ -0,0 +1,38 @@
+parameters:
+  cloud_env: "openstack"
+  dcae_collector_ip: "10.0.4.1"
+  dcae_collector_port: "30235"
+  demo_artifacts_version: "1.4.0-SNAPSHOT"
+  install_script_version: "1.4.0-SNAPSHOT"
+  key_name: "vfw_key"
+  nexus_artifact_repo: "https://nexus.onap.org"
+  onap_private_net_cidr: "10.0.0.0/16"
+  onap_private_net_id: "PUT THE ONAP PRIVATE NETWORK NAME HERE"
+  onap_private_subnet_id: "PUT THE ONAP PRIVATE NETWORK NAME HERE"
+  protected_private_net_cidr: "192.168.20.0/24"
+  protected_private_net_id: "zdfw1fwl01_protected"
+  pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQXYJYYi3/OUZXUiCYWdtc7K0m5C0dJKVxPG0eI8EWZrEHYdfYe6WoTSDJCww+1qlBSpA5ac/Ba4Wn9vh+lR1vtUKkyIC/nrYb90ReUd385Glkgzrfh5HdR5y5S2cL/Frh86lAn9r6b3iWTJD8wBwXFyoe1S2nMTOIuG4RPNvfmyCTYVh8XTCCE8HPvh3xv2r4egawG1P4Q4UDwk+hDBXThY2KS8M5/8EMyxHV0ImpLbpYCTBA6KYDIRtqmgS6iKyy8v2D1aSY5mc9J0T5t9S2Gv+VZQNWQDDKNFnxqYaAo1uEoq/i1q63XC5AD3ckXb2VT6dp23BQMdDfbHyUWfJN"
+  public_net_id: "PUT THE PUBLIC NETWORK ID HERE"
+  sec_group: "PUT THE ONAP SECURITY GROUP HERE"
+  unprotected_private_net_cidr: "192.168.10.0/24"
+  unprotected_private_net_id: "zdfw1fwl01_unprotected"
+  vf_module_id: "vFirewall"
+  vfw_flavor_name: "PUT THE VM FLAVOR NAME HERE (m1.medium suggested)"
+  vfw_image_name: "PUT THE VM IMAGE NAME HERE (UBUNTU 1404 required)"
+  vfw_int_protected_private_floating_ip: "192.168.10.200"
+  vfw_int_protected_private_ip_0: "192.168.20.100"
+  vfw_int_unprotected_private_ip_0: "192.168.10.100"
+  vfw_name_0: "zdfw1fwl01fwl01"
+  vfw_onap_private_ip_0: "10.0.100.1"
+  vnf_id: "vFirewall_demo_app"
+  vnf_name: "vFW"
+  vpg_flavor_name: "PUT THE VM FLAVOR NAME HERE (m1.medium suggested)"
+  vpg_image_name: "PUT THE VM IMAGE NAME HERE (UBUNTU 1404 required)"
+  vpg_int_unprotected_private_ip_0: "192.168.10.200"
+  vpg_name_0: "zdfw1fwl01pgn01"
+  vpg_onap_private_ip_0: "10.0.100.2"
+  vsn_flavor_name: "PUT THE VM FLAVOR NAME HERE (m1.medium suggested)"
+  vsn_image_name: "PUT THE VM IMAGE NAME HERE (UBUNTU 1404 required)"
+  vsn_int_protected_private_ip_0: "192.168.20.250"
+  vsn_name_0: "zdfw1fwl01snk01"
+  vsn_onap_private_ip_0: "10.0.100.3"
diff --git a/asdc-controller/src/test/resources/resource-examples/vFW/base_vfw.yaml b/asdc-controller/src/test/resources/resource-examples/vFW/base_vfw.yaml
new file mode 100644 (file)
index 0000000..6137e8a
--- /dev/null
@@ -0,0 +1,491 @@
+##########################################################################
+#
+#==================LICENSE_START==========================================
+#
+#
+# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#==================LICENSE_END============================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+#
+##########################################################################
+
+heat_template_version: 2013-05-23
+
+description: Heat template that deploys vFirewall demo app for ONAP
+
+##############
+#            #
+# PARAMETERS #
+#            #
+##############
+
+parameters:
+  vfw_image_name:
+    type: string
+    label: Image name or ID
+    description: Image to be used for compute instance
+  vfw_flavor_name:
+    type: string
+    label: Flavor
+    description: Type of instance (flavor) to be used
+  vpg_image_name:
+    type: string
+    label: Image name or ID
+    description: Image to be used for compute instance
+  vpg_flavor_name:
+    type: string
+    label: Flavor
+    description: Type of instance (flavor) to be used
+  vsn_image_name:
+    type: string
+    label: Image name or ID
+    description: Image to be used for compute instance
+  vsn_flavor_name:
+    type: string
+    label: Flavor
+    description: Type of instance (flavor) to be used
+  public_net_id:
+    type: string
+    label: Public network name or ID
+    description: Public network that enables remote connection to VNF
+  unprotected_private_net_id:
+    type: string
+    label: Unprotected private network name or ID
+    description: Private network that connects vPacketGenerator with vFirewall
+  protected_private_net_id:
+    type: string
+    label: Protected private network name or ID
+    description: Private network that connects vFirewall with vSink
+  onap_private_net_id:
+    type: string
+    label: ONAP management network name or ID
+    description: Private network that connects ONAP components and the VNF
+  onap_private_subnet_id:
+    type: string
+    label: ONAP management sub-network name or ID
+    description: Private sub-network that connects ONAP components and the VNF
+  unprotected_private_net_cidr:
+    type: string
+    label: Unprotected private network CIDR
+    description: The CIDR of the unprotected private network
+  protected_private_net_cidr:
+    type: string
+    label: Protected private network CIDR
+    description: The CIDR of the protected private network
+  onap_private_net_cidr:
+    type: string
+    label: ONAP private network CIDR
+    description: The CIDR of the protected private network
+  vfw_int_unprotected_private_ip_0:
+    type: string
+    label: vFirewall private IP address towards the unprotected network
+    description: Private IP address that is assigned to the vFirewall to communicate with the vPacketGenerator
+  vfw_int_protected_private_ip_0:
+    type: string
+    label: vFirewall private IP address towards the protected network
+    description: Private IP address that is assigned to the vFirewall to communicate with the vSink
+  vfw_onap_private_ip_0:
+    type: string
+    label: vFirewall private IP address towards the ONAP management network
+    description: Private IP address that is assigned to the vFirewall to communicate with ONAP components
+  vfw_int_protected_private_floating_ip:
+    type: string
+    label: same value as vpg_int_unprotected_private_ip_0  
+    description: IP to inform OpenStack to enable vfw protected private port to allow packets coming from the packet generator
+  vpg_int_unprotected_private_ip_0:
+    type: string
+    label: vPacketGenerator private IP address towards the unprotected network
+    description: Private IP address that is assigned to the vPacketGenerator to communicate with the vFirewall
+  vpg_onap_private_ip_0:
+    type: string
+    label: vPacketGenerator private IP address towards the ONAP management network
+    description: Private IP address that is assigned to the vPacketGenerator to communicate with ONAP components
+  vsn_int_protected_private_ip_0:
+    type: string
+    label: vSink private IP address towards the protected network
+    description: Private IP address that is assigned to the vSink to communicate with the vFirewall
+  vsn_onap_private_ip_0:
+    type: string
+    label: vSink private IP address towards the ONAP management network
+    description: Private IP address that is assigned to the vSink to communicate with ONAP components
+  vfw_name_0:
+    type: string
+    label: vFirewall name
+    description: Name of the vFirewall
+  vpg_name_0:
+    type: string
+    label: vPacketGenerator name
+    description: Name of the vPacketGenerator
+  vsn_name_0:
+    type: string
+    label: vSink name
+    description: Name of the vSink
+  vnf_id:
+    type: string
+    label: VNF ID
+    description: The VNF ID is provided by ONAP
+  vnf_name:
+    type: string
+    label: VNF NAME
+    description: The VNF NAME is provided by ONAP
+  vf_module_id:
+    type: string
+    label: vFirewall module ID
+    description: The vFirewall Module ID is provided by ONAP
+  dcae_collector_ip:
+    type: string
+    label: DCAE collector IP address
+    description: IP address of the DCAE collector
+  dcae_collector_port:
+    type: string
+    label: DCAE collector port
+    description: Port of the DCAE collector
+  key_name:
+    type: string
+    label: Key pair name
+    description: Public/Private key pair name
+  pub_key:
+    type: string
+    label: Public key
+    description: Public key to be installed on the compute instance
+  install_script_version:
+    type: string
+    label: Installation script version number
+    description: Version number of the scripts that install the vFW demo app
+  demo_artifacts_version:
+    type: string
+    label: Artifacts version used in demo vnfs
+    description: Artifacts (jar, tar.gz) version used in demo vnfs
+  nexus_artifact_repo:
+    type: string
+    description: Root URL for the Nexus repository for Maven artifacts.
+  cloud_env:
+    type: string
+    label: Cloud environment
+    description: Cloud environment (e.g., openstack, rackspace)
+  sec_group:
+    type: string
+    description: ONAP Security Group
+
+#############
+#           #
+# RESOURCES #
+#           #
+#############
+
+resources:
+  random-str:
+    type: OS::Heat::RandomString
+    properties:
+      length: 4
+
+  my_keypair:
+    type: OS::Nova::KeyPair
+    properties:
+      name:
+        str_replace:
+          template: vnfname_base_rand
+          params:
+            base: { get_param: key_name }
+            rand: { get_resource: random-str }
+            vnfname: { get_param: vnf_name }
+      public_key: { get_param: pub_key }
+      save_private_key: false
+
+  # NETWORK_ROLE: unprotected_private
+  # NETWORK_TYPE: internal
+  int_unprotected_private_network:
+    type: OS::Neutron::Net
+    properties:
+      name:
+        str_replace:
+          template: vnfname_netid
+          params:
+            netid: { get_param: unprotected_private_net_id }
+            vnfname: { get_param: vnf_name }
+
+  # NETWORK_ROLE: protected_private
+  # NETWORK_TYPE: internal
+  int_protected_private_network:
+    type: OS::Neutron::Net
+    properties:
+      name:
+        str_replace:
+          template: vnfname_netid
+          params:
+            netid: { get_param: protected_private_net_id }
+            vnfname: { get_param: vnf_name }
+
+  # NETWORK_ROLE: unprotected_private
+  # NETWORK_TYPE: internal
+  int_unprotected_private_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      network: { get_resource: int_unprotected_private_network }
+      cidr: { get_param: unprotected_private_net_cidr }
+
+  # NETWORK_ROLE: protected_private
+  # NETWORK_TYPE: internal
+  int_protected_private_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      network: { get_resource: int_protected_private_network }
+      cidr: { get_param: protected_private_net_cidr }
+
+  ### Virtual Firewall instantiation ###
+
+  # VM_TYPE: vfw
+  # NETWORK_ROLE: protected_private
+  # NETWORK_TYPE: internal
+  vfw_0_int_unprotected_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: int_unprotected_private_network }
+      fixed_ips: [{"subnet": { get_resource: int_unprotected_private_subnet }, "ip_address": { get_param: vfw_int_unprotected_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  # VM_TYPE: vfw
+  # NETWORK_ROLE: protected_private
+  # NETWORK_TYPE: internal
+  vfw_0_int_protected_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      allowed_address_pairs: [{ "ip_address": { get_param: vfw_int_protected_private_floating_ip }}]
+      network: { get_resource: int_protected_private_network }
+      fixed_ips: [{"subnet": { get_resource: int_protected_private_subnet }, "ip_address": { get_param: vfw_int_protected_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  # VM_TYPE: vfw
+  # NETWORK_ROLE: onap_private
+  # NETWORK_TYPE: external
+  vfw_0_onap_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: onap_private_net_id }
+      fixed_ips: [{"subnet": { get_param: onap_private_subnet_id }, "ip_address": { get_param: vfw_onap_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  # VM_TYPE: vfw
+  vfw_server_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vfw_image_name }
+      flavor: { get_param: vfw_flavor_name }
+      name: { get_param: vfw_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vfw_0_int_unprotected_private_port_0 }
+        - port: { get_resource: vfw_0_int_protected_private_port_0 }
+        - port: { get_resource: vfw_0_onap_private_port_0 }
+      metadata:
+        vnf_id: { get_param: vnf_id }
+        vf_module_id: { get_param: vf_module_id }
+        vnf_name: { get_param: vnf_name }
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __dcae_collector_ip__ : { get_param: dcae_collector_ip }
+            __dcae_collector_port__ : { get_param: dcae_collector_port }
+            __demo_artifacts_version__ : { get_param: demo_artifacts_version }
+            __install_script_version__ : { get_param: install_script_version }
+            __vfw_private_ip_0__ : { get_param: vfw_int_unprotected_private_ip_0 }
+            __vfw_private_ip_1__ : { get_param: vfw_int_protected_private_ip_0 }
+            __vfw_private_ip_2__ : { get_param: vfw_onap_private_ip_0 }
+            __unprotected_private_net_cidr__ : { get_param: unprotected_private_net_cidr }
+            __protected_private_net_cidr__ : { get_param: protected_private_net_cidr }
+            __onap_private_net_cidr__ : { get_param: onap_private_net_cidr }
+            __cloud_env__ : { get_param: cloud_env }
+            __nexus_artifact_repo__: { get_param: nexus_artifact_repo }
+          template: |
+            #!/bin/bash
+
+            # Create configuration files
+            mkdir /opt/config
+            echo "__dcae_collector_ip__" > /opt/config/dcae_collector_ip.txt
+            echo "__dcae_collector_port__" > /opt/config/dcae_collector_port.txt
+            echo "__demo_artifacts_version__" > /opt/config/demo_artifacts_version.txt
+            echo "__install_script_version__" > /opt/config/install_script_version.txt
+            echo "__vfw_private_ip_0__" > /opt/config/vfw_private_ip_0.txt
+            echo "__vfw_private_ip_1__" > /opt/config/vfw_private_ip_1.txt
+            echo "__vfw_private_ip_2__" > /opt/config/vfw_private_ip_2.txt
+            echo "__unprotected_private_net_cidr__" > /opt/config/unprotected_private_net_cidr.txt
+            echo "__protected_private_net_cidr__" > /opt/config/protected_private_net_cidr.txt
+            echo "__onap_private_net_cidr__" > /opt/config/onap_private_net_cidr.txt
+            echo "__cloud_env__" > /opt/config/cloud_env.txt
+            echo "__nexus_artifact_repo__" > /opt/config/nexus_artifact_repo.txt
+
+            # Download and run install script
+            apt-get update
+            apt-get -y install unzip
+            if [[ "__install_script_version__" =~ "SNAPSHOT" ]]; then REPO=snapshots; else REPO=releases; fi
+            curl -k -L "__nexus_artifact_repo__/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.demo.vnf.vfw&a=vfw-scripts&e=zip&v=__install_script_version__" -o /opt/vfw-scripts-__install_script_version__.zip
+            unzip -j /opt/vfw-scripts-__install_script_version__.zip -d /opt v_firewall_install.sh
+            cd /opt
+            chmod +x v_firewall_install.sh
+            ./v_firewall_install.sh
+
+
+  ### Virtual Packet Generator instantiation ###
+
+  vpg_0_int_unprotected_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: int_unprotected_private_network }
+      fixed_ips: [{"subnet": { get_resource: int_unprotected_private_subnet }, "ip_address": { get_param: vpg_int_unprotected_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  vpg_0_onap_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: onap_private_net_id }
+      fixed_ips: [{"subnet": { get_param: onap_private_subnet_id }, "ip_address": { get_param: vpg_onap_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  vpg_server_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vpg_image_name }
+      flavor: { get_param: vpg_flavor_name }
+      name: { get_param: vpg_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vpg_0_int_unprotected_private_port_0 }
+        - port: { get_resource: vpg_0_onap_private_port_0 }
+      metadata:
+        vnf_id: { get_param: vnf_id }
+        vf_module_id: { get_param: vf_module_id }
+        vnf_name: { get_param: vnf_name }
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __fw_ipaddr__: { get_param: vfw_int_unprotected_private_ip_0 }
+            __protected_net_cidr__: { get_param: protected_private_net_cidr }
+            __sink_ipaddr__: { get_param: vsn_int_protected_private_ip_0 }
+            __demo_artifacts_version__ : { get_param: demo_artifacts_version }
+            __install_script_version__ : { get_param: install_script_version }
+            __vpg_private_ip_0__ : { get_param: vpg_int_unprotected_private_ip_0 }
+            __vpg_private_ip_1__ : { get_param: vpg_onap_private_ip_0 }
+            __unprotected_private_net_cidr__ : { get_param: unprotected_private_net_cidr }
+            __onap_private_net_cidr__ : { get_param: onap_private_net_cidr }
+            __cloud_env__ : { get_param: cloud_env }
+            __nexus_artifact_repo__: { get_param: nexus_artifact_repo }
+          template: |
+            #!/bin/bash
+
+            # Create configuration files
+            mkdir /opt/config
+            echo "__fw_ipaddr__" > /opt/config/fw_ipaddr.txt
+            echo "__protected_net_cidr__" > /opt/config/protected_net_cidr.txt
+            echo "__sink_ipaddr__" > /opt/config/sink_ipaddr.txt
+            echo "__demo_artifacts_version__" > /opt/config/demo_artifacts_version.txt
+            echo "__install_script_version__" > /opt/config/install_script_version.txt
+            echo "__vpg_private_ip_0__" > /opt/config/vpg_private_ip_0.txt
+            echo "__vpg_private_ip_1__" > /opt/config/vpg_private_ip_1.txt
+            echo "__unprotected_private_net_cidr__" > /opt/config/unprotected_private_net_cidr.txt
+            echo "__onap_private_net_cidr__" > /opt/config/onap_private_net_cidr.txt
+            echo "__cloud_env__" > /opt/config/cloud_env.txt
+            echo "__nexus_artifact_repo__" > /opt/config/nexus_artifact_repo.txt
+
+            # Download and run install script
+            apt-get update
+            apt-get -y install unzip
+            if [[ "__install_script_version__" =~ "SNAPSHOT" ]]; then REPO=snapshots; else REPO=releases; fi
+            curl -k -L "__nexus_artifact_repo__/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.demo.vnf.vfw&a=vfw-scripts&e=zip&v=__install_script_version__" -o /opt/vfw-scripts-__install_script_version__.zip
+            unzip -j /opt/vfw-scripts-__install_script_version__.zip -d /opt v_packetgen_install.sh
+            cd /opt
+            chmod +x v_packetgen_install.sh
+            ./v_packetgen_install.sh
+
+
+  ### Virtual Sink instantiation ###
+
+  vsn_0_int_protected_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: int_protected_private_network }
+      fixed_ips: [{"subnet": { get_resource: int_protected_private_subnet }, "ip_address": { get_param: vsn_int_protected_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  vsn_0_onap_private_port_0:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: onap_private_net_id }
+      fixed_ips: [{"subnet": { get_param: onap_private_subnet_id }, "ip_address": { get_param: vsn_onap_private_ip_0 }}]
+      security_groups:
+      - { get_param: sec_group }
+
+  vsn_server_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vsn_image_name }
+      flavor: { get_param: vsn_flavor_name }
+      name: { get_param: vsn_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vsn_0_int_protected_private_port_0 }
+        - port: { get_resource: vsn_0_onap_private_port_0 }
+      metadata:
+        vnf_id: { get_param: vnf_id }
+        vf_module_id: { get_param: vf_module_id }
+        vnf_name: { get_param: vnf_name }
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __protected_net_gw__: { get_param: vfw_int_protected_private_ip_0 }
+            __unprotected_net__: { get_param: unprotected_private_net_cidr }
+            __install_script_version__ : { get_param: install_script_version }
+            __vsn_private_ip_0__ : { get_param: vsn_int_protected_private_ip_0 }
+            __vsn_private_ip_1__ : { get_param: vsn_onap_private_ip_0 }
+            __protected_private_net_cidr__ : { get_param: protected_private_net_cidr }
+            __onap_private_net_cidr__ : { get_param: onap_private_net_cidr }
+            __cloud_env__ : { get_param: cloud_env }
+            __nexus_artifact_repo__: { get_param: nexus_artifact_repo }
+          template: |
+            #!/bin/bash
+
+            # Create configuration files
+            mkdir /opt/config
+            echo "__protected_net_gw__" > /opt/config/protected_net_gw.txt
+            echo "__unprotected_net__" > /opt/config/unprotected_net.txt
+            echo "__install_script_version__" > /opt/config/install_script_version.txt
+            echo "__vsn_private_ip_0__" > /opt/config/vsn_private_ip_0.txt
+            echo "__vsn_private_ip_1__" > /opt/config/vsn_private_ip_1.txt
+            echo "__protected_private_net_cidr__" > /opt/config/protected_private_net_cidr.txt
+            echo "__onap_private_net_cidr__" > /opt/config/onap_private_net_cidr.txt
+            echo "__cloud_env__" > /opt/config/cloud_env.txt
+            echo "__nexus_artifact_repo__" > /opt/config/nexus_artifact_repo.txt
+
+            # Download and run install script
+            apt-get update
+            apt-get -y install unzip
+            if [[ "__install_script_version__" =~ "SNAPSHOT" ]]; then REPO=snapshots; else REPO=releases; fi
+            curl -k -L "__nexus_artifact_repo__/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.demo.vnf.vfw&a=vfw-scripts&e=zip&v=__install_script_version__" -o /opt/vfw-scripts-__install_script_version__.zip
+            unzip -j /opt/vfw-scripts-__install_script_version__.zip -d /opt v_sink_install.sh
+            cd /opt
+            chmod +x v_sink_install.sh
+            ./v_sink_install.sh
diff --git a/asdc-controller/src/test/resources/resource-examples/vFW/notification.json b/asdc-controller/src/test/resources/resource-examples/vFW/notification.json
new file mode 100644 (file)
index 0000000..4e93df5
--- /dev/null
@@ -0,0 +1,80 @@
+{
+  "distributionID": "3d1c9f3c-550e-41c3-bfb6-800f8274a40c", 
+  "resources": [
+    {
+      "artifacts": [
+        {
+          "artifactChecksum": "NDg0ZDJjYTIzNDhlZmFkZjRjMzM5MTkzOGFhZTU5ZjI=", 
+          "artifactDescription": "Auto-generated VF Modules information artifact", 
+          "artifactName": "vfw1f52feb055020_modules.json", 
+          "artifactTimeout": 120, 
+          "artifactType": "VF_MODULES_METADATA", 
+          "artifactURL": "vfw1f52feb055020_modules.json", 
+          "artifactUUID": "7ff1c5cb-8ca1-43b1-8f97-05c0d8c879ec", 
+          "artifactVersion": "1", 
+          "relatedArtifactsInfo": []
+        }, 
+        {
+          "artifactChecksum": "MDQyYTIxMTlhZDdlMzdiNjBjNjdjZTFhMWE0NThmMzc=", 
+          "artifactDescription": "created from csar", 
+          "artifactName": "base_vfw.yaml", 
+          "artifactTimeout": 120, 
+          "artifactType": "HEAT", 
+          "artifactURL": "base_vfw.yaml", 
+          "artifactUUID": "4f0b1b88-09ab-43b9-9506-57de3c69433a", 
+          "artifactVersion": "2", 
+          "generatedArtifact": {
+            "artifactChecksum": "MjQ2YWIxOTY2M2E0ZjAzMTI4NjVkNWZkZGRmM2VmMGI=", 
+            "artifactDescription": "Auto-generated HEAT Environment deployment artifact", 
+            "artifactName": "base_vfw.env", 
+            "artifactTimeout": 120, 
+            "artifactType": "HEAT_ENV", 
+            "artifactURL": "base_vfw.env", 
+            "artifactUUID": "005bc362-b40f-4c54-82bc-2716147f9c3a", 
+            "artifactVersion": "2", 
+            "generatedFromUUID": "4f0b1b88-09ab-43b9-9506-57de3c69433a"
+          }, 
+          "relatedArtifactsInfo": []
+        }, 
+        {
+          "artifactChecksum": "MjQ2YWIxOTY2M2E0ZjAzMTI4NjVkNWZkZGRmM2VmMGI=", 
+          "artifactDescription": "Auto-generated HEAT Environment deployment artifact", 
+          "artifactName": "base_vfw.env", 
+          "artifactTimeout": 120, 
+          "artifactType": "HEAT_ENV", 
+          "artifactURL": "base_vfw.env", 
+          "artifactUUID": "005bc362-b40f-4c54-82bc-2716147f9c3a", 
+          "artifactVersion": "2", 
+          "relatedArtifactsInfo": []
+        }
+      ], 
+      "category": "Generic", 
+      "resourceType": "VF", 
+      "resourceCustomizationUUID": "0451bf8d-49e1-4f7f-960f-2e24f27c9f42", 
+      "resourceInstanceName": "vFW 1f52feb0-5502 0", 
+      "resourceInvariantUUID": "459f18ec-aaee-40d1-8fae-60fec2aae37f", 
+      "resourceName": "vFW 1f52feb0-5502", 
+      "resourceUUID": "1b1346cb-bf0b-4097-9d1b-5a041c536897", 
+      "resourceVersion": "1.0", 
+      "subcategory": "Abstract"
+    }
+  ], 
+  "serviceArtifacts": [
+    {
+      "artifactChecksum": "YWNkZTJmYmVmYTg0NTdjMzg0MjVjZTliOTRiYTQ5YjM=", 
+      "artifactDescription": "TOSCA definition package of the asset", 
+      "artifactName": "service-Vfw20190410215305-csar.csar", 
+      "artifactTimeout": 0, 
+      "artifactType": "TOSCA_CSAR", 
+      "artifactURL": "service-Vfw.csar", 
+      "artifactUUID": "f4fcb0ba-40d3-46d2-819e-3b69eda88fcf",
+      "artifactVersion": "1"
+    }
+  ], 
+  "serviceDescription": "catalog service description", 
+  "serviceInvariantUUID": "3164f9ff-d7e7-4813-ab32-6be7e1cacb18", 
+  "serviceName": "vFW 2019-04-10 21:53:05", 
+  "serviceUUID": "e16e4ed9-3429-423a-bc3c-1389ae91491c", 
+  "serviceVersion": "1.0", 
+  "workloadContext": "Production"
+}
diff --git a/asdc-controller/src/test/resources/resource-examples/vFW/service-Vfw.csar b/asdc-controller/src/test/resources/resource-examples/vFW/service-Vfw.csar
new file mode 100644 (file)
index 0000000..fe0b9f3
Binary files /dev/null and b/asdc-controller/src/test/resources/resource-examples/vFW/service-Vfw.csar differ
diff --git a/asdc-controller/src/test/resources/resource-examples/vFW/vfw1f52feb055020_modules.json b/asdc-controller/src/test/resources/resource-examples/vFW/vfw1f52feb055020_modules.json
new file mode 100644 (file)
index 0000000..944adbd
--- /dev/null
@@ -0,0 +1,25 @@
+[
+  {
+    "vfModuleModelName": "Vfw1f52feb05502..base_vfw..module-0",
+    "vfModuleModelInvariantUUID": "062e75f9-ccbd-4946-8d31-92118efac741",
+    "vfModuleModelVersion": "1",
+    "vfModuleModelUUID": "3f99a421-abd0-4e5e-a9e4-3b9b8464ddb6",
+    "vfModuleModelCustomizationUUID": "12c7bf93-9021-41cf-8c65-86856cfab11d",
+    "isBase": true,
+    "artifacts": [
+      "4f0b1b88-09ab-43b9-9506-57de3c69433a",
+      "005bc362-b40f-4c54-82bc-2716147f9c3a"
+    ],
+    "properties": {
+      "min_vf_module_instances": "1",
+      "vf_module_label": "base_vfw",
+      "max_vf_module_instances": "1",
+      "vfc_list": "",
+      "vf_module_description": "",
+      "vf_module_type": "Base",
+      "availability_zone_count": "",
+      "volume_group": "false",
+      "initial_count": "1"
+    }
+  }
+]
\ No newline at end of file
index 2db2dfb..0b48b2e 100644 (file)
@@ -1,7 +1,6 @@
 
 --------START Catalog DB SCHEMA --------
 use catalogdb;
-
 set foreign_key_checks=0;
 DROP TABLE IF EXISTS `allotted_resource`;
 /*!40101 SET @saved_cs_client     = @@character_set_client */;
@@ -1170,7 +1169,7 @@ CREATE TABLE `vnfc_instance_group_customization` (
 set foreign_key_checks=1;
 
 CREATE TABLE IF NOT EXISTS `pnf_resource` (
-  `ORCHESTRATION_MODE` varchar(20) NOT NULL DEFAULT 'HEAT',
+  `ORCHESTRATION_MODE` varchar(20) DEFAULT NULL,
   `DESCRIPTION` varchar(1200) DEFAULT NULL,
   `CREATION_TIMESTAMP` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `MODEL_UUID` varchar(200) NOT NULL,
@@ -1208,6 +1207,170 @@ CREATE TABLE IF NOT EXISTS `pnf_resource_customization_to_service` (
   PRIMARY KEY (`SERVICE_MODEL_UUID`,`RESOURCE_MODEL_CUSTOMIZATION_UUID`)
 )ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
+CREATE TABLE IF NOT EXISTS `workflow` (
+  `ID` int(11) NOT NULL AUTO_INCREMENT,
+  `ARTIFACT_UUID` varchar(200) NOT NULL,
+  `ARTIFACT_NAME` varchar(200) NOT NULL,
+  `NAME` varchar(200) NOT NULL,
+  `OPERATION_NAME` varchar(200) DEFAULT NULL,
+  `VERSION` double NOT NULL,
+  `DESCRIPTION` varchar(1200) DEFAULT NULL,
+  `BODY` longtext DEFAULT NULL,
+  `RESOURCE_TARGET` varchar(200) NOT NULL,
+  `SOURCE` varchar(200) NOT NULL,
+  `TIMEOUT_MINUTES` int(11) DEFAULT NULL,
+  `ARTIFACT_CHECKSUM` varchar(200) DEFAULT 'MANUAL RECORD',
+  `CREATION_TIMESTAMP` datetime NOT NULL DEFAULT current_timestamp(),
+  PRIMARY KEY (`ID`),
+  UNIQUE KEY `UK_workflow` (`ARTIFACT_UUID`,`NAME`,`VERSION`,`SOURCE`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `vnf_resource_to_workflow` (
+  `ID` int(11) NOT NULL AUTO_INCREMENT,
+  `VNF_RESOURCE_MODEL_UUID` varchar(200) NOT NULL,
+  `WORKFLOW_ID` int(11) NOT NULL,
+  PRIMARY KEY (`ID`),
+  UNIQUE KEY `UK_vnf_resource_to_workflow` (`VNF_RESOURCE_MODEL_UUID`,`WORKFLOW_ID`),
+  KEY `fk_vnf_resource_to_workflow__workflow1_idx` (`WORKFLOW_ID`),
+  KEY `fk_vnf_resource_to_workflow__vnf_res_mod_uuid_idx` (`VNF_RESOURCE_MODEL_UUID`),
+  CONSTRAINT `fk_vnf_resource_to_workflow__vnf_resource1` FOREIGN KEY (`VNF_RESOURCE_MODEL_UUID`) REFERENCES `vnf_resource` (`MODEL_UUID`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `fk_vnf_resource_to_workflow__workflow1` FOREIGN KEY (`WORKFLOW_ID`) REFERENCES `workflow` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `activity_spec` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `NAME` VARCHAR(200) NOT NULL,
+  `DESCRIPTION` VARCHAR(1200) NOT NULL,
+  `VERSION` DOUBLE NOT NULL,
+  `CREATION_TIMESTAMP` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_activity_spec` (`NAME` ASC, `VERSION` ASC))
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `user_parameters` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `NAME` VARCHAR(200) NOT NULL,
+  `PAYLOAD_LOCATION` VARCHAR(500) NULL,
+  `LABEL` VARCHAR(200) NOT NULL,
+  `TYPE` VARCHAR(200) NOT NULL,
+  `DESCRIPTION` VARCHAR(1200) NULL,
+  `IS_REQUIRED` TINYINT(1) NOT NULL,
+  `MAX_LENGTH` INT(11) NULL,
+  `ALLOWABLE_CHARS` VARCHAR(200) NULL,
+  `CREATION_TIMESTAMP` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_user_parameters` (`NAME` ASC))
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `workflow_activity_spec_sequence` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `WORKFLOW_ID` INT(11) NOT NULL,
+  `ACTIVITY_SPEC_ID` INT(11) NOT NULL,
+  `SEQ_NO` INT(11) NOT NULL,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_workflow_activity_spec_sequence` (`WORKFLOW_ID` ASC, `ACTIVITY_SPEC_ID` ASC, `SEQ_NO` ASC),
+  INDEX `fk_workflow_activity_spec_sequence__activity_spec_idx` (`ACTIVITY_SPEC_ID` ASC),
+  INDEX `fk_workflow_activity_spec_sequence__workflow_actifact_uuid_idx` (`WORKFLOW_ID` ASC),
+  CONSTRAINT `fk_workflow_activity_spec_sequence__activity_spec1`
+    FOREIGN KEY (`ACTIVITY_SPEC_ID`)
+    REFERENCES `activity_spec` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE,
+  CONSTRAINT `fk_workflow_activity_spec_sequence__workflow1`
+    FOREIGN KEY (`WORKFLOW_ID`)
+    REFERENCES `workflow` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE)
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `activity_spec_parameters` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `NAME` VARCHAR(200) NOT NULL,
+  `TYPE` VARCHAR(200) NOT NULL,
+  `DIRECTION` VARCHAR(200) NULL,
+  `DESCRIPTION` VARCHAR(1200) NULL,
+  `CREATION_TIMESTAMP` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_activity_spec_parameters` (`NAME` ASC, `DIRECTION` ASC))
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `activity_spec_categories` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `NAME` VARCHAR(200) NOT NULL,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_activity_spec_categories` (`NAME` ASC))
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `activity_spec_to_activity_spec_categories` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `ACTIVITY_SPEC_ID` INT(11) NOT NULL,
+  `ACTIVITY_SPEC_CATEGORIES_ID` INT(11) NOT NULL,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_activity_spec_to_activity_spec_categories` (`ACTIVITY_SPEC_ID` ASC, `ACTIVITY_SPEC_CATEGORIES_ID` ASC),
+  INDEX `fk_activity_spec_to_activity_spec_categories__activity_spec_idx` (`ACTIVITY_SPEC_CATEGORIES_ID` ASC),
+  INDEX `fk_activity_spec_to_activity_spec_categories__activity_spec_idx1` (`ACTIVITY_SPEC_ID` ASC),
+  CONSTRAINT `fk_activity_spec_to_activity_spec_categories__activity_spec1`
+    FOREIGN KEY (`ACTIVITY_SPEC_ID`)
+    REFERENCES `activity_spec` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE,
+  CONSTRAINT `fk_activity_spec_to_activity_spec_categories__activity_spec_c1`
+    FOREIGN KEY (`ACTIVITY_SPEC_CATEGORIES_ID`)
+    REFERENCES `activity_spec_categories` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE)
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `activity_spec_to_activity_spec_parameters` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `ACTIVITY_SPEC_ID` INT(11) NOT NULL,
+  `ACTIVITY_SPEC_PARAMETERS_ID` INT(11) NOT NULL,
+  PRIMARY KEY (`ID`),
+  INDEX `fk_activity_spec_to_activity_spec_params__act_sp_param_id_idx` (`ACTIVITY_SPEC_PARAMETERS_ID` ASC),
+  UNIQUE INDEX `UK_activity_spec_to_activity_spec_parameters` (`ACTIVITY_SPEC_ID` ASC, `ACTIVITY_SPEC_PARAMETERS_ID` ASC),
+  INDEX `fk_activity_spec_to_activity_spec_parameters__act_spec_id_idx` (`ACTIVITY_SPEC_ID` ASC),
+  CONSTRAINT `fk_activity_spec_to_activity_spec_parameters__activity_spec_1`
+    FOREIGN KEY (`ACTIVITY_SPEC_ID`)
+    REFERENCES `activity_spec` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE,
+  CONSTRAINT `fk_activity_spec_to_activity_spec_parameters__activ_spec_param1`
+    FOREIGN KEY (`ACTIVITY_SPEC_PARAMETERS_ID`)
+    REFERENCES `activity_spec_parameters` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE)
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+CREATE TABLE IF NOT EXISTS `activity_spec_to_user_parameters` (
+  `ID` INT(11) NOT NULL AUTO_INCREMENT,
+  `ACTIVITY_SPEC_ID` INT(11) NOT NULL,
+  `USER_PARAMETERS_ID` INT(11) NOT NULL,
+  PRIMARY KEY (`ID`),
+  UNIQUE INDEX `UK_activity_spec_to_user_parameters` (`ACTIVITY_SPEC_ID` ASC, `USER_PARAMETERS_ID` ASC),
+  INDEX `fk_activity_spec_to_user_parameters__user_parameters1_idx` (`USER_PARAMETERS_ID` ASC),
+  INDEX `fk_activity_spec_to_user_parameters__activity_spec1_idx` (`ACTIVITY_SPEC_ID` ASC),
+  CONSTRAINT `fk_activity_spec_to_user_parameters__activity_spec1`
+    FOREIGN KEY (`ACTIVITY_SPEC_ID`)
+    REFERENCES `activity_spec` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE,
+  CONSTRAINT `fk_activity_spec_to_user_parameters__user_parameters1`
+    FOREIGN KEY (`USER_PARAMETERS_ID`)
+    REFERENCES `user_parameters` (`ID`)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE)
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = latin1;
+
+
+
 --------START Request DB SCHEMA --------
 CREATE DATABASE requestdb;
 USE requestdb;
@@ -1477,3 +1640,7 @@ create table if not exists model (
        CONSTRAINT uk1_model UNIQUE (`MODEL_TYPE`, `MODEL_VERSION_ID`),
        FOREIGN KEY (`RECIPE`) REFERENCES `model_recipe` (`MODEL_ID`) ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+
+