Merge "Add Kafka message lib consumer services"
authorDan Timoney <dtimoney@att.com>
Thu, 5 Sep 2019 18:54:33 +0000 (18:54 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 5 Sep 2019 18:54:33 +0000 (18:54 +0000)
15 files changed:
components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/data_types.json
components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/node_types.json
components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/resources_definition_types.json
components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/vFW_spinup.json
components/model-catalog/blueprint-model/uat-blueprints/echo/Tests/uat.yaml
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml
ms/blueprintsprocessor/functions/config-snapshots/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/ComponentConfigSnapshotsExecutor.kt
ms/blueprintsprocessor/functions/config-snapshots/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/db/ResourceConfigSnapshotService.kt
ms/blueprintsprocessor/functions/config-snapshots/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/ComponentConfigSnapshotsExecutorTest.kt
ms/blueprintsprocessor/functions/config-snapshots/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/db/ResourceConfigSnapshotServiceTest.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt
ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt
ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt

index 8c304c4..b710925 100644 (file)
@@ -1,3 +1,448 @@
 {
-  "data_types" : { }
+  "data_types" : {
+    "dt-resource-assignment-properties" : {
+      "description" : "Dynamic DataType definition for workflow(resource-assignment).",
+      "version" : "1.0.0",
+      "properties" : {
+        "nf-role" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "default" : "vSN",
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vm-type" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vnf-id" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "public_net_id" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "value" : "public_net_id",
+          "default" : "public_net_id",
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vnf_name" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vfw_private_ip_1" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "unprotected-prefix-id" : {
+          "description" : "",
+          "required" : false,
+          "type" : "integer",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "onap_private_subnet_id" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vfw_private_ip_0" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "aic-cloud-region" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "sec_group" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "default" : "onap_sg_PUhf",
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vfw_private_ip_2" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vnfc-model-invariant-uuid" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "nfc-naming-code" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "private-prefix-id" : {
+          "description" : "",
+          "required" : false,
+          "type" : "integer",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf-module-model-customization-uuid" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vfw_name_0" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf_module_name" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "nexus_artifact_repo" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "value" : "nexus_artifact_repo",
+          "default" : "nexus_artifact_repo",
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "onap_private_net_cidr" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "image_name" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf-nf-code" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf-module-id" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf-module-label" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vsn_private_ip_0" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vpg_name_0" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vpg_private_ip_1" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "protected_private_net_cidr" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf-naming-policy" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "default" : "SDNC_Policy.Config_MS_ONAP_VSN_NAMING_TIMESTAMP",
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vpg_private_ip_0" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vsn_private_ip_1" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vfccustomizationuuid" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "unprotected_private_net_cidr" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vsn_name_0" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "onap_private_net_id" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vnfc-model-version" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "service-instance-id" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vf-module-type" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vnf-model-customization-uuid" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "pub_key" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "key_name" : {
+          "description" : "",
+          "required" : false,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "protected-prefix-id" : {
+          "description" : "",
+          "required" : false,
+          "type" : "integer",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        },
+        "vnf-name" : {
+          "description" : "",
+          "required" : true,
+          "type" : "string",
+          "status" : "",
+          "constraints" : [ { } ],
+          "entry_schema" : {
+            "type" : ""
+          }
+        }
+      },
+      "derived_from" : "tosca.datatypes.Dynamic"
+    }
+  }
 }
\ No newline at end of file
index 599e377..e812db1 100644 (file)
                   "required" : false,
                   "type" : "string"
                 },
+                "occurrence" : {
+                  "description" : "Number of time to perform the resolution.",
+                  "required" : false,
+                  "type" : "integer",
+                  "default" : 1
+                },
                 "store-result" : {
                   "description" : "Whether or not to store the output.",
                   "required" : false,
       },
       "derived_from" : "tosca.nodes.ResourceSource"
     },
-    "source-default" : {
-      "description" : "This is Default Resource Source Node Type",
-      "version" : "1.0.0",
-      "properties" : { },
-      "derived_from" : "tosca.nodes.ResourceSource"
-    },
-    "source-input" : {
-      "description" : "This is Input Resource Source Node Type",
-      "version" : "1.0.0",
-      "properties" : { },
-      "derived_from" : "tosca.nodes.ResourceSource"
-    },
     "source-db" : {
       "description" : "This is Database Resource Source Node Type",
       "version" : "1.0.0",
           "type" : "string",
           "constraints" : [ {
             "valid_values" : [ "SQL", "PLSQL" ]
-          } ]
+          } ],
+          "default" : "SQL"
         },
         "endpoint-selector" : {
           "required" : false,
       },
       "derived_from" : "tosca.nodes.ResourceSource"
     },
+    "source-default" : {
+      "description" : "This is Default Resource Source Node Type",
+      "version" : "1.0.0",
+      "properties" : { },
+      "derived_from" : "tosca.nodes.ResourceSource"
+    },
+    "source-input" : {
+      "description" : "This is Input Resource Source Node Type",
+      "version" : "1.0.0",
+      "properties" : { },
+      "derived_from" : "tosca.nodes.ResourceSource"
+    },
     "source-rest" : {
       "description" : "This is Rest Resource Source Node Type",
       "version" : "1.0.0",
       "derived_from" : "tosca.nodes.Root"
     }
   }
-}
+}
\ No newline at end of file
index 1a62972..2406240 100644 (file)
       "description" : "nexus_artifact_repo",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
       "default" : {
         "type" : "source-default",
         "properties" : { }
       },
-      "input" : {
-        "type" : "source-input",
-        "properties" : { }
+      "sdnc" : {
+        "type" : "source-rest",
+        "properties" : {
+          "type" : "JSON",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nexus_artifact_repo",
+          "path" : "/param/0/value",
+          "input-key-mapping" : {
+            "service-instance-id" : "service-instance-id",
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "nexus_artifact_repo" : "value"
+          },
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+        }
       }
     }
   },
       "description" : "nfc-naming-code",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
           "query" : "select nfc_naming_code as nfc_naming_code from sdnctl.VFC_MODEL where customization_uuid=:vfccustomizationuuid",
           "input-key-mapping" : {
       "description" : "onap_private_net_cidr",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
+      "sdnc" : {
+        "type" : "source-rest",
+        "properties" : {
+          "type" : "JSON",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_cidr",
+          "path" : "/param/0/value",
+          "input-key-mapping" : {
+            "service-instance-id" : "service-instance-id",
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "onap_private_net_cidr" : "value"
+          },
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+        }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
-          "query" : "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private\"",
+          "query" : "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"management\"",
+          "input-key-mapping" : { },
           "output-key-mapping" : {
             "onap_private_net_cidr" : "prefix"
           }
       "description" : "onap_private_net_id",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
       "input" : {
         "type" : "source-input"
       },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "sdnc" : {
         "type" : "source-rest",
         "properties" : {
       "description" : "onap_private_subnet_id",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
       "input" : {
         "type" : "source-input"
       },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "sdnc" : {
         "type" : "source-rest",
         "properties" : {
       "description" : "private-prefix-id",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
           "query" : "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"private\"",
+          "input-key-mapping" : { },
           "output-key-mapping" : {
             "private-prefix-id" : "prefix_id"
           }
       "description" : "pub_key",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
       "input" : {
         "type" : "source-input"
       },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "sdnc" : {
         "type" : "source-rest",
         "properties" : {
       "description" : "public_net_id",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
       "default" : {
         "type" : "source-default",
         "properties" : { }
       },
-      "input" : {
-        "type" : "source-input"
+      "sdnc" : {
+        "type" : "source-rest",
+        "properties" : {
+          "type" : "JSON",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/public_net_id",
+          "path" : "/param/0/value",
+          "input-key-mapping" : {
+            "service-instance-id" : "service-instance-id",
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "public_net_id" : "value"
+          },
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+        }
       }
     }
   },
       "description" : "sec_group",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
       "default" : {
         "type" : "source-default",
         "properties" : { }
       },
-      "input" : {
-        "type" : "source-input",
-        "properties" : { }
+      "sdnc" : {
+        "type" : "source-rest",
+        "properties" : {
+          "type" : "JSON",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/sec_group",
+          "path" : "/param/0/value",
+          "input-key-mapping" : {
+            "service-instance-id" : "service-instance-id",
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "sec_group" : "value"
+          },
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+        }
       }
     }
   },
       "description" : "vf-module-label",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
       "description" : "vf-module-model-customization-uuid",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
       "input" : {
-        "type" : "source-input",
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
         "properties" : { }
       }
     }
     }
   },
   "vfccustomizationuuid" : {
-    "tags" : "vfccustomizationuuid, tosca.datatypes.Root, data_type",
+    "tags" : "vfccustomizationuuid",
     "name" : "vfccustomizationuuid",
     "property" : {
       "description" : "vfccustomizationuuid",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
           "query" : "select sdnctl.VF_MODULE_TO_VFC_MAPPING.vfc_customization_uuid as vnf_customid from sdnctl.VF_MODULE_TO_VFC_MAPPING where vm_count = 1 and sdnctl.VF_MODULE_TO_VFC_MAPPING.vf_module_customization_uuid=:vfmodulecustomizationuuid",
           "input-key-mapping" : {
       "description" : "vm-type",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
           "query" : "select VFC_MODEL.vm_type as vm_type from VFC_MODEL where customization_uuid=:vfccustomizationuuid",
           "input-key-mapping" : {
       "description" : "vnf-id",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
       "input" : {
-        "type" : "source-input",
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
         "properties" : { }
+      },
+      "sdnc" : {
+        "type" : "source-rest",
+        "properties" : {
+          "type" : "JSON",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-id",
+          "path" : "/param/0/value",
+          "input-key-mapping" : {
+            "service-instance-id" : "service-instance-id",
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "vnf-id" : "value"
+          },
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+        }
       }
     }
   },
     }
   },
   "vnf-name" : {
-    "tags" : "vnf-name, tosca.datatypes.Root, data_type",
+    "tags" : "vnf-name",
     "name" : "vnf-name",
     "property" : {
       "description" : "vnf-name",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "sdnc" : {
         "type" : "source-rest",
         "properties" : {
           "type" : "JSON",
-          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-name/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-name",
           "path" : "/param/0/value",
-          "expression-type" : "JSON_POINTER",
           "input-key-mapping" : {
             "service-instance-id" : "service-instance-id",
-            "vnf-id" : "vnf-id"
+            "vnf-name" : "vnf-name"
           },
           "output-key-mapping" : {
             "vnf-name" : "value"
           },
-          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
+          "key-dependencies" : [ "service-instance-id", "vnf-name" ]
+        }
+      },
+      "aai-data" : {
+        "type" : "source-rest",
+        "properties" : {
+          "type" : "JSON",
+          "verb" : "GET",
+          "url-path" : "/aai/v14/network/generic-vnfs/generic-vnf/$vnf-id",
+          "path" : "",
+          "input-key-mapping" : {
+            "vnf-id" : "vnf-id"
+          },
+          "output-key-mapping" : {
+            "vnf-name" : "vnf-name"
+          },
+          "key-dependencies" : [ "vnf-id" ]
         }
       }
     }
     "tags" : "vnfc-model-invariant-uuid",
     "name" : "vnfc-model-invariant-uuid",
     "property" : {
-      "description" : "vnfc-model-invariant-uuid for SRIOV VPE template",
+      "description" : "vnfc-model-invariant-uuid",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
           "query" : "select VFC_MODEL.invariant_uuid as vfc_invariant_uuid from VFC_MODEL where customization_uuid=:vfccustomizationuuid",
           "input-key-mapping" : {
     "tags" : "vnfc-model-version",
     "name" : "vnfc-model-version",
     "property" : {
-      "description" : "vnfc-model-version for  SRIOV VPE template",
+      "description" : "vnfc-model-version",
       "type" : "string"
     },
-    "updated-by" : "Singal, Kapil <ks220y@att.com>",
+    "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>",
     "sources" : {
+      "input" : {
+        "type" : "source-input"
+      },
+      "default" : {
+        "type" : "source-default",
+        "properties" : { }
+      },
       "processor-db" : {
         "type" : "source-db",
         "properties" : {
+          "endpoint-selector" : "dynamic-db-source",
           "type" : "SQL",
           "query" : "select VFC_MODEL.version as vnfc_model_version from VFC_MODEL where customization_uuid=:vfccustomizationuuid",
           "input-key-mapping" : {
       }
     }
   }
-}
+}
\ No newline at end of file
index a4d90ad..9ff4f3a 100644 (file)
@@ -1,19 +1,31 @@
 {
-  "metadata": {
-    "template_author": "Alexis de Talhouët",
-    "author-email": "adetalhouet89@gmail.com",
-    "user-groups": "ADMIN, OPERATION",
-    "template_name": "vFW_spinup",
-    "template_version": "1.0.0",
-    "template_tags": "vFW"
+  "tosca_definitions_version" : "controller_blueprint_1_0_0",
+  "metadata" : {
+    "template_author" : "Alexis de Talhouët",
+    "author-email" : "adetalhouet89@gmail.com",
+    "user-groups" : "ADMIN, OPERATION",
+    "template_name" : "vFW_spinup",
+    "template_version" : "1.0.0",
+    "template_tags" : "vFW"
   },
-  "topology_template": {
-    "workflows": {
-      "resource-assignment": {
-        "steps": {
-          "resource-assignment": {
-            "description": "Resource Assign Workflow",
-            "target": "resource-assignment"
+  "imports" : [ {
+    "file" : "Definitions/data_types.json"
+  }, {
+    "file" : "Definitions/relationship_types.json"
+  }, {
+    "file" : "Definitions/artifact_types.json"
+  }, {
+    "file" : "Definitions/node_types.json"
+  }, {
+    "file" : "Definitions/policy_types.json"
+  } ],
+  "topology_template" : {
+    "workflows" : {
+      "resource-assignment" : {
+        "steps" : {
+          "resource-assignment" : {
+            "description" : "Resource Assign Workflow",
+            "target" : "resource-assignment"
           }
         },
         "inputs" : {
             "entry_schema" : {
               "type" : "string"
             }
+          },
+          "resource-assignment-properties" : {
+            "description" : "Dynamic PropertyDefinition for workflow(resource-assignment).",
+            "required" : true,
+            "type" : "dt-resource-assignment-properties"
           }
         },
-        "outputs": {
-          "meshed-template": {
-            "type": "json",
-            "value": {
-              "get_attribute": [
-                "resource-assignment",
-                "assignment-params"
-              ]
+        "outputs" : {
+          "meshed-template" : {
+            "type" : "json",
+            "value" : {
+              "get_attribute" : [ "resource-assignment", "assignment-params" ]
             }
           }
         }
       }
     },
-    "node_templates": {
+    "node_templates" : {
       "resource-assignment" : {
         "type" : "component-resource-resolution",
         "interfaces" : {
             }
           }
         },
-        "artifacts": {
-          "base-template": {
-            "type": "artifact-template-velocity",
-            "file": "Templates/base-template.vtl"
+        "artifacts" : {
+          "base-template" : {
+            "type" : "artifact-template-velocity",
+            "file" : "Templates/base-template.vtl"
           },
-          "base-mapping": {
-            "type": "artifact-mapping-resource",
-            "file": "Templates/base-mapping.json"
+          "base-mapping" : {
+            "type" : "artifact-mapping-resource",
+            "file" : "Templates/base-mapping.json"
           },
-          "vfw-template": {
-            "type": "artifact-template-velocity",
-            "file": "Templates/vfw-template.vtl"
+          "vfw-template" : {
+            "type" : "artifact-template-velocity",
+            "file" : "Templates/vfw-template.vtl"
           },
-          "vfw-mapping": {
-            "type": "artifact-mapping-resource",
-            "file": "Templates/vfw-mapping.json"
+          "vfw-mapping" : {
+            "type" : "artifact-mapping-resource",
+            "file" : "Templates/vfw-mapping.json"
           },
-          "vfw-vnf-template": {
-            "type": "artifact-template-velocity",
-            "file": "Templates/vfw-vnf-template.vtl"
+          "vfw-vnf-template" : {
+            "type" : "artifact-template-velocity",
+            "file" : "Templates/vfw-vnf-template.vtl"
           },
-          "vfw-vnf-mapping": {
-            "type": "artifact-mapping-resource",
-            "file": "Templates/vfw-vnf-mapping.json"
+          "vfw-vnf-mapping" : {
+            "type" : "artifact-mapping-resource",
+            "file" : "Templates/vfw-vnf-mapping.json"
           },
-          "vpg-template": {
-            "type": "artifact-template-velocity",
-            "file": "Templates/vpg-template.vtl"
+          "vpg-template" : {
+            "type" : "artifact-template-velocity",
+            "file" : "Templates/vpg-template.vtl"
           },
-          "vpg-mapping": {
-            "type": "artifact-mapping-resource",
-            "file": "Templates/vpg-mapping.json"
+          "vpg-mapping" : {
+            "type" : "artifact-mapping-resource",
+            "file" : "Templates/vpg-mapping.json"
           },
-          "vsn-template": {
-            "type": "artifact-template-velocity",
-            "file": "Templates/vsn-template.vtl"
+          "vsn-template" : {
+            "type" : "artifact-template-velocity",
+            "file" : "Templates/vsn-template.vtl"
           },
-          "vsn-mapping": {
-            "type": "artifact-mapping-resource",
-            "file": "Templates/vsn-mapping.json"
+          "vsn-mapping" : {
+            "type" : "artifact-mapping-resource",
+            "file" : "Templates/vsn-mapping.json"
           }
         }
       }
index 1162309..5036a6f 100644 (file)
@@ -26,9 +26,3 @@ processes:
         message: success
       payload:
         echo-response: {}
-      stepData:
-        name: echo
-        properties:
-          resource-assignment-params:
-            echo: *message
-          status: success
index 3a5903c..fbdb2ee 100644 (file)
@@ -31,32 +31,6 @@ processes:
         message: success
       payload:
         config-assign-response: {}
-      stepData:
-        name: config-assign
-        properties:
-          resource-assignment-params:
-            config-assign: &assignPatch
-              ietf-restconf:yang-patch:
-                patch-id: patch-1
-                edit:
-                  - edit-id: edit1
-                    operation: merge
-                    target: /
-                    value: { netconflist: { netconf: [ { netconf-id: "10", netconf-param: "1000" }]}}
-                  - edit-id: edit2
-                    operation: merge
-                    target: /
-                    value: { netconflist: { netconf: [ { netconf-id: "20", netconf-param: "2000" }]}}
-                  - edit-id: edit3
-                    operation: merge
-                    target: /
-                    value: { netconflist: { netconf: [ { netconf-id: "30", netconf-param: "3000" }]}}
-          status: success
-    responseNormalizerSpec:
-      stepData:
-        properties:
-          resource-assignment-params:
-            config-assign: ?from-json(.stepData.properties.resource-assignment-params.config-assign)
   - name: config-deploy
     request:
       commonHeader: *commonHeader
@@ -84,11 +58,6 @@ processes:
         errorMessage: null
         eventType: EVENT_COMPONENT_EXECUTED
         message: success
-      stepData:
-        name: config-deploy
-        properties:
-          response-data: ""
-          status: success
 
 external-services:
   - selector: sdncodl
@@ -127,7 +96,22 @@ external-services:
           path: [*configUri, *configletResourcePath]
           headers:
             Content-Type: application/yang.patch+json
-          body: *assignPatch
+          body:
+            ietf-restconf:yang-patch:
+              patch-id: patch-1
+              edit:
+                - edit-id: edit1
+                  operation: merge
+                  target: /
+                  value: { netconflist: { netconf: [ { netconf-id: "10", netconf-param: "1000" }]}}
+                - edit-id: edit2
+                  operation: merge
+                  target: /
+                  value: { netconflist: { netconf: [ { netconf-id: "20", netconf-param: "2000" }]}}
+                - edit-id: edit3
+                  operation: merge
+                  target: /
+                  value: { netconflist: { netconf: [ { netconf-id: "30", netconf-param: "3000" }]}}
       - request:
           method: DELETE
           path: *configUri
index eafcaf4..180ad7b 100644 (file)
  *  limitations under the License.
  */
 
-package org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots
 
 import com.github.fge.jsonpatch.diff.JsonDiff
+import org.apache.logging.log4j.util.Strings
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot.Status.RUNNING
@@ -144,18 +145,20 @@ open class ComponentConfigSnapshotsExecutor(private val cfgSnapshotService: Reso
      */
     private suspend fun compareConfigurationSnapshot(resourceId: String, resourceType: String, contentType : String) {
 
+        val cfgRunning = cfgSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, RUNNING)
+        val cfgCandidate = cfgSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, CANDIDATE)
+
+        if (cfgRunning.isEmpty() || cfgCandidate.isEmpty()) {
+            setNodeOutputProperties(OUTPUT_STATUS_SUCCESS, Strings.EMPTY)
+            return
+        }
+
         when (contentType.toUpperCase()) {
             DIFF_JSON -> {
-                val cfgRunning = cfgSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, RUNNING)
-                val cfgCandidate = cfgSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, CANDIDATE)
-
                 val patchNode = JsonDiff.asJson(cfgRunning.jsonAsJsonType(), cfgCandidate.jsonAsJsonType())
                 setNodeOutputProperties(OUTPUT_STATUS_SUCCESS, patchNode.toString())
             }
             DIFF_XML -> {
-                val cfgRunning = cfgSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, RUNNING)
-                val cfgCandidate = cfgSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, CANDIDATE)
-
                 val myDiff = DiffBuilder
                         .compare(Input.fromString(cfgRunning))
                         .withTest(Input.fromString(cfgCandidate))
index 50c90f3..5fcba5b 100644 (file)
@@ -17,6 +17,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db
 
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
+import org.apache.logging.log4j.util.Strings
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot.Status.RUNNING
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
 import org.slf4j.LoggerFactory
@@ -40,7 +41,7 @@ class ResourceConfigSnapshotService(private val repository: ResourceConfigSnapsh
                                                          status : ResourceConfigSnapshot.Status = RUNNING): String =
             withContext(Dispatchers.IO) {
                 repository.findByResourceIdAndResourceTypeAndStatus(resourceId, resourceType, status)
-                        ?.config_snapshot ?: throw NoSuchElementException()
+                        ?.config_snapshot ?: Strings.EMPTY
             }
 
     suspend fun write(snapshot: String, resId: String, resType: String,
index 79dd930..c212908 100644 (file)
@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots
 
 import com.fasterxml.jackson.databind.JsonNode
 import kotlinx.coroutines.runBlocking
@@ -27,11 +27,12 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration
-import org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor.ComponentConfigSnapshotsExecutor.Companion.DIFF_JSON
-import org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor.ComponentConfigSnapshotsExecutor.Companion.DIFF_XML
-import org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor.ComponentConfigSnapshotsExecutor.Companion.OPERATION_DIFF
-import org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor.ComponentConfigSnapshotsExecutor.Companion.OPERATION_FETCH
-import org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor.ComponentConfigSnapshotsExecutor.Companion.OPERATION_STORE
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.DIFF_JSON
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.DIFF_XML
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.OPERATION_DIFF
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.OPERATION_FETCH
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.OPERATION_STORE
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshotService
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
@@ -192,9 +193,7 @@ class ComponentConfigSnapshotsExecutorTest {
                 return@runBlocking
             }
 
-            // then; we should get error and the PAYLOAD payload in our output properties
-            assertTrue( bluePrintRuntimeService.getBluePrintError().errors.size > 0 )
-            assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_ERROR.asJsonPrimitive(),
+            assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
         }
@@ -234,7 +233,10 @@ class ComponentConfigSnapshotsExecutorTest {
         runBlocking {
             // when; asking for unknown content type diff operation; should get an error response
             try {
-                prepareRequestProperties(OPERATION_DIFF, "asdasd",  "PNF", "YANG")
+                val resId = "121111"
+                val resType = "PNF"
+                cfgSnapshotService.write("snapshotConfig", resId, resType,  ResourceConfigSnapshot.Status.CANDIDATE)
+                prepareRequestProperties(OPERATION_DIFF, resId,  resType, "YANG")
 
                 cfgSnapshotComponent.processNB(executionRequest)
 
@@ -245,7 +247,6 @@ class ComponentConfigSnapshotsExecutorTest {
             }
 
             // then; we should get error in our output properties
-            assertTrue( bluePrintRuntimeService.getBluePrintError().errors.size == 1 )
             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_ERROR.asJsonPrimitive(),
                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
index 2830cb5..3c989c1 100644 (file)
@@ -48,18 +48,6 @@ class ResourceConfigSnapshotServiceTest {
         }
     }
 
-    @Test(expected = NoSuchElementException::class)
-    fun notFoundEntryReturnsExceptionTest() {
-        val tr = ResourceConfigSnapshot()
-        runBlocking {
-            every {
-                cfgRepository.findByResourceIdAndResourceTypeAndStatus(any(), any(), any())
-            } returns tr
-            val snap = cfgService.findByResourceIdAndResourceTypeAndStatus("MISSING_ID", "UNKNOWN_TYPE")
-            assertTrue ( snap.isBlank(), "Not found but returned a non empty string" )
-        }
-    }
-
     @Test
     fun createNewResourceConfigSnapshotTest() {
         val tr = ResourceConfigSnapshot()
index 2a9218d..7696442 100644 (file)
@@ -29,5 +29,4 @@ object ResourceResolutionConstants {
         const val RESOURCE_RESOLUTION_INPUT_OCCURRENCE = "occurrence"
         const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id"
         const val RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE = "resource-type"
-        val DATA_DICTIONARY_SECRET_SOURCE_TYPES = arrayOf("vault-data") //Add more secret data dictionary source type here
 }
\ No newline at end of file
index 01cfd72..117df1e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright Â© 2017-2018 AT&T Intellectual Property.
- * Modifications Copyright Â© 2019 IBM.
+ * Modifications Copyright (c) 2019 IBM, Bell Canada.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.uti
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.databind.node.ArrayNode
+import com.fasterxml.jackson.databind.node.NullNode
 import com.fasterxml.jackson.databind.node.ObjectNode
 import com.fasterxml.jackson.databind.node.TextNode
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
@@ -194,85 +195,214 @@ class ResourceAssignmentUtils {
         @Throws(BluePrintProcessorException::class)
         fun parseResponseNode(responseNode: JsonNode, resourceAssignment: ResourceAssignment,
                               raRuntimeService: ResourceAssignmentRuntimeService, outputKeyMapping: MutableMap<String, String>): JsonNode {
+            try {
+                if ((resourceAssignment.property?.type).isNullOrEmpty()) {
+                    throw BluePrintProcessorException("Couldn't get data dictionary type for dictionary name (${resourceAssignment.name})")
+                }
+                val type = resourceAssignment.property!!.type
+                return when (type) {
+                    in BluePrintTypes.validPrimitiveTypes() -> {
+                        parseResponseNodeForPrimitiveTypes(responseNode, resourceAssignment, outputKeyMapping)
+                    }
+                    in BluePrintTypes.validCollectionTypes() -> {
+                        // Array Types
+                        parseResponseNodeForCollection(responseNode, resourceAssignment, raRuntimeService, outputKeyMapping)
+                    }
+                    else -> {
+                        // Complex Types
+                        parseResponseNodeForComplexType(responseNode, resourceAssignment, raRuntimeService, outputKeyMapping)
+                    }
+                }
+            } catch (e: Exception) {
+                logger.error("Fail to parse response data, error message $e")
+                throw BluePrintProcessorException("${e.message}", e)
+            }
+        }
+
+        private fun parseResponseNodeForPrimitiveTypes(responseNode: JsonNode, resourceAssignment: ResourceAssignment,
+                                                       outputKeyMapping: MutableMap<String, String>): JsonNode {
             val dName = resourceAssignment.dictionaryName
-            val dSource = resourceAssignment.dictionarySource
-            val type = nullToEmpty(resourceAssignment.property?.type)
-            lateinit var entrySchemaType: String
-            when (type) {
-                in BluePrintTypes.validPrimitiveTypes() -> {
-                    if (dSource !in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES)
-                        logger.info("For template key (${resourceAssignment.name}) setting value as ($responseNode)")
-                    val result = if (responseNode is ArrayNode)
-                        responseNode.get(0)
-                    else
-                        responseNode
-                    return if (result.isComplexType()) {
-                        check(result.has(outputKeyMapping[dName])) {
-                            "Fail to find output key mapping ($dName) in result."
+            logger.info("For template key (${resourceAssignment.name}) setting value as ($responseNode)")
+
+            var result: JsonNode? = responseNode
+            if (responseNode.isComplexType()) {
+                val key = outputKeyMapping.keys.firstOrNull()
+                var returnNode: JsonNode? = responseNode
+                if (responseNode is ArrayNode) {
+                    val arrayNode = responseNode.toList()
+                    val firstElement = if (key.isNullOrEmpty()) {
+                        arrayNode.first()
+                    }
+                    else{
+                        arrayNode.firstOrNull { element ->
+                            element.isComplexType() && element.has(outputKeyMapping[key])
+                        }
+                    }
+
+                    if (firstElement.isNull() || (firstElement!!.isComplexType() && !firstElement!!.has(outputKeyMapping[key]))
+                            || (!result!!.isComplexType() && result is NullNode)) {
+                        if (key.isNullOrEmpty()) {
+                            throw BluePrintProcessorException("Fail to find mapping in the responseNode.")
+                        }
+                        else {
+                            throw BluePrintProcessorException("Fail to find response with output key mapping ($key) in result.")
                         }
-                        result[outputKeyMapping[dName]]
-                    } else {
-                        result
                     }
+                    returnNode = firstElement
                 }
-                in BluePrintTypes.validCollectionTypes() -> {
-                    // Array Types
-                    entrySchemaType = checkNotEmpty(resourceAssignment.property?.entrySchema?.type) {
-                        "Entry schema is not defined for dictionary ($dName) info"
+                result = if (returnNode!!.isComplexType()) {
+                    returnNode[outputKeyMapping[key]]
+                }
+                else {
+                    returnNode
+                }
+            }
+            return result!!
+        }
+
+        private fun parseResponseNodeForCollection(responseNode: JsonNode, resourceAssignment: ResourceAssignment,
+                                                   raRuntimeService: ResourceAssignmentRuntimeService,
+                                                   outputKeyMapping: MutableMap<String, String>): JsonNode {
+            val dName = resourceAssignment.dictionaryName
+            if ((resourceAssignment.property?.entrySchema?.type).isNullOrEmpty()) {
+                throw BluePrintProcessorException("Couldn't get data type for dictionary type " +
+                        "(${resourceAssignment.property!!.type}) and dictionary name ($dName)")
+            }
+            val entrySchemaType = resourceAssignment.property!!.entrySchema!!.type
+
+            var arrayNode = JacksonUtils.objectMapper.createArrayNode()
+
+            if (outputKeyMapping.isNotEmpty()) {
+                when (responseNode) {
+                    is ArrayNode -> {
+                        val responseArrayNode = responseNode.toList()
+                        for (responseSingleJsonNode in responseArrayNode) {
+                            val arrayChildNode = parseArrayNodeElementWithOutputKeyMapping(raRuntimeService, responseSingleJsonNode,
+                                    outputKeyMapping, entrySchemaType)
+                            arrayNode.add(arrayChildNode)
+                        }
                     }
-                    val arrayNode = JacksonUtils.objectMapper.createArrayNode()
-                    lateinit var responseValueNode: JsonNode
-                    lateinit var propertyType: String
-                    outputKeyMapping.map {
-                        val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
+                    is ObjectNode -> {
                         val responseArrayNode = responseNode.rootFieldsToMap()
-                        outer@ for ((key, responseSingleJsonNode) in responseArrayNode) {
-                            if (key == it.key) {
-                                if (entrySchemaType in BluePrintTypes.validPrimitiveTypes()) {
-                                    responseValueNode = responseSingleJsonNode
-                                    propertyType = entrySchemaType
-
-                                } else {
-                                    responseValueNode = responseSingleJsonNode.get(it.key)
-                                    propertyType = getPropertyType(raRuntimeService, entrySchemaType, it.key)
-                                }
-                                if (resourceAssignment.dictionarySource !in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES)
-                                    logger.info("For List Type Resource: key (${it.key}), value ($responseValueNode), " +
-                                            "type  ({$propertyType})")
-                                JacksonUtils.populateJsonNodeValues(it.value,
-                                        responseValueNode, propertyType, arrayChildNode)
-                                arrayNode.add(arrayChildNode)
-                                break@outer
-                            }
-                        }
+                        val arrayNodeResult = parseObjectNodeWithOutputKeyMapping(responseArrayNode, outputKeyMapping, entrySchemaType)
+                        arrayNode.addAll(arrayNodeResult)
+                    }
+                    else -> {
+                        throw BluePrintProcessorException("Key-value response expected to match the responseNode.")
                     }
-                    if (resourceAssignment.dictionarySource !in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES)
-                        logger.info("For template key (${resourceAssignment.name}) setting value as ($arrayNode)")
-
-                    return arrayNode
                 }
-                else -> {
-                    // Complex Types
-                    entrySchemaType = checkNotEmpty(resourceAssignment.property?.type) {
-                        "Entry schema is not defined for dictionary ($dName) info"
+            }
+            else {
+                when (responseNode) {
+                    is ArrayNode -> {
+                        responseNode.forEach { elementNode ->
+                            arrayNode.add(elementNode)
+                        }
                     }
-                    val objectNode = JacksonUtils.objectMapper.createObjectNode()
+                    is ObjectNode -> {
+                        val responseArrayNode = responseNode.rootFieldsToMap()
+                        for ((key, responseSingleJsonNode) in responseArrayNode) {
+                            val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
+                            JacksonUtils.populateJsonNodeValues(key, responseSingleJsonNode, entrySchemaType, arrayChildNode)
+                            arrayNode.add(arrayChildNode)
+                        }
+                    }
+                    else -> {
+                        arrayNode.add(responseNode)
+                    }
+                }
+            }
+
+            logger.info("For template key (${resourceAssignment.name}) setting value as ($arrayNode)")
+
+            return arrayNode
+        }
+
+        private fun parseResponseNodeForComplexType(responseNode: JsonNode, resourceAssignment: ResourceAssignment,
+                                                    raRuntimeService: ResourceAssignmentRuntimeService,
+                                                    outputKeyMapping: MutableMap<String, String>): JsonNode {
+            val entrySchemaType = resourceAssignment.property!!.type
+            val dictionaryName = resourceAssignment.dictionaryName!!
+
+            var result: ObjectNode
+            if (checkOutputKeyMappingInDataTypeProperties(entrySchemaType, outputKeyMapping, raRuntimeService))
+            {
+                result = parseArrayNodeElementWithOutputKeyMapping(raRuntimeService, responseNode, outputKeyMapping, entrySchemaType)
+            }
+            else {
+                val childNode = JacksonUtils.objectMapper.createObjectNode()
+                if (outputKeyMapping.isNotEmpty()) {
                     outputKeyMapping.map {
-                        val responseKeyValue = responseNode.get(it.key)
-                        val propertyTypeForDataType = ResourceAssignmentUtils
-                                .getPropertyType(raRuntimeService, entrySchemaType, it.key)
+                        val responseKeyValue = if (responseNode.has(it.key)) {
+                            responseNode.get(it.key)
+                        }
+                        else {
+                            NullNode.getInstance()
+                        }
 
-                        if (resourceAssignment.dictionarySource !in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES)
-                            logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), type  ({$propertyTypeForDataType})")
-                        JacksonUtils.populateJsonNodeValues(it.value, responseKeyValue, propertyTypeForDataType, objectNode)
+                        JacksonUtils.populateJsonNodeValues(it.value,
+                                responseKeyValue, entrySchemaType, childNode)
                     }
+                }
+                else {
+                    JacksonUtils.populateJsonNodeValues(dictionaryName, responseNode, entrySchemaType, childNode)
+                }
+                result = childNode
+            }
+            return result
+        }
+
+        private fun parseArrayNodeElementWithOutputKeyMapping(raRuntimeService: ResourceAssignmentRuntimeService,
+                                                              responseSingleJsonNode: JsonNode, outputKeyMapping:
+                                                              MutableMap<String, String>, entrySchemaType: String): ObjectNode {
+            val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
+
+            outputKeyMapping.map {
+                val responseKeyValue = if (responseSingleJsonNode.has(it.key)) {
+                    responseSingleJsonNode.get(it.key)
+                }
+                else {
+                    NullNode.getInstance()
+                }
+                val propertyTypeForDataType = ResourceAssignmentUtils
+                        .getPropertyType(raRuntimeService, entrySchemaType, it.key)
+
+                logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), " +
+                        "type  ({$propertyTypeForDataType})")
 
-                    if (resourceAssignment.dictionarySource !in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES)
-                        logger.info("For template key (${resourceAssignment.name}) setting value as ($objectNode)")
+                JacksonUtils.populateJsonNodeValues(it.value,
+                        responseKeyValue, propertyTypeForDataType, arrayChildNode)
+            }
+
+            return arrayChildNode
+        }
+
+        private fun parseObjectNodeWithOutputKeyMapping(responseArrayNode: MutableMap<String, JsonNode>,
+                                                        outputKeyMapping: MutableMap<String, String>,
+                                                        entrySchemaType: String): ArrayNode {
+            val arrayNode = JacksonUtils.objectMapper.createArrayNode()
+            outputKeyMapping.map {
+                val objectNode = JacksonUtils.objectMapper.createObjectNode()
+                val responseSingleJsonNode = responseArrayNode.filterKeys { key -> key == it.key }.entries.firstOrNull()
 
-                    return objectNode
+                if (responseSingleJsonNode == null) {
+                    JacksonUtils.populateJsonNodeValues(it.value, NullNode.getInstance(), entrySchemaType, objectNode)
                 }
+                else
+                {
+                    JacksonUtils.populateJsonNodeValues(it.value, responseSingleJsonNode.value, entrySchemaType, objectNode)
+                }
+                arrayNode.add(objectNode)
             }
+
+            return arrayNode
+        }
+
+        private fun checkOutputKeyMappingInDataTypeProperties(dataTypeName: String, outputKeyMapping: MutableMap<String, String>,
+                                                              raRuntimeService: ResourceAssignmentRuntimeService): Boolean {
+            val dataTypeProps = raRuntimeService.bluePrintContext().dataTypeByName(dataTypeName)?.properties
+            val result = outputKeyMapping.filterKeys { !dataTypeProps!!.containsKey(it) }.keys.firstOrNull()
+            return result == null
         }
     }
 }
\ No newline at end of file
index 9b87c12..9365c3e 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (c) 2019 IBM, Bell Canada.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * ============LICENSE_END=========================================================
  */
 
-
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils
 
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.node.NullNode
 import com.fasterxml.jackson.databind.node.TextNode
+import io.mockk.every
+import io.mockk.spyk
+import org.junit.Before
 import org.junit.Test
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.EntrySchema
 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import kotlin.test.assertEquals
 
+data class IpAddress(val port: String, val ip: String)
+data class Host(val name: String, val ipAddress: IpAddress)
+data class ExpectedResponseIp(val ip: String)
+data class ExpectedResponsePort(val port: String)
+
 class ResourceAssignmentUtilsTest {
+    private lateinit var resourceAssignmentRuntimeService: ResourceAssignmentRuntimeService
+
+    @Before
+    fun setup() {
+
+        val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext(
+                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+
+        resourceAssignmentRuntimeService = spyk(ResourceAssignmentRuntimeService("1234", bluePrintContext))
+
+        val propertiesDefinition1 = PropertyDefinition().apply {
+            type = "string"
+            id = "port"
+        }
+
+        val propertiesDefinition2 = PropertyDefinition().apply {
+            type = "string"
+            id = "ip"
+        }
+
+        val propertiesDefinition3 = PropertyDefinition().apply {
+            type = "string"
+            id = "name"
+        }
+
+        val propertiesDefinition4 = PropertyDefinition().apply {
+            type = "ip-address"
+            id = "ipAddress"
+        }
+
+        var mapOfPropertiesIpAddress = mutableMapOf<String, PropertyDefinition>()
+        mapOfPropertiesIpAddress["port"] = propertiesDefinition1
+        mapOfPropertiesIpAddress["ip"] = propertiesDefinition2
+
+        var mapOfPropertiesHost = mutableMapOf<String, PropertyDefinition>()
+        mapOfPropertiesHost["name"] = propertiesDefinition3
+        mapOfPropertiesHost["ipAddress"] = propertiesDefinition4
+
+        val myDataTypeIpaddress = DataType().apply {
+            id = "ip-address"
+            properties = mapOfPropertiesIpAddress
+        }
+
+        val myDataTypeHost = DataType().apply {
+            id = "host"
+            properties = mapOfPropertiesHost
+        }
+
+        every { resourceAssignmentRuntimeService.bluePrintContext().dataTypeByName("ip-address") } returns myDataTypeIpaddress
+
+        every { resourceAssignmentRuntimeService.bluePrintContext().dataTypeByName("host") } returns myDataTypeHost
+
+        every { resourceAssignmentRuntimeService.setNodeTemplateAttributeValue(any(), any(), any()) } returns Unit
+    }
 
     @Test
     fun `generateResourceDataForAssignments - positive test`() {
@@ -43,7 +114,6 @@ class ResourceAssignmentUtilsTest {
         //then the assignment should produce a valid result
         val expected = "{\n" + "  \"pnf-id\" : \"valid_value\"\n" + "}"
         assertEquals(expected, outcome, "unexpected outcome generated")
-
     }
 
     @Test
@@ -76,4 +146,243 @@ class ResourceAssignmentUtilsTest {
         }
         return resourceAssignmentForTest
     }
+
+    @Test
+    fun parseResponseNodeTestForPrimitivesTypes(){
+        // Input values for primitive type
+        val keyValue = mutableMapOf<String, String>()
+        keyValue["value"]= "1.2.3.1"
+        val expectedPrimitiveType = TextNode("1.2.3.1")
+
+        var outcome = prepareResponseNodeForTest("sample-value", "string",
+                "", "1.2.3.1".asJsonPrimitive())
+        assertEquals(expectedPrimitiveType, outcome, "Unexpected outcome returned for primitive type of simple String")
+        outcome = prepareResponseNodeForTest("sample-key-value", "string", "", keyValue)
+        assertEquals(expectedPrimitiveType, outcome, "Unexpected outcome returned for primitive type of key-value String")
+    }
+
+    @Test
+    fun parseResponseNodeTestForCollectionsOfString(){
+        // Input values for collection type
+        val mapOfString = mutableMapOf<String, String>()
+        mapOfString["value1"] = "1.2.3.1"
+        mapOfString["port"] = "8888"
+        mapOfString["value2"] = "1.2.3.2"
+        val arrayOfKeyValue = arrayListOf(ExpectedResponseIp("1.2.3.1"),
+                ExpectedResponsePort( "8888"), ExpectedResponseIp("1.2.3.2"))
+
+        val mutableMapKeyValue = mutableMapOf<String, String>()
+        mutableMapKeyValue["value1"] = "1.2.3.1"
+        mutableMapKeyValue["port"] = "8888"
+
+        //List
+        val expectedListOfString = arrayOfKeyValue.asJsonType()
+        var outcome = prepareResponseNodeForTest("listOfString", "list",
+                "string", mapOfString.asJsonType())
+        assertEquals(expectedListOfString, outcome, "unexpected outcome returned for list of String")
+
+        //Map
+        val expectedMapOfString = mutableMapOf<String, JsonNode>()
+        expectedMapOfString["ip"] = "1.2.3.1".asJsonPrimitive()
+        expectedMapOfString["port"] = "8888".asJsonPrimitive()
+
+        val arrayNode = JacksonUtils.objectMapper.createArrayNode()
+        expectedMapOfString.map {
+            val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
+            arrayChildNode.set(it.key, it.value)
+            arrayNode.add(arrayChildNode)
+        }
+        val arrayChildNode1 = JacksonUtils.objectMapper.createObjectNode()
+        arrayChildNode1.set("ip", NullNode.getInstance())
+        arrayNode.add(arrayChildNode1)
+        outcome = prepareResponseNodeForTest("mapOfString", "map", "string",
+                mutableMapKeyValue.asJsonType())
+        assertEquals(arrayNode, outcome, "unexpected outcome returned for map of String")
+    }
+
+    @Test
+    fun parseResponseNodeTestForCollectionsOfJsonNode(){
+        // Input values for collection type
+        val mapOfString = mutableMapOf<String, JsonNode>()
+        mapOfString["value1"] = "1.2.3.1".asJsonPrimitive()
+        mapOfString["port"] = "8888".asJsonPrimitive()
+        mapOfString["value2"] = "1.2.3.2".asJsonPrimitive()
+        val arrayOfKeyValue = arrayListOf(ExpectedResponseIp("1.2.3.1"),
+                ExpectedResponsePort( "8888"), ExpectedResponseIp("1.2.3.2"))
+
+        val mutableMapKeyValue = mutableMapOf<String, JsonNode>()
+        mutableMapKeyValue["value1"] = "1.2.3.1".asJsonPrimitive()
+        mutableMapKeyValue["port"] = "8888".asJsonPrimitive()
+
+        //List
+        val expectedListOfString = arrayOfKeyValue.asJsonType()
+        var outcome = prepareResponseNodeForTest("listOfString", "list",
+                "string", mapOfString.asJsonType())
+        assertEquals(expectedListOfString, outcome, "unexpected outcome returned for list of String")
+
+        //Map
+        val expectedMapOfString = mutableMapOf<String, JsonNode>()
+        expectedMapOfString["ip"] = "1.2.3.1".asJsonPrimitive()
+        expectedMapOfString["port"] = "8888".asJsonPrimitive()
+        val arrayNode = JacksonUtils.objectMapper.createArrayNode()
+        expectedMapOfString.map {
+            val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
+            arrayChildNode.set(it.key, it.value)
+            arrayNode.add(arrayChildNode)
+        }
+        val arrayChildNode1 = JacksonUtils.objectMapper.createObjectNode()
+        arrayChildNode1.set("ip", NullNode.getInstance())
+        arrayNode.add(arrayChildNode1)
+        outcome = prepareResponseNodeForTest("mapOfString", "map",
+                "string", mutableMapKeyValue.asJsonType())
+        assertEquals(arrayNode, outcome, "unexpected outcome returned for map of String")
+    }
+
+    @Test
+    fun parseResponseNodeTestForCollectionsOfComplexType(){
+        // Input values for collection type
+        val mapOfComplexType = mutableMapOf<String, JsonNode>()
+        mapOfComplexType["value1"] = IpAddress("1111", "1.2.3.1").asJsonType()
+        mapOfComplexType["value2"] = IpAddress("2222", "1.2.3.2").asJsonType()
+        mapOfComplexType["value3"] = IpAddress("3333", "1.2.3.3").asJsonType()
+
+        //List
+        val arrayNode = JacksonUtils.objectMapper.createArrayNode()
+        mapOfComplexType.map {
+            val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
+            arrayChildNode.set("ipAddress", it.value)
+            arrayNode.add(arrayChildNode)
+        }
+        var outcome = prepareResponseNodeForTest("listOfMyDataType", "list",
+                "ip-address", mapOfComplexType.asJsonType())
+        assertEquals(arrayNode, outcome, "unexpected outcome returned for list of String")
+    }
+
+    @Test
+    fun `parseResponseNodeTestForComplexType find one output key mapping`(){
+        // Input values for complex type
+        val objectNode = JacksonUtils.objectMapper.createObjectNode()
+
+        // Input values for collection type
+        val mapOfComplexType = mutableMapOf<String, JsonNode>()
+        mapOfComplexType["value"] = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType()
+        mapOfComplexType["port"] = "8888".asJsonType()
+        mapOfComplexType["something"] = "1.2.3.2".asJsonType()
+
+        val expectedComplexType = objectNode.set("ipAddress", Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType())
+        val outcome = prepareResponseNodeForTest("complexTypeOneKeys", "host",
+                "", mapOfComplexType.asJsonType())
+        assertEquals(expectedComplexType, outcome, "Unexpected outcome returned for complex type")
+    }
+
+    @Test
+    fun `parseResponseNodeTestForComplexType find all output key mapping`(){
+        // Input values for complex type
+        val objectNode = JacksonUtils.objectMapper.createObjectNode()
+
+        // Input values for collection type
+        val mapOfComplexType = mutableMapOf<String, JsonNode>()
+        mapOfComplexType["name"] = "my-ipAddress".asJsonType()
+        mapOfComplexType["ipAddress"] = IpAddress("1111", "1.2.3.1").asJsonType()
+
+        val expectedComplexType = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType()
+        val outcome = prepareResponseNodeForTest("complexTypeAllKeys", "host",
+                "", mapOfComplexType.asJsonType())
+        assertEquals(expectedComplexType, outcome, "Unexpected outcome returned for complex type")
+    }
+
+    private fun prepareResponseNodeForTest(dictionary_source: String, sourceType: String, entrySchema: String,
+                                           response: Any): JsonNode {
+
+        val resourceAssignment = when (sourceType) {
+            "list", "map" -> {
+                prepareRADataDictionaryCollection(dictionary_source, sourceType, entrySchema)
+            }
+            "string" -> {
+                prepareRADataDictionaryOfPrimaryType(dictionary_source)
+            }
+            else -> {
+                prepareRADataDictionaryComplexType(dictionary_source, sourceType, entrySchema)
+            }
+        }
+
+        val responseNode = checkNotNull(JacksonUtils.getJsonNode(response)) {
+            "Failed to get database query result into Json node."
+        }
+
+        val outputKeyMapping = prepareOutputKeyMapping(dictionary_source)
+
+        return ResourceAssignmentUtils.parseResponseNode(responseNode, resourceAssignment, resourceAssignmentRuntimeService, outputKeyMapping)
+    }
+
+    private fun prepareRADataDictionaryOfPrimaryType(dictionary_source: String): ResourceAssignment {
+        return ResourceAssignment().apply {
+            name = "ipAddress"
+            dictionaryName = "sample-ip"
+            dictionarySource = "$dictionary_source"
+            property = PropertyDefinition().apply {
+                type = "string"
+            }
+        }
+    }
+
+    private fun prepareRADataDictionaryCollection(dictionary_source: String, sourceType: String, schema: String): ResourceAssignment {
+        return ResourceAssignment().apply {
+            name = "ipAddress-list"
+            dictionaryName = "sample-licenses"
+            dictionarySource = "$dictionary_source"
+            property = PropertyDefinition().apply {
+                type = "$sourceType"
+                entrySchema = EntrySchema().apply {
+                    type = "$schema"
+                }
+            }
+        }
+    }
+
+    private fun prepareRADataDictionaryComplexType(dictionary_source: String, sourceType: String, schema: String): ResourceAssignment {
+        return ResourceAssignment().apply {
+            name = "ipAddress-complexType"
+            dictionaryName = "sample-licenses"
+            dictionarySource = "$dictionary_source"
+            property = PropertyDefinition().apply {
+                type = "$sourceType"
+            }
+        }
+    }
+
+    private fun prepareOutputKeyMapping(dictionary_source: String): MutableMap<String, String> {
+        val outputMapping = mutableMapOf<String, String>()
+
+        when (dictionary_source) {
+            "listOfString", "mapOfString" -> {
+                //List of string
+                outputMapping["value1"] = "ip"
+                outputMapping["port"] = "port"
+                outputMapping["value2"] = "ip"
+            }
+            "listOfMyDataType", "mapOfMyDataType" -> {
+                //List or map of complex Type
+                outputMapping["value1"] = "ipAddress"
+                outputMapping["value2"] = "ipAddress"
+                outputMapping["value3"] = "ipAddress"
+            }
+            "sample-key-value", "sample-value" -> {
+                //Primary Type
+                if (dictionary_source=="sample-key-value")
+                    outputMapping["sample-ip"] = "value"
+            }
+            else -> {
+                //Complex Type
+                if (dictionary_source == "complexTypeOneKeys")
+                    outputMapping["value"] = "ipAddress"
+                else {
+                    outputMapping["name"] = "name"
+                    outputMapping["ipAddress"] = "ipAddress"
+                }
+
+            }
+        }
+        return outputMapping
+    }
 }
\ No newline at end of file
index c45ebc1..5a6ba06 100644 (file)
@@ -18,6 +18,7 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.core.api.data
 
 import com.fasterxml.jackson.annotation.JsonFormat
+import com.fasterxml.jackson.annotation.JsonIgnore
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.node.ObjectNode
 import io.swagger.annotations.ApiModelProperty
@@ -40,6 +41,7 @@ open class ExecutionServiceInput {
                 " and the input for resource resolution located within the xxx-request block, contained within xxx-properties")
     lateinit var payload: ObjectNode
     @get:ApiModelProperty(hidden = true)
+    @get:JsonIgnore
     var stepData: StepData? = null
 }
 
@@ -56,6 +58,7 @@ open class ExecutionServiceOutput {
                 " and the input for resource resolution located within the xxx-request block, contained within xxx-properties")
     lateinit var payload: ObjectNode
     @get:ApiModelProperty(hidden = true)
+    @get:JsonIgnore
     var stepData: StepData? = null
 }
 
index c3f18fc..b4c1ad0 100644 (file)
@@ -129,14 +129,15 @@ class ResourceConfigSnapshotControllerTest {
     }
 
     @Test
-    fun `get returns 404 if entry not found`() {
+    fun `get returns 200 if entry not found`() {
         runBlocking {
 
             webTestClient
                 .get()
                 .uri("/api/v1/configs?resourceId=MISSING&resourceType=PNF")
                 .exchange()
-                .expectStatus().isNotFound
+                .expectStatus().is2xxSuccessful
+                .expectBody()
         }
     }