summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Timoney <dtimoney@att.com>2019-08-09 21:49:29 +0000
committerGerrit Code Review <gerrit@onap.org>2019-08-09 21:49:29 +0000
commit4001ac13397c082ee97c7ff440fa2ead5d50b421 (patch)
tree4ef46a3908b84acb9b46919856efef6657f785dd
parent3c1781135b4029fdc657b2009259d3b8ddd8eebc (diff)
parent1e7e4a53684df04ba248c20d884ba907ca7c2870 (diff)
Merge "Add declarative acceptance tests"
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-deploy-restconf-mount-template.vtl14
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/README.md146
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/artifact_types.json22
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/data_types.json14
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-mapping.json13
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-test.json91
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/node_types.json129
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/policy_types.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/policy_types.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/relationship_types.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/relationship_types.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/resources_definition_types.json17
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Plans/TEST_echo.xml15
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/TOSCA-Metadata/TOSCA.meta5
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Templates/echo-template.vtl1
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/echo/Tests/uat.yaml34
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/activation-blueprint.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/activation-blueprint.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/artifact_types.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/artifact_types.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-assign-pnf-mapping.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-assign-pnf-mapping.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-deploy-pnf-mapping.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-deploy-pnf-mapping.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/data_types.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/data_types.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/node_types.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/node_types.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/policy_types.json3
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/relationship_types.json3
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/resources_definition_types.json (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/resources_definition_types.json)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configAssign.xml (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configAssign.xml)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configDeploy.xml (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configDeploy.xml)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Scripts/python/RestconfConfigDeploy.py (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py)2
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/TOSCA-Metadata/TOSCA.meta (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/TOSCA-Metadata/TOSCA.meta)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-assign-restconf-configlet-template.vtl (renamed from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-assign-restconf-configlet-template.vtl)0
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-deploy-restconf-mount-template.vtl18
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml126
-rw-r--r--components/parent/pom.xml9
-rw-r--r--components/scripts/python/ccsdk_restconf/restconf_client.py4
-rwxr-xr-xms/blueprintsprocessor/application/pom.xml16
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTests.kt280
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/CollectionUtils2.kt31
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ExtendedTemporaryFolder.kt40
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/TestSecuritySettings.kt45
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/WorkingFoldersInitializer.kt48
-rw-r--r--ms/blueprintsprocessor/application/src/test/resources/application-test.properties50
-rw-r--r--ms/blueprintsprocessor/application/src/test/resources/logback-test.xml20
-rw-r--r--ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt4
-rwxr-xr-xms/blueprintsprocessor/parent/pom.xml9
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/FileExtensionFunctions.kt2
-rwxr-xr-xms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt109
-rw-r--r--ms/controllerblueprints/modules/db-resources/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/db/resources/BlueprintCatalogServiceImpl.kt2
-rw-r--r--ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt2
-rw-r--r--ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt7
-rw-r--r--ms/controllerblueprints/parent/pom.xml9
48 files changed, 1238 insertions, 102 deletions
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-deploy-restconf-mount-template.vtl b/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-deploy-restconf-mount-template.vtl
deleted file mode 100644
index ad03321af..000000000
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-deploy-restconf-mount-template.vtl
+++ /dev/null
@@ -1,14 +0,0 @@
-<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
- <node-id>$pnf-id</node-id>
- <key-based xmlns="urn:opendaylight:netconf-node-topology">
- <key-id xmlns="urn:opendaylight:netconf-node-topology">ODL_private_key_0</key-id>
- <username xmlns="urn:opendaylight:netconf-node-topology">netconf</username>
- </key-based>
- <host xmlns="urn:opendaylight:netconf-node-topology">$pnf-ipv4-address</host>
- <port xmlns="urn:opendaylight:netconf-node-topology">6513</port>
- <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
- <protocol xmlns="urn:opendaylight:netconf-node-topology">
- <name xmlns="urn:opendaylight:netconf-node-topology">TLS</name>
- </protocol>
- <max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">5</max-connection-attempts>
-</node>
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/README.md b/components/model-catalog/blueprint-model/uat-blueprints/README.md
new file mode 100644
index 000000000..d6a335273
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/README.md
@@ -0,0 +1,146 @@
+# Acceptance Testing Blueprints
+
+## What is BP User Acceptance Tests (UATs)?
+
+UATs aims to fully test the BlueprintsProcessor (BPP) using a blueprint.
+The BPP runs in an almost production-like configuration with some minor exceptions:
+
+- It uses an embedded, in-memory, and initially empty H2 database, running in MySQL/MariaDB compatibility mode;
+- All external services are mocked.
+
+## How it works?
+
+The UATs are declarative, data-driven tests implemented in YAML 1.1 documents.
+This YAML files express:
+
+- Sequence of requests to be sent to the BPP for every process;
+- The expected BPP responses;
+- For every used external service:
+ - The `selector` used internally to instantiate the rest client;
+ - A variable set of expected requests and corresponding responses.
+
+The UAT engine will perform the following validations:
+
+- The BPP responses;
+- The payloads in the external services requests and it's content type.
+
+## Adding your BP to the suite of UATs
+
+To add a new BP to the UAT suite, all you need to do is:
+1. Add your blueprint folder under
+CDS project's `components/model-catalog/blueprint-model/uat-blueprints` directory;
+2. Create a `Tests/uat.yaml` document under your BP folder.
+
+## `uat.yaml` reference
+
+### Skeleton of a basic `uat.yaml`
+
+```yaml
+%YAML 1.1
+---
+processes:
+ - name: process1
+ request:
+ commonHeader: &commonHeader
+ originatorId: sdnc
+ requestId: "123456-1000"
+ subRequestId: sub-123456-1000
+ actionIdentifiers: &assign-ai
+ blueprintName: configuration_over_restconf
+ blueprintVersion: "1.0.0"
+ actionName: config-assign
+ mode: sync
+ payload:
+ # ...
+ expectedResponse:
+ commonHeader: *commonHeader
+ actionIdentifiers: *assign-ai
+ status:
+ code: 200
+ eventType: EVENT_COMPONENT_EXECUTED
+ errorMessage: null
+ message: success
+ payload:
+ # ...
+ stepData:
+ name: config-assign
+ properties:
+ resource-assignment-params:
+ # ...
+ status: success
+ - name: process2
+ # ...
+
+external-services:
+ - selector: odl
+ expectations:
+ - request:
+ method: GET
+ path:
+ response:
+ status: 200 # optional, 200 is the default value
+ body: # optional, default is an empty content
+ # ...
+ - request:
+ method: POST
+ path:
+ content-type: application/json
+ body:
+ # JSON request body
+ response:
+ status: 201
+```
+
+### Composite URI paths
+
+In case your YAML document contains many URI path definitions, you'd better keep the duplications
+as low as possible in order to ease the document maintenance, and avoid inconsistencies.
+
+Since YAML doesn't provide a standard mechanism to concatenate strings,
+the UAT engine implements an ad-hoc mechanism based on multi-level lists.
+Please note that currently this mechanism is only applied to URI paths.
+
+To exemplify how it works, let's take the case of eliminating duplications when defining multiple OpenDaylight URLs.
+
+You might starting using the following definitions:
+```yaml
+ nodeId: &nodeId "new-netconf-device"
+ # ...
+ - request:
+ path: &configUri [restconf/config, &nodeIdentifier [network-topology:network-topology/topology/topology-netconf/node, *nodeId]]
+ # ...
+ - request:
+ path: [restconf/operational, *nodeIdentifier]
+ # ...
+ - request:
+ path: [*configUri, &configletResourcePath yang-ext:mount/mynetconf:netconflist]
+```
+
+The UAT engine will expand the above multi-level lists, resulting on the following URI paths:
+```yaml
+ # ...
+ - request:
+ path: restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
+ # ...
+ - request:
+ path: restconf/operational/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
+ # ...
+ - request:
+ path: restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device/yang-ext:mount/mynetconf:netconflist
+```
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+
+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.
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/artifact_types.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/artifact_types.json
new file mode 100644
index 000000000..6ec3b4105
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/artifact_types.json
@@ -0,0 +1,22 @@
+{
+ "artifact_types" : {
+ "artifact-directed-graph" : {
+ "description" : "Directed Graph File",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "json", "xml" ]
+ },
+ "artifact-mapping-resource" : {
+ "description" : "Resource Mapping File used along with Configuration template",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "json" ]
+ },
+ "artifact-template-velocity" : {
+ "description" : " Velocity Template used for Configuration",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "vtl" ]
+ }
+ }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/data_types.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/data_types.json
new file mode 100644
index 000000000..24f501953
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/data_types.json
@@ -0,0 +1,14 @@
+{
+ "data_types" : {
+ "dt-echo-properties" : {
+ "description" : "Dynamic DataType definition for workflow(echo).",
+ "version" : "1.0.0",
+ "properties" : {
+ "echoed-message" : {
+ "type" : "string"
+ }
+ },
+ "derived_from" : "tosca.datatypes.Dynamic"
+ }
+ }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-mapping.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-mapping.json
new file mode 100644
index 000000000..02f2b496f
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-mapping.json
@@ -0,0 +1,13 @@
+[
+ {
+ "name": "echoed-message",
+ "input-param": true,
+ "property": {
+ "type": "string"
+ },
+ "dictionary-name": "echoed-message",
+ "dictionary-source": "input",
+ "dependencies": [
+ ]
+ }
+]
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-test.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-test.json
new file mode 100644
index 000000000..3105484ce
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-test.json
@@ -0,0 +1,91 @@
+{
+ "tosca_definitions_version" : "controller_blueprint_1_0_0",
+ "metadata" : {
+ "template_author" : "Rodrigo Ottero",
+ "author-email" : "rodrigo.ottero@est.tech",
+ "user-groups" : "ADMIN, OPERATION",
+ "template_name" : "echo_test",
+ "template_version" : "1.0.0",
+ "template_tags" : "echo_test, echo, test, testing"
+ },
+ "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" : {
+ "echo" : {
+ "steps" : {
+ "activate-process" : {
+ "description" : "Echo a message",
+ "target" : "echo-process",
+ "activities" : [ {
+ "call_operation" : ""
+ } ]
+ }
+ },
+ "inputs" : {
+ "echo-properties" : {
+ "description" : "Dynamic PropertyDefinition for workflow(echo).",
+ "required" : true,
+ "type" : "dt-echo-properties"
+ }
+ }
+ }
+ },
+ "node_templates" : {
+ "echo-process" : {
+ "type" : "dg-generic",
+ "properties" : {
+ "content" : {
+ "get_artifact" : [ "SELF", "dg-echo-process" ]
+ },
+ "dependency-node-templates" : [ "echo" ]
+ },
+ "artifacts" : {
+ "dg-config-assign-process" : {
+ "type" : "artifact-directed-graph",
+ "file" : "Plans/TEST_echo.xml"
+ }
+ }
+ },
+ "echo" : {
+ "type" : "component-resource-resolution",
+ "interfaces" : {
+ "ResourceResolutionComponent" : {
+ "operations" : {
+ "process" : {
+ "inputs" : {
+ "artifact-prefix-names" : [ "echo" ]
+ },
+ "outputs" : {
+ "resource-assignment-params" : {
+ "get_attribute" : [ "SELF", "assignment-params" ]
+ },
+ "status" : "success"
+ }
+ }
+ }
+ }
+ },
+ "artifacts" : {
+ "echo-template" : {
+ "type" : "artifact-template-velocity",
+ "file" : "Templates/echo-template.vtl"
+ },
+ "echo-mapping" : {
+ "type" : "artifact-mapping-resource",
+ "file" : "Definitions/echo-mapping.json"
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/node_types.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/node_types.json
new file mode 100644
index 000000000..a3fc254b2
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/node_types.json
@@ -0,0 +1,129 @@
+{
+ "node_types" : {
+ "component-resource-resolution" : {
+ "description" : "This is Resource Assignment Component API",
+ "version" : "1.0.0",
+ "attributes" : {
+ "assignment-params" : {
+ "required" : true,
+ "type" : "string"
+ }
+ },
+ "capabilities" : {
+ "component-node" : {
+ "type" : "tosca.capabilities.Node"
+ }
+ },
+ "interfaces" : {
+ "ResourceResolutionComponent" : {
+ "operations" : {
+ "process" : {
+ "inputs" : {
+ "resolution-key" : {
+ "description" : "Key for service instance related correlation.",
+ "required" : false,
+ "type" : "string"
+ },
+ "occurrence": {
+ "description": "Number of time to perform the resolution.",
+ "required": false,
+ "default": 1,
+ "type": "integer"
+ },
+ "store-result" : {
+ "description" : "Whether or not to store the output.",
+ "required" : false,
+ "type" : "boolean"
+ },
+ "resource-type" : {
+ "description" : "Request type.",
+ "required" : false,
+ "type" : "string"
+ },
+ "artifact-prefix-names" : {
+ "description" : "Template , Resource Assignment Artifact Prefix names",
+ "required" : true,
+ "type" : "list",
+ "entry_schema" : {
+ "type" : "string"
+ }
+ },
+ "request-id" : {
+ "description" : "Request Id, Unique Id for the request.",
+ "required" : true,
+ "type" : "string"
+ },
+ "resource-id" : {
+ "description" : "Resource Id.",
+ "required" : false,
+ "type" : "string"
+ },
+ "action-name" : {
+ "description" : "Action Name of the process",
+ "required" : false,
+ "type" : "string"
+ },
+ "dynamic-properties" : {
+ "description" : "Dynamic Json Content or DSL Json reference.",
+ "required" : false,
+ "type" : "json"
+ }
+ },
+ "outputs" : {
+ "resource-assignment-params" : {
+ "required" : true,
+ "type" : "string"
+ },
+ "status" : {
+ "required" : true,
+ "type" : "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "derived_from" : "tosca.nodes.Component"
+ },
+ "dg-generic" : {
+ "description" : "This is Generic Directed Graph Type",
+ "version" : "1.0.0",
+ "properties" : {
+ "content" : {
+ "required" : true,
+ "type" : "string"
+ },
+ "dependency-node-templates" : {
+ "description" : "Dependent Step Components NodeTemplate name.",
+ "required" : true,
+ "type" : "list",
+ "entry_schema" : {
+ "type" : "string"
+ }
+ }
+ },
+ "derived_from" : "tosca.nodes.Workflow"
+ },
+ "source-input" : {
+ "description" : "This is Input Resource Source Node Type",
+ "version" : "1.0.0",
+ "properties" : { },
+ "derived_from" : "tosca.nodes.ResourceSource"
+ },
+ "tosca.nodes.Component" : {
+ "description" : "This is default Component Node",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.nodes.Root"
+ },
+ "tosca.nodes.ResourceSource" : {
+ "description" : "TOSCA base type for Resource Sources",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.nodes.Root"
+ },
+ "tosca.nodes.Workflow" : {
+ "description" : "This is Directed Graph Node Type",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.nodes.Root"
+ }
+ }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/policy_types.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/policy_types.json
index 1e44cc70a..1e44cc70a 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/policy_types.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/policy_types.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/relationship_types.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/relationship_types.json
index 4ddd7a57c..4ddd7a57c 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/relationship_types.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/relationship_types.json
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/resources_definition_types.json
new file mode 100644
index 000000000..4b0cf47e7
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/resources_definition_types.json
@@ -0,0 +1,17 @@
+{
+ "echoed-message" : {
+ "tags" : "echoed-message",
+ "name" : "echoed-message",
+ "property" : {
+ "description" : "echoed-message",
+ "type" : "string"
+ },
+ "updated-by" : "Rodrigo Ottero <rodrigo.ottero@est.tech>",
+ "sources" : {
+ "input" : {
+ "type" : "source-input",
+ "properties" : { }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Plans/TEST_echo.xml b/components/model-catalog/blueprint-model/uat-blueprints/echo/Plans/TEST_echo.xml
new file mode 100644
index 000000000..4305c7dd8
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Plans/TEST_echo.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" module="CONFIG" version="1.0.0">
+ <method rpc="ResourceAssignAndActivate" mode="sync">
+ <block atomic="true">
+ <execute plugin="echo" method="process">
+ <outcome value="failure">
+ <return status="failure" />
+ </outcome>
+ <outcome value="success">
+ <return status="success" />
+ </outcome>
+ </execute>
+ </block>
+ </method>
+</service-logic>
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/uat-blueprints/echo/TOSCA-Metadata/TOSCA.meta
new file mode 100644
index 000000000..769d46474
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/TOSCA-Metadata/TOSCA.meta
@@ -0,0 +1,5 @@
+TOSCA-Meta-File-Version: 1.0.0
+CSAR-Version: 1.0
+Created-By: Rodrigo Ottero
+Entry-Definitions: Definitions/echo-test.json
+Template-Tags: activation-blueprint
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Templates/echo-template.vtl b/components/model-catalog/blueprint-model/uat-blueprints/echo/Templates/echo-template.vtl
new file mode 100644
index 000000000..9e2dcc1e5
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Templates/echo-template.vtl
@@ -0,0 +1 @@
+${echoed-message} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/echo/Tests/uat.yaml b/components/model-catalog/blueprint-model/uat-blueprints/echo/Tests/uat.yaml
new file mode 100644
index 000000000..116230929
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/echo/Tests/uat.yaml
@@ -0,0 +1,34 @@
+%YAML 1.1
+---
+processes:
+ - name: echo-it
+ request:
+ commonHeader: &ch
+ originatorId: sdnc
+ requestId: "1234"
+ subRequestId: "1234-12234"
+ actionIdentifiers: &ai
+ blueprintName: echo_test
+ blueprintVersion: "1.0.0"
+ actionName: echo
+ mode: sync
+ payload:
+ echo-request:
+ echo-properties:
+ echoed-message: &message "Hello World!"
+ expectedResponse:
+ commonHeader: *ch
+ actionIdentifiers: *ai
+ status:
+ code: 200
+ eventType: EVENT_COMPONENT_EXECUTED
+ errorMessage: null
+ message: success
+ payload:
+ echo-response: {}
+ stepData:
+ name: echo
+ properties:
+ resource-assignment-params:
+ echo: *message
+ status: success
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/activation-blueprint.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/activation-blueprint.json
index d185128d5..d185128d5 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/activation-blueprint.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/activation-blueprint.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/artifact_types.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/artifact_types.json
index aa5295e44..aa5295e44 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/artifact_types.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/artifact_types.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-assign-pnf-mapping.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-assign-pnf-mapping.json
index fe51488c7..fe51488c7 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-assign-pnf-mapping.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-assign-pnf-mapping.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-deploy-pnf-mapping.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-deploy-pnf-mapping.json
index d87b8d1f1..d87b8d1f1 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-deploy-pnf-mapping.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-deploy-pnf-mapping.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/data_types.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/data_types.json
index a0804bb3f..a0804bb3f 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/data_types.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/data_types.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/node_types.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/node_types.json
index 8c2c0abea..8c2c0abea 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/node_types.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/node_types.json
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/policy_types.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/policy_types.json
new file mode 100644
index 000000000..1e44cc70a
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/policy_types.json
@@ -0,0 +1,3 @@
+{
+ "policy_types" : { }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/relationship_types.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/relationship_types.json
new file mode 100644
index 000000000..4ddd7a57c
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/relationship_types.json
@@ -0,0 +1,3 @@
+{
+ "relationship_types" : { }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/resources_definition_types.json
index 114eb1992..114eb1992 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/resources_definition_types.json
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/resources_definition_types.json
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configAssign.xml b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configAssign.xml
index 220cba9f7..220cba9f7 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configAssign.xml
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configAssign.xml
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configDeploy.xml b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configDeploy.xml
index fbed3d575..fbed3d575 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configDeploy.xml
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configDeploy.xml
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Scripts/python/RestconfConfigDeploy.py
index 7bda87229..f8225e0ce 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Scripts/python/RestconfConfigDeploy.py
@@ -37,7 +37,7 @@ class RestconfConfigDeploy(AbstractScriptComponentFunction):
try:
# mount the device
mount_payload = restconf_client.resolve_and_generate_message_from_template_prefix("config-deploy")
- restconf_client.mount_device(web_client_service, pnf_id, mount_payload)
+ restconf_client.mount_device(web_client_service, pnf_id, mount_payload, "application/json")
# log the current configuration subtree
current_configuration = restconf_client.retrieve_device_configuration_subtree(
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/TOSCA-Metadata/TOSCA.meta
index 6ac9caf57..6ac9caf57 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/TOSCA-Metadata/TOSCA.meta
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/TOSCA-Metadata/TOSCA.meta
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-assign-restconf-configlet-template.vtl b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-assign-restconf-configlet-template.vtl
index af91ba00d..af91ba00d 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-assign-restconf-configlet-template.vtl
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-assign-restconf-configlet-template.vtl
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-deploy-restconf-mount-template.vtl b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-deploy-restconf-mount-template.vtl
new file mode 100644
index 000000000..8098b05d8
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-deploy-restconf-mount-template.vtl
@@ -0,0 +1,18 @@
+{
+ "node": [
+ {
+ "node-id": "${pnf-id}",
+ "netconf-node-topology:protocol": {
+ "name": "TLS"
+ },
+ "netconf-node-topology:host": "${pnf-ipv4-address}",
+ "netconf-node-topology:key-based": {
+ "username": "netconf",
+ "key-id": "ODL_private_key_0"
+ },
+ "netconf-node-topology:port": 6513,
+ "netconf-node-topology:tcp-only": false,
+ "netconf-node-topology:max-connection-attempts": 5
+ }
+ ]
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml
new file mode 100644
index 000000000..37029e181
--- /dev/null
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml
@@ -0,0 +1,126 @@
+%YAML 1.1
+---
+processes:
+ - name: config-assign
+ request:
+ commonHeader: &commonHeader
+ originatorId: sdnc
+ requestId: "123456-1000"
+ subRequestId: sub-123456-1000
+ actionIdentifiers: &assign-ai
+ blueprintName: configuration_over_restconf
+ blueprintVersion: "1.0.0"
+ actionName: config-assign
+ mode: sync
+ payload:
+ config-assign-request:
+ resolution-key: &resKey "RES-KEY 61"
+ config-assign-properties:
+ service-instance-id: siid_1234
+ pnf-id: &pnfId pnf-id-2019-07-12
+ pnf-ipv4-address: &pnfAddress "192.168.100.11"
+ service-model-uuid: service-model-uuid
+ pnf-customization-uuid: pnf-customization-uuid
+ expectedResponse:
+ commonHeader: *commonHeader
+ actionIdentifiers: *assign-ai
+ status:
+ code: 200
+ eventType: EVENT_COMPONENT_EXECUTED
+ errorMessage: null
+ 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
+ - name: config-deploy
+ request:
+ commonHeader: *commonHeader
+ actionIdentifiers: &deploy-ai
+ actionName: config-deploy
+ blueprintName: configuration_over_restconf
+ blueprintVersion: "1.0.0"
+ mode: sync
+ payload:
+ config-deploy-request:
+ resolution-key: *resKey
+ config-deploy-properties:
+ service-instance-id: siid_1234
+ pnf-id: *pnfId
+ pnf-ipv4-address: *pnfAddress
+ service-model-uuid: service-model-uuid
+ pnf-customization-uuid: pnf-customization-uuid
+ expectedResponse:
+ commonHeader: *commonHeader
+ actionIdentifiers: *deploy-ai
+ payload:
+ config-deploy-response: {}
+ status:
+ code: 200
+ errorMessage: null
+ eventType: EVENT_COMPONENT_EXECUTED
+ message: success
+ stepData:
+ name: config-deploy
+ properties:
+ response-data: ""
+ status: success
+
+external-services:
+ - selector: sdncodl
+ expectations:
+ - request:
+ method: PUT
+ path: &configUri [ restconf/config, &nodeIdentifier [network-topology:network-topology/topology/topology-netconf/node, *pnfId]]
+ content-type: application/json
+ body:
+ node:
+ - node-id: *pnfId
+ netconf-node-topology:protocol: { name: TLS }
+ netconf-node-topology:host: *pnfAddress
+ netconf-node-topology:key-based:
+ username: netconf
+ key-id: ODL_private_key_0
+ netconf-node-topology:port: 6513
+ netconf-node-topology:tcp-only: false
+ netconf-node-topology:max-connection-attempts: 5
+ response:
+ status: 201
+ - request:
+ method: GET
+ path: [ restconf/operational, *nodeIdentifier]
+ response:
+ body:
+ node: [ { netconf-node-topology:connection-status: connected }]
+ - request:
+ method: GET
+ path: [*configUri, &configletResourcePath yang-ext:mount/mynetconf:netconflist]
+ response:
+ body: {}
+ - request:
+ method: PATCH
+ path: [*configUri, *configletResourcePath]
+ content-type: application/yang.patch+json
+ body: *assignPatch
+ - request:
+ method: DELETE
+ path: *configUri
diff --git a/components/parent/pom.xml b/components/parent/pom.xml
index 233aa586b..ef030cde5 100644
--- a/components/parent/pom.xml
+++ b/components/parent/pom.xml
@@ -82,11 +82,6 @@
<version>2.6</version>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- <version>1.15</version>
- </dependency>
- <dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
@@ -237,10 +232,6 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- </dependency>
- <dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<exclusions>
diff --git a/components/scripts/python/ccsdk_restconf/restconf_client.py b/components/scripts/python/ccsdk_restconf/restconf_client.py
index 43f2a02c4..927c1fedd 100644
--- a/components/scripts/python/ccsdk_restconf/restconf_client.py
+++ b/components/scripts/python/ccsdk_restconf/restconf_client.py
@@ -43,9 +43,9 @@ class RestconfClient:
return ResourceResolutionExtensionsKt.storedContentFromResolvedArtifact(self.__component_function, key,
artifact_template)
- def mount_device(self, web_client_service, nf_id, mount_payload):
+ def mount_device(self, web_client_service, nf_id, mount_payload, content_type="application/xml"):
self.__log.debug("mounting device {}", nf_id)
- headers = {"Content-Type": "application/xml"}
+ headers = {"Content-Type": content_type}
url = self.__base_odl_url + nf_id
self.__log.debug("sending mount request, url: {}", url)
web_client_service.exchangeResource("PUT", url, mount_payload, headers)
diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml
index 4e487304c..a504ce3cc 100755
--- a/ms/blueprintsprocessor/application/pom.xml
+++ b/ms/blueprintsprocessor/application/pom.xml
@@ -113,6 +113,22 @@
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nhaarman.mockitokotlin2</groupId>
+ <artifactId>mockito-kotlin</artifactId>
+ <version>2.1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<resources>
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTests.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTests.kt
new file mode 100644
index 000000000..0a57277ea
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTests.kt
@@ -0,0 +1,280 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.nhaarman.mockitokotlin2.any
+import com.nhaarman.mockitokotlin2.argThat
+import com.nhaarman.mockitokotlin2.atLeast
+import com.nhaarman.mockitokotlin2.atLeastOnce
+import com.nhaarman.mockitokotlin2.eq
+import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.verify
+import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
+import com.nhaarman.mockitokotlin2.whenever
+import org.junit.ClassRule
+import org.junit.Rule
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestLibConstants
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService.WebClientResponse
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintArchiveUtils.Companion.compressToBytes
+import org.skyscreamer.jsonassert.JSONAssert
+import org.skyscreamer.jsonassert.JSONCompareMode
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.boot.test.mock.mockito.MockBean
+import org.springframework.core.io.ByteArrayResource
+import org.springframework.core.io.Resource
+import org.springframework.http.MediaType
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.TestPropertySource
+import org.springframework.test.context.junit4.rules.SpringClassRule
+import org.springframework.test.context.junit4.rules.SpringMethodRule
+import org.springframework.test.web.reactive.server.WebTestClient
+import org.yaml.snakeyaml.Yaml
+import reactor.core.publisher.Mono
+import java.io.File
+import java.nio.file.Path
+import java.nio.file.Paths
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+
+@RunWith(Parameterized::class)
+// Set blueprintsprocessor.httpPort=0 to trigger a random port selection
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+@AutoConfigureWebTestClient(timeout = "PT10S")
+@ContextConfiguration(initializers = [
+ WorkingFoldersInitializer::class,
+ TestSecuritySettings.ServerContextInitializer::class
+])
+@TestPropertySource(locations = ["classpath:application-test.properties"])
+@Suppress("UNCHECKED_CAST")
+class BlueprintsAcceptanceTests(private val blueprintName: String, private val filename: String) {
+
+ companion object {
+ const val UAT_BLUEPRINTS_BASE_DIR = "../../../components/model-catalog/blueprint-model/uat-blueprints"
+ const val EMBEDDED_UAT_FILE = "Tests/uat.yaml"
+
+ @ClassRule
+ @JvmField
+ val springClassRule = SpringClassRule()
+
+ val log: Logger = LoggerFactory.getLogger(BlueprintsAcceptanceTests::class.java)
+
+ @Parameterized.Parameters(name = "{index} {0}")
+ @JvmStatic
+ fun filenames(): List<Array<String>> {
+ return File(UAT_BLUEPRINTS_BASE_DIR)
+ .listFiles { file -> file.isDirectory && File(file, EMBEDDED_UAT_FILE).isFile }
+ ?.map { file -> arrayOf(file.nameWithoutExtension, file.canonicalPath) }
+ ?: emptyList()
+ }
+ }
+
+ @Rule
+ @JvmField
+ val springMethodRule = SpringMethodRule()
+
+ @MockBean(name = RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY)
+ lateinit var restClientFactory: BluePrintRestLibPropertyService
+
+ @Autowired
+ // Bean is created programmatically by {@link WorkingFoldersInitializer#initialize(String)}
+ @Suppress("SpringJavaInjectionPointsAutowiringInspection")
+ lateinit var tempFolder: ExtendedTemporaryFolder
+
+ @Autowired
+ lateinit var webTestClient: WebTestClient
+
+ @Autowired
+ lateinit var mapper: ObjectMapper
+
+ @BeforeTest
+ fun cleanupTemporaryFolder() {
+ tempFolder.deleteAllFiles()
+ }
+
+ @Test
+ fun testBlueprint() {
+ val yaml: Map<String, *> = loadYaml(Paths.get(filename, EMBEDDED_UAT_FILE))
+
+ uploadBlueprint(blueprintName)
+
+ // Configure mocked external services
+ val services = yaml["external-services"] as List<Map<String, *>>? ?: emptyList()
+ val expectationPerClient = services.map { service ->
+ val selector = service["selector"] as String
+ val expectations = (service["expectations"] as List<Map<String, *>>).map {
+ parseExpectation(it)
+ }
+ val mockClient = createRestClientMock(selector, expectations)
+ mockClient to expectations
+ }.toMap()
+
+ // Run processes
+ for (process in (yaml["processes"] as List<Map<String, *>>)) {
+ val processName = process["name"]
+ log.info("Executing process '$processName'")
+ val request = mapper.writeValueAsString(process["request"])
+ val expectedResponse = mapper.writeValueAsString(process["expectedResponse"])
+ processBlueprint(request, expectedResponse)
+ }
+
+ // Validate request payloads
+ for ((mockClient, expectations) in expectationPerClient) {
+ expectations.forEach { expectation ->
+ verify(mockClient, atLeastOnce()).exchangeResource(
+ eq(expectation.method),
+ eq(expectation.path),
+ argThat { assertJsonEqual(expectation.expectedRequestBody, this) },
+ expectation.requestHeadersMatcher())
+ }
+ // Don't mind the invocations to the overloaded exchangeResource(String, String, String)
+ verify(mockClient, atLeast(0)).exchangeResource(any(), any(), any())
+ verifyNoMoreInteractions(mockClient)
+ }
+ }
+
+ private fun createRestClientMock(selector: String, restExpectations: List<RestExpectation>): BlueprintWebClientService {
+ val restClient = mock<BlueprintWebClientService>(verboseLogging = true)
+
+ // Delegates to overloaded exchangeResource(String, String, String, Map<String, String>)
+ whenever(restClient.exchangeResource(any(), any(), any()))
+ .thenAnswer { invocation ->
+ val method = invocation.arguments[0] as String
+ val path = invocation.arguments[1] as String
+ val request = invocation.arguments[2] as String
+ restClient.exchangeResource(method, path, request, emptyMap())
+ }
+ for (expectation in restExpectations) {
+ whenever(restClient.exchangeResource(
+ eq(expectation.method),
+ eq(expectation.path),
+ any(),
+ any()))
+ .thenReturn(WebClientResponse(expectation.statusCode, expectation.responseBody))
+ }
+
+ whenever(restClientFactory.blueprintWebClientService(selector))
+ .thenReturn(restClient)
+ return restClient
+ }
+
+ private fun uploadBlueprint(blueprintName: String) {
+ val body = toMultiValueMap("file", getBlueprintAsResource(blueprintName))
+ webTestClient
+ .post()
+ .uri("/api/v1/execution-service/upload")
+ .header("Authorization", TestSecuritySettings.clientAuthToken())
+ .syncBody(body)
+ .exchange()
+ .expectStatus().isOk
+ }
+
+ private fun processBlueprint(request: String, expectedResponse: String) {
+ webTestClient
+ .post()
+ .uri("/api/v1/execution-service/process")
+ .header("Authorization", TestSecuritySettings.clientAuthToken())
+ .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .body(Mono.just(request), String::class.java)
+ .exchange()
+ .expectStatus().isOk
+ .expectBody()
+ .json(expectedResponse)
+ }
+
+ private fun getBlueprintAsResource(blueprintName: String): Resource {
+ val baseDir = Paths.get(UAT_BLUEPRINTS_BASE_DIR, blueprintName)
+ val zipBytes = compressToBytes(baseDir)
+ return object : ByteArrayResource(zipBytes) {
+ // Filename has to be returned in order to be able to post
+ override fun getFilename() = "$blueprintName.zip"
+ }
+ }
+
+ private fun loadYaml(path: Path): Map<String, Any> {
+ return path.toFile().reader().use { reader ->
+ Yaml().load(reader)
+ }
+ }
+
+ private fun assertJsonEqual(expected: Any, actual: String): Boolean {
+ if (actual != expected) {
+ // assertEquals throws an exception whenever match fails
+ JSONAssert.assertEquals(mapper.writeValueAsString(expected), actual, JSONCompareMode.LENIENT)
+ }
+ return true
+ }
+
+ private fun parseExpectation(expectation: Map<String, *>): RestExpectation {
+ val request = expectation["request"] as Map<String, Any>
+ val method = request["method"] as String
+ val path = joinPath(request.getValue("path"))
+ val contentType = request["content-type"] as String?
+ val requestBody = request.getOrDefault("body", "")
+
+ val response = expectation["response"] as Map<String, Any>? ?: emptyMap()
+ val status = response["status"] as Int? ?: 200
+ val responseBody = when (val body = response["body"] ?: "") {
+ is String -> body
+ else -> mapper.writeValueAsString(body)
+ }
+
+ return RestExpectation(method, path, contentType, requestBody, status, responseBody)
+ }
+
+ /**
+ * Join a multilevel lists of strings.
+ * Example: joinPath(listOf("a", listOf("b", "c"), "d")) will result in "a/b/c/d".
+ */
+ private fun joinPath(any: Any): String {
+ fun recursiveJoin(any: Any, sb: StringBuilder): StringBuilder {
+ when (any) {
+ is List<*> -> any.filterNotNull().forEach { recursiveJoin(it, sb) }
+ is String -> {
+ if (sb.isNotEmpty()) {
+ sb.append('/')
+ }
+ sb.append(any)
+ }
+ else -> throw IllegalArgumentException("Unsupported type: ${any.javaClass}")
+ }
+ return sb
+ }
+
+ return recursiveJoin(any, StringBuilder()).toString()
+ }
+
+ data class RestExpectation(val method: String, val path: String, val contentType: String?,
+ val expectedRequestBody: Any,
+ val statusCode: Int, val responseBody: String) {
+
+ fun requestHeadersMatcher(): Map<String, String> {
+ return if (contentType != null) eq(mapOf("Content-Type" to contentType)) else any()
+ }
+ }
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/CollectionUtils2.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/CollectionUtils2.kt
new file mode 100644
index 000000000..63d64cae4
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/CollectionUtils2.kt
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import org.springframework.util.CollectionUtils
+import org.springframework.util.MultiValueMap
+
+
+/**
+ * Convenient method to create a single-entry MultiValueMap.
+ */
+fun <K, V> toMultiValueMap(key: K, vararg values: V): MultiValueMap<K, V> {
+ return CollectionUtils.toMultiValueMap(mapOf(key to values.asList()))
+}
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ExtendedTemporaryFolder.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ExtendedTemporaryFolder.kt
new file mode 100644
index 000000000..4576f2761
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ExtendedTemporaryFolder.kt
@@ -0,0 +1,40 @@
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import org.junit.rules.TemporaryFolder
+import java.io.File
+import java.io.IOException
+import java.nio.file.FileVisitResult
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.SimpleFileVisitor
+import java.nio.file.attribute.BasicFileAttributes
+import javax.annotation.PreDestroy
+
+class ExtendedTemporaryFolder {
+ private val tempFolder = TemporaryFolder()
+
+ init {
+ tempFolder.create()
+ }
+
+ @PreDestroy
+ fun delete() = tempFolder.delete()
+
+ /**
+ * A delegate to org.junit.rules.TemporaryFolder.TemporaryFolder.newFolder(String).
+ */
+ fun newFolder(folder: String): File = tempFolder.newFolder(folder)
+
+ /**
+ * Delete all files under the root temporary folder recursively. The folders are preserved.
+ */
+ fun deleteAllFiles() {
+ Files.walkFileTree(tempFolder.root.toPath(), object : SimpleFileVisitor<Path>() {
+ @Throws(IOException::class)
+ override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult {
+ file?.toFile()?.delete()
+ return FileVisitResult.CONTINUE
+ }
+ })
+ }
+}
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/TestSecuritySettings.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/TestSecuritySettings.kt
new file mode 100644
index 000000000..f7ab2554c
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/TestSecuritySettings.kt
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import org.springframework.context.ApplicationContextInitializer
+import org.springframework.context.ConfigurableApplicationContext
+import org.springframework.test.context.support.TestPropertySourceUtils
+import org.springframework.util.Base64Utils
+import java.nio.charset.StandardCharsets
+
+class TestSecuritySettings {
+ companion object {
+ private const val authUsername = "walter.white"
+ private const val authPassword = "Heisenberg"
+
+ fun clientAuthToken() =
+ "Basic " + Base64Utils.encodeToString("$authUsername:$authPassword".toByteArray(StandardCharsets.UTF_8))
+ }
+
+ class ServerContextInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
+ override fun initialize(context: ConfigurableApplicationContext) {
+ TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context,
+ "security.user.name=$authUsername",
+ "security.user.password={noop}$authPassword"
+ )
+ }
+ }
+}
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/WorkingFoldersInitializer.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/WorkingFoldersInitializer.kt
new file mode 100644
index 000000000..37615cb1a
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/WorkingFoldersInitializer.kt
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder
+import org.springframework.beans.factory.support.BeanDefinitionRegistry
+import org.springframework.context.ApplicationContextInitializer
+import org.springframework.context.ConfigurableApplicationContext
+import org.springframework.stereotype.Component
+import org.springframework.test.context.support.TestPropertySourceUtils
+
+@Component
+class WorkingFoldersInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
+
+ override fun initialize(context: ConfigurableApplicationContext) {
+ val tempFolder = ExtendedTemporaryFolder()
+ val properties = listOf("Deploy", "Archive", "Working")
+ .map { "blueprintsprocessor.blueprint${it}Path=${tempFolder.newFolder(it)}" }
+ .toTypedArray()
+ TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, *properties)
+ // Expose tempFolder as a bean so it can be accessed via DI
+ registerSingleton(context, "tempFolder", ExtendedTemporaryFolder::class.java, tempFolder)
+ }
+
+ @Suppress("SameParameterValue")
+ private fun <T> registerSingleton(context: ConfigurableApplicationContext,
+ beanName: String, beanClass: Class<T>, instance: T) {
+ val builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass) { instance }
+ (context.beanFactory as BeanDefinitionRegistry).registerBeanDefinition(beanName, builder.beanDefinition)
+ }
+}
diff --git a/ms/blueprintsprocessor/application/src/test/resources/application-test.properties b/ms/blueprintsprocessor/application/src/test/resources/application-test.properties
new file mode 100644
index 000000000..b8b80f2dd
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/resources/application-test.properties
@@ -0,0 +1,50 @@
+#
+# Copyright © 2019 Nordix Foundation.
+#
+# 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.
+#
+
+spring.http.log-request-details=true
+
+blueprintsprocessor.httpPort=0
+blueprintsprocessor.grpcEnable=true
+blueprintsprocessor.grpcPort=0
+
+blueprintsprocessor.db.primary.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1
+blueprintsprocessor.db.primary.username=sa
+blueprintsprocessor.db.primary.password=
+blueprintsprocessor.db.primary.driverClassName=org.h2.Driver
+blueprintsprocessor.db.primary.hibernateHbm2ddlAuto=create-drop
+blueprintsprocessor.db.primary.hibernateDDLAuto=update
+blueprintsprocessor.db.primary.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy
+blueprintsprocessor.db.primary.hibernateDialect=org.hibernate.dialect.H2Dialect
+
+# The properties bellow are set programmatically
+#blueprintsprocessor.blueprintDeployPath=
+#blueprintsprocessor.blueprintArchivePath=
+#blueprintsprocessor.blueprintWorkingPath=
+#security.user.name=
+#security.user.password=
+
+# Python executor
+blueprints.processor.functions.python.executor.executionPath=../../../components/scripts/python/ccsdk_blueprints
+blueprints.processor.functions.python.executor.modulePaths=\
+ ../../../components/scripts/python/ccsdk_blueprints,\
+ ../../../components/scripts/python/ccsdk_netconf,\
+ ../../../components/scripts/python/ccsdk_restconf
+
+# Executor Options
+blueprintsprocessor.cliExecutor.enabled=true
+blueprintprocessor.netconfExecutor.enabled=true
+
+blueprintsprocessor.restconfEnabled=true \ No newline at end of file
diff --git a/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml
index 16e7d3d1b..eaa51c0a3 100644
--- a/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml
+++ b/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml
@@ -1,5 +1,6 @@
<!--
~ Copyright © 2017-2018 AT&T Intellectual Property.
+ ~ Modifications Copyright (C) 2019 Nordix Foundation.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,19 +17,24 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
- <pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{50} - %msg%n</pattern>
+ <pattern>%d{HH:mm:ss.SSS} %-5level %-40.40logger{39} : %msg%n</pattern>
</encoder>
</appender>
+ <logger name="org.springframework.web.HttpLogging" level="trace"/>
+ <logger name="org.springframework.web.reactive.function.client.ExchangeFunctions" level="trace"/>
- <logger name="org.springframework" level="warn"/>
- <logger name="org.hibernate" level="info"/>
- <logger name="org.onap.ccsdk.cds.blueprintsprocessor" level="info"/>
+ <!-- Helpful to optimize Spring Context caching to speed-up tests
+ and prevent resorting to @DirtiesContext as much as possible -->
+ <logger name="org.springframework.test.context.cache" level="debug"/>
- <root level="warn">
+ <!-- Please refer to https://thoughts-on-java.org/hibernate-logging-guide/
+ for a lengthy discussion on good Hibernate logging practices -->
+ <logger name="org.hibernate.SQL" level="debug"/>
+ <logger name="org.hibernate.type.descriptor.sql" level="trace"/>
+
+ <root level="info">
<appender-ref ref="STDOUT"/>
</root>
diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt
index da4d9933f..4f6865764 100644
--- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt
+++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt
@@ -37,13 +37,13 @@ import org.springframework.stereotype.Service
open class BluePrintRestLibPropertyService(private var bluePrintProperties:
BluePrintProperties) {
- fun blueprintWebClientService(jsonNode: JsonNode):
+ open fun blueprintWebClientService(jsonNode: JsonNode):
BlueprintWebClientService {
val restClientProperties = restClientProperties(jsonNode)
return blueprintWebClientService(restClientProperties)
}
- fun blueprintWebClientService(selector: String): BlueprintWebClientService {
+ open fun blueprintWebClientService(selector: String): BlueprintWebClientService {
val prefix = "blueprintsprocessor.restclient.$selector"
val restClientProperties = restClientProperties(prefix)
return blueprintWebClientService(restClientProperties)
diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml
index 5bc4d3645..ec8bfd816 100755
--- a/ms/blueprintsprocessor/parent/pom.xml
+++ b/ms/blueprintsprocessor/parent/pom.xml
@@ -122,11 +122,6 @@
<version>2.6</version>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- <version>1.15</version>
- </dependency>
- <dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
@@ -531,10 +526,6 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- </dependency>
- <dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<exclusions>
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/FileExtensionFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/FileExtensionFunctions.kt
index 18091e630..518e9b236 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/FileExtensionFunctions.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/FileExtensionFunctions.kt
@@ -52,7 +52,7 @@ fun File.compress(targetZipFileName: String): File {
* Compress the current Dir to the target zip file and return the target zip file
*/
fun File.compress(targetZipFile: File): File {
- BluePrintArchiveUtils.compress(this, targetZipFile, true)
+ BluePrintArchiveUtils.compress(this, targetZipFile)
return targetZipFile
}
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
index 8517be843..2f082db9c 100755
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
@@ -1,6 +1,7 @@
/*
* Copyright © 2017-2018 AT&T Intellectual Property.
* Modifications Copyright © 2019 Bell Canada.
+ * Modifications Copyright © 2019 Nordix Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,17 +18,26 @@
package org.onap.ccsdk.cds.controllerblueprints.core.utils
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
-import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
-import org.apache.commons.io.IOUtils
+import com.google.common.base.Predicates
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
import org.slf4j.LoggerFactory
import java.io.BufferedInputStream
+import java.io.ByteArrayOutputStream
import java.io.File
-import java.io.FileInputStream
+import java.io.FileOutputStream
import java.io.IOException
+import java.io.OutputStream
import java.nio.charset.Charset
+import java.nio.file.FileVisitResult
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.SimpleFileVisitor
+import java.nio.file.attribute.BasicFileAttributes
+import java.util.function.Predicate
+import java.util.zip.Deflater
+import java.util.zip.ZipEntry
import java.util.zip.ZipFile
+import java.util.zip.ZipOutputStream
class BluePrintArchiveUtils {
@@ -39,17 +49,17 @@ class BluePrintArchiveUtils {
*
* @param source the base directory
* @param destination the output filename
- * @param absolute store absolute filepath (from directory) or only filename
* @return True if OK
*/
- fun compress(source: File, destination: File, absolute: Boolean): Boolean {
+ fun compress(source: File, destination: File): Boolean {
try {
if(!destination.parentFile.exists()) {
destination.parentFile.mkdirs()
}
destination.createNewFile()
- ZipArchiveOutputStream(destination).use {
- recurseFiles(source, source, it, absolute)
+ val ignoreZipFiles = Predicate<Path> { path -> !path.endsWith(".zip") && !path.endsWith(".ZIP") }
+ FileOutputStream(destination).use { out ->
+ compressFolder(source.toPath(), out, pathFilter = ignoreZipFiles)
}
} catch (e: Exception) {
log.error("Fail to compress folder($source) to path(${destination.path})", e)
@@ -59,40 +69,61 @@ class BluePrintArchiveUtils {
}
/**
- * Recursive traversal to add files
- *
- * @param root
- * @param file
- * @param zaos
- * @param absolute
- * @throws IOException
+ * In-memory compress an entire folder.
*/
- @Throws(IOException::class)
- private fun recurseFiles(root: File, file: File, zaos: ZipArchiveOutputStream,
- absolute: Boolean) {
- if (file.isDirectory) {
- // recursive call
- val files = file.listFiles()
- for (fileChild in files!!) {
- recurseFiles(root, fileChild, zaos, absolute)
- }
- } else if (!file.name.endsWith(".zip") && !file.name.endsWith(".ZIP")) {
- val filename = if (absolute) {
- file.absolutePath.substring(root.absolutePath.length)
- } else {
- file.name
- }
- val zae = ZipArchiveEntry(filename)
- zae.size = file.length()
- zaos.putArchiveEntry(zae)
- FileInputStream(file).use {
- IOUtils.copy(it, zaos)
- it.close()
- }
- zaos.closeArchiveEntry()
- }
+ fun compressToBytes(baseDir: Path, compressionLevel: Int = Deflater.NO_COMPRESSION): ByteArray {
+ return compressFolder(baseDir, ByteArrayOutputStream(), compressionLevel = compressionLevel)
+ .toByteArray()
}
+ /**
+ * Compress an entire folder.
+ *
+ * @param baseDir path of base folder to be packaged.
+ * @param output the output stream
+ * @param pathFilter filter to ignore files based on its path.
+ * @param compressionLevel the wanted compression level.
+ * @param fixedModificationTime to force every entry to have this modification time.
+ * Useful for reproducible operations, like tests, for example.
+ */
+ private fun <T> compressFolder(baseDir: Path, output: T,
+ pathFilter: Predicate<Path> = Predicates.alwaysTrue(),
+ compressionLevel: Int = Deflater.DEFAULT_COMPRESSION,
+ fixedModificationTime: Long? = null): T
+ where T : OutputStream {
+ ZipOutputStream(output)
+ .apply { setLevel(compressionLevel) }
+ .use { zos ->
+ Files.walkFileTree(baseDir, object : SimpleFileVisitor<Path>() {
+ @Throws(IOException::class)
+ override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
+ if (pathFilter.test(file)) {
+ val zipEntry = ZipEntry(baseDir.relativize(file).toString())
+ fixedModificationTime?.let {
+ zipEntry.time = it
+ }
+ zipEntry.time = 0;
+ zos.putNextEntry(zipEntry)
+ Files.copy(file, zos)
+ zos.closeEntry()
+ }
+ return FileVisitResult.CONTINUE
+ }
+
+ @Throws(IOException::class)
+ override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
+ val zipEntry = ZipEntry(baseDir.relativize(dir).toString() + "/")
+ fixedModificationTime?.let {
+ zipEntry.time = it
+ }
+ zos.putNextEntry(zipEntry)
+ zos.closeEntry()
+ return FileVisitResult.CONTINUE
+ }
+ })
+ }
+ return output
+ }
fun deCompress(zipFile: File, targetPath: String): File {
val zip = ZipFile(zipFile, Charset.defaultCharset())
diff --git a/ms/controllerblueprints/modules/db-resources/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/db/resources/BlueprintCatalogServiceImpl.kt b/ms/controllerblueprints/modules/db-resources/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/db/resources/BlueprintCatalogServiceImpl.kt
index 9780bbd31..b3436a991 100644
--- a/ms/controllerblueprints/modules/db-resources/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/db/resources/BlueprintCatalogServiceImpl.kt
+++ b/ms/controllerblueprints/modules/db-resources/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/db/resources/BlueprintCatalogServiceImpl.kt
@@ -46,7 +46,7 @@ abstract class BlueprintCatalogServiceImpl(
workingDir = blueprintFile.absolutePath
archiveFile = normalizedFile(bluePrintPathConfiguration.blueprintArchivePath, processingId, "cba.zip")
- if (!BluePrintArchiveUtils.compress(blueprintFile, archiveFile, true)) {
+ if (!BluePrintArchiveUtils.compress(blueprintFile, archiveFile)) {
throw BluePrintException("Fail to compress blueprint")
}
} else {
diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt
index d4753e194..a0f8ca9c5 100644
--- a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt
+++ b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt
@@ -109,7 +109,7 @@ class BluePrintEnhancerUtils {
suspend fun compressToFilePart(enhanceDir: String, archiveDir: String): ResponseEntity<Resource> {
val compressedFile = normalizedFile(archiveDir, "enhanced-cba.zip")
- BluePrintArchiveUtils.compress(Paths.get(enhanceDir).toFile(), compressedFile, true)
+ BluePrintArchiveUtils.compress(Paths.get(enhanceDir).toFile(), compressedFile)
return prepareResourceEntity(compressedFile.name, compressedFile.readBytes())
}
diff --git a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
index 1f872c2da..d09479b6c 100644
--- a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
+++ b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
@@ -66,7 +66,6 @@ class BluePrintEnhancerServiceImplTest {
testBaseConfigEnhancementAndValidation()
testVFWEnhancementAndValidation()
testGoldenEnhancementAndValidation()
- testCapabilityRestconfEnhancementAndValidation()
testRemoteScriptsEnhancementAndValidation()
testCapabilityCliEnhancementAndValidation()
}
@@ -87,12 +86,6 @@ class BluePrintEnhancerServiceImplTest {
testComponentInvokeEnhancementAndValidation(basePath, "golden-enhance")
}
- fun testCapabilityRestconfEnhancementAndValidation() {
- val basePath = "./../../../../components/model-catalog/blueprint-model/test-blueprint/capability_restconf"
- testComponentInvokeEnhancementAndValidation(basePath, "capability_restconf-enhance")
-
- }
-
fun testRemoteScriptsEnhancementAndValidation() {
val basePath = "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_scripts"
testComponentInvokeEnhancementAndValidation(basePath, "remote_scripts-enhance")
diff --git a/ms/controllerblueprints/parent/pom.xml b/ms/controllerblueprints/parent/pom.xml
index a16783f75..2e9dcb243 100644
--- a/ms/controllerblueprints/parent/pom.xml
+++ b/ms/controllerblueprints/parent/pom.xml
@@ -94,11 +94,6 @@
<version>2.6</version>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- <version>1.15</version>
- </dependency>
- <dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
@@ -294,10 +289,6 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- </dependency>
- <dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<exclusions>