Merge "Resource resolution should return a string"
authorDan Timoney <dtimoney@att.com>
Mon, 12 Aug 2019 13:14:12 +0000 (13:14 +0000)
committerGerrit Code Review <gerrit@onap.org>
Mon, 12 Aug 2019 13:14:12 +0000 (13:14 +0000)
105 files changed:
cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.ts
cds-ui/client/src/app/feature-modules/blueprint/select-template/template-options/template-options.component.html
cds-ui/client/src/app/feature-modules/blueprint/select-template/template-options/template-options.component.ts
cds-ui/client/src/app/feature-modules/resource-definition/resource-edit/resource-metadata/resource-metadata.component.ts
cds-ui/client/src/app/feature-modules/resource-definition/resource-edit/sources-template/sources-template.component.ts
cds-ui/server/src/config/app-config.ts
components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json
components/model-catalog/blueprint-model/test-blueprint/capability_cli/Distribution/cba_zip.xml [new file with mode: 0755]
components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt [moved from components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/CapabilityCli.kt with 92% similarity]
components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCliDefinitions.kt [moved from components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/CapabilityCliDefinitions.kt with 95% similarity]
components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-deploy-restconf-mount-template.vtl [deleted file]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/Distribution/cba_zip.xml [new file with mode: 0755]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/DeviceResourceDefinitions.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/ResourceAuditDefinitions.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/functions/ResourceAuditFunctions.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/processor/RAProcessor.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/README.md [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/artifact_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/data_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-mapping.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/echo-test.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/node_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/policy_types.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/policy_types.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/relationship_types.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/relationship_types.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/echo/Definitions/resources_definition_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Plans/TEST_echo.xml [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Templates/echo-template.vtl [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/echo/Tests/uat.yaml [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/activation-blueprint.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/activation-blueprint.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/artifact_types.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/artifact_types.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-assign-pnf-mapping.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-assign-pnf-mapping.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/config-deploy-pnf-mapping.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/config-deploy-pnf-mapping.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/data_types.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/data_types.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/node_types.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/node_types.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/policy_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/relationship_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Definitions/resources_definition_types.json [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Definitions/resources_definition_types.json with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configAssign.xml [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configAssign.xml with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Plans/CONFIG_configDeploy.xml [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Plans/CONFIG_configDeploy.xml with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Scripts/python/RestconfConfigDeploy.py [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py with 96% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/TOSCA-Metadata/TOSCA.meta [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/TOSCA-Metadata/TOSCA.meta with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-assign-restconf-configlet-template.vtl [moved from components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Templates/config-assign-restconf-configlet-template.vtl with 100% similarity]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Templates/config-deploy-restconf-mount-template.vtl [new file with mode: 0644]
components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml [new file with mode: 0644]
components/parent/pom.xml
components/scripts/python/ccsdk_restconf/restconf_client.py
ms/blueprintsprocessor/application/pom.xml
ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTests.kt [new file with mode: 0644]
ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/CollectionUtils2.kt [new file with mode: 0644]
ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ExtendedTemporaryFolder.kt [new file with mode: 0644]
ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/TestSecuritySettings.kt [new file with mode: 0644]
ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/WorkingFoldersInitializer.kt [new file with mode: 0644]
ms/blueprintsprocessor/application/src/test/resources/application-test.properties [new file with mode: 0644]
ms/blueprintsprocessor/application/src/test/resources/logback-test.xml
ms/blueprintsprocessor/cba-parent/pom.xml [new file with mode: 0644]
ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorDSL.kt
ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorDSLTest.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt [deleted file]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponentDSL.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceDSL.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.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/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSLTest.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponentDSLTest.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceDSLTest.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt
ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt
ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/MessagingControllerTest.kt
ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentScriptExecutorDSL.kt
ms/blueprintsprocessor/parent/pom.xml
ms/blueprintsprocessor/pom.xml
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintExtensionFunctions.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/FileExtensionFunctions.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/annotations/BluePrintsAnnotations.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/AbstractNodeTemplateOperationImplBuilder.kt [moved from ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/AbstractNodeTemplateImplBuilder.kt with 59% similarity]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintDSL.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintServiceDSLBuilder.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintTemplateDSLBuilder.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintWorkflowDSLBuilder.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt
ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/annotations/BluePrintsAnnotationsTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintDSLTest.kt
ms/controllerblueprints/modules/db-resources/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/db/resources/BlueprintCatalogServiceImpl.kt
ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt
ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt
ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt
ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
ms/controllerblueprints/parent/pom.xml

index 1c36306..df3aafb 100644 (file)
@@ -23,7 +23,9 @@ import { Component, OnInit, ViewChild, EventEmitter, Output } from '@angular/cor
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { SearchTemplateService } from '../search-template.service';
 import { MatAutocompleteTrigger } from '@angular/material';
+import { NotificationHandlerService } from 'src/app/common/core/services/notification-handler.service';
 import { SearchPipe } from 'src/app/common/shared/pipes/search.pipe';
+
 @Component({
   selector: 'app-search-from-database',
   templateUrl: './search-from-database.component.html',
@@ -38,7 +40,7 @@ export class SearchFromDatabaseComponent implements OnInit {
 
   searchText: string = '';
   constructor(private _formBuilder: FormBuilder,
-    private searchService: SearchTemplateService) { }
+    private searchService: SearchTemplateService, private alertService: NotificationHandlerService, ) { }
 
   ngOnInit() {
     this.myControl = this._formBuilder.group({
@@ -50,18 +52,21 @@ export class SearchFromDatabaseComponent implements OnInit {
   }
 
   fetchResourceByName() {
+    this.options = [];
     this.searchService.searchByTags(this.searchText)
       .subscribe(data => {
-        // console.log(data);
         data.forEach(element => {
           this.options.push(element)
         });
-        // this.resourceSelect.openPanel();
       }, error => {
-        window.alert('error' + error);
+        this.alertService.error('Blueprint not matching the search tag' + error);
       })
-  console.log(this.options)
-    // this.options=['test','vns','capability','hello','hi','hoi','dfagfagshdgfashdf','adsfhksd'];
   }
 
+  editCBA(artifactname: string,option : string) {
+    
+  }
+
+
+
 }
index 1e8f469..101bf06 100644 (file)
@@ -19,7 +19,7 @@ limitations under the License.
 ============LICENSE_END============================================
 -->
 <mat-radio-group>
-    <mat-radio-button value="1" (click)="selected(1)">Upload From local</mat-radio-button><br> <br>
-    <mat-radio-button value="2" (click)="selected(2)">Existing Template File</mat-radio-button><br> <br>
-    <mat-radio-button value="3" (click)="selected(3)">Create New</mat-radio-button>
+    <mat-radio-button value="1" (click)="selected(1)">Upload from local</mat-radio-button><br> <br>
+    <mat-radio-button value="2" (click)="selected(2)">Search from Existing Template </mat-radio-button><br> <br>
+    <mat-radio-button value="3" (click)="selected(3)">Create new</mat-radio-button>
 </mat-radio-group>
\ No newline at end of file
index 3b598b2..58fd57b 100644 (file)
@@ -19,8 +19,8 @@ limitations under the License.
 ============LICENSE_END============================================
 */
 
-import { Component, OnInit, Output, EventEmitter} from '@angular/core';
-import { HttpClient } from '@angular/common/http';
+import { Component, OnInit, Output, EventEmitter } from '@angular/core';
+
 @Component({
   selector: 'app-template-options',
   templateUrl: './template-options.component.html',
@@ -35,11 +35,7 @@ export class TemplateOptionsComponent implements OnInit {
   ngOnInit() {
   }
 
-  selected(value){
-    console.log(value);
+  selected(value) {
     this.option.emit(value);
   }
-  // loadTemplateData() {
-  //  // to do
-  // }
 }
index 6762f7c..e155ec1 100644 (file)
@@ -39,7 +39,7 @@ import { IEntrySchema } from 'src/app/common/core/store/models/entrySchema.model
 })
 export class ResourceMetadataComponent implements OnInit {
     entry_schema:IEntrySchema;
-    properties: IPropertyData;
+    properties: any = {};
     ResourceMetadata: FormGroup;
     resource_name: string;
     tags: string;
@@ -68,15 +68,22 @@ export class ResourceMetadataComponent implements OnInit {
         this.resource_name = resourcesState.resources.name;
         this.tags = resourcesState.resources.tags;
         this.resources = resourcesState.resources;
-        this.properties= resourcesState.resources.property;
-        this.propertyValues=  this.checkNested(this.properties);
+        if (resourcesState.resources.definition && resourcesState.resources.definition.property) {
+         this.properties= resourcesState.resources.definition.property;
+        } else {
+           this.properties['description']= '';
+           this.properties['type'] = '';
+           this.properties['entry_schema'] = '';
+           this.properties['required'] = false;
+        }
+      //   this.propertyValues=  this.checkNested(this.properties);
         this.ResourceMetadata = this.formBuilder.group({
         Resource_Name: [this.resource_name, Validators.required],
          _tags: [this.tags, Validators.required],
-         _description : [ this.propertyValues[0], Validators.required],
-         _type: [ this.propertyValues[1], Validators.required],
-         required: [ JSON.stringify(this.propertyValues[2]), Validators.required],
-         entry_schema: [this.propertyValues[3]]
+         _description : [ this.properties.description, Validators.required, ''],
+         _type: [ this.properties.type, Validators.required],
+         required: [ JSON.stringify(this.properties.required), Validators.required],
+         entry_schema: [this.properties.entry_schema]
       });   
     })
  }
@@ -85,10 +92,10 @@ export class ResourceMetadataComponent implements OnInit {
   
     this.resources.name = this.ResourceMetadata.value.Resource_Name;
     this.resources.tags = this.ResourceMetadata.value._tags;
-    this.resources.property.description = this.ResourceMetadata.value._description;
-    this.resources.property.type = this.ResourceMetadata.value._type;
-       this.resources.property.required = this.ResourceMetadata.value.required;
-       this.resources.property.entry_schema = this.ResourceMetadata.value.entry_schema;
+    this.resources.definition.property.description = this.ResourceMetadata.value._description;
+    this.resources.definition.property.type = this.ResourceMetadata.value._type;
+    this.resources.definition.property.required = this.ResourceMetadata.value.required;
+    this.resources.definition.property.entry_schema = this.ResourceMetadata.value.entry_schema;
        this.resourcesData.emit(this.resources); 
  }
    
index 1d41ae7..943b20e 100644 (file)
@@ -34,184 +34,213 @@ import { JsonEditorComponent, JsonEditorOptions } from 'ang-jsoneditor';
 import { ResourceEditService } from '../resource-edit.service';
 
 @Component({
-  selector: 'app-sources-template',
-  templateUrl: './sources-template.component.html',
-  styleUrls: ['./sources-template.component.scss']
+   selector: 'app-sources-template',
+   templateUrl: './sources-template.component.html',
+   styleUrls: ['./sources-template.component.scss']
 })
 export class SourcesTemplateComponent implements OnInit {
 
-    @ViewChild(JsonEditorComponent) editor: JsonEditorComponent;
-    options = new JsonEditorOptions(); 
-    rdState: Observable<IResourcesState>;
-    resources: IResources;
-    option = [];
-    sources:ISourcesData; 
-    sourcesOptions = [];
-    sourcesData = {};
-    @Output() resourcesData = new EventEmitter();
-    tempOption = [];
-    constructor(private store: Store<IAppState>, private apiService: ResourceEditService) {
-    this.rdState = this.store.select('resources');
-    this.options.mode = 'text';
-    this.options.modes = [ 'text', 'tree', 'view'];
-    this.options.statusBar = false;     
- }
+   @ViewChild(JsonEditorComponent) editor: JsonEditorComponent;
+   options = new JsonEditorOptions();
+   rdState: Observable<IResourcesState>;
+   resources: IResources;
+   option = [];
+   sources: ISourcesData;
+   sourcesOptions = [];
+   sourcesData = {};
+   @Output() resourcesData = new EventEmitter();
+   tempOption = [];
 
- ngOnInit() {
-    this.rdState.subscribe(
-      resourcesdata => {
-        var resourcesState: IResourcesState = { resources: resourcesdata.resources, isLoadSuccess: resourcesdata.isLoadSuccess, isSaveSuccess: resourcesdata.isSaveSuccess, isUpdateSuccess: resourcesdata.isUpdateSuccess };
-        this.resources=resourcesState.resources;
-         if(resourcesState.resources.definition && resourcesState.resources.definition.sources) {
-         this.sources = resourcesState.resources.definition.sources;
-         }
-        for (let key in this.sources) {
-            let source = {
-               name : key,
-               data: this.sources[key]
+   constructor(private store: Store<IAppState>, private apiService: ResourceEditService) {
+      this.rdState = this.store.select('resources');
+      this.options.mode = 'text';
+      this.options.modes = ['text', 'tree', 'view'];
+      this.options.statusBar = false;
+   }
+
+   ngOnInit() {
+      this.rdState.subscribe(
+         resourcesdata => {
+            var resourcesState: IResourcesState = { resources: resourcesdata.resources, isLoadSuccess: resourcesdata.isLoadSuccess, isSaveSuccess: resourcesdata.isSaveSuccess, isUpdateSuccess: resourcesdata.isUpdateSuccess };
+            this.resources = resourcesState.resources;
+            if (resourcesState.resources.definition && resourcesState.resources.definition.sources) {
+               this.sources = resourcesState.resources.definition.sources;
             }
-             this.sourcesOptions.push(source);    
-        }
-    })
- }
+            this.sourcesOptions = [];
+            for (let key in this.sources) {
+               let source = {
+                  name: key,
+                  data: this.sources[key]
+               }
+               this.sourcesOptions.push(source);
+            }
+         })
+   }
 
onChange(item,$event) {
-    var editedData =JSON.parse($event.srcElement.value);
-    var originalSources = this.resources.sources;
-     for (let key in originalSources){
-        if(key == item){
  onChange(item, $event) {
+      var editedData = JSON.parse($event.srcElement.value);
+      var originalSources = this.resources.definition.sources;
+      for (let key in originalSources) {
+         if (key == item.name) {
             originalSources[key] = editedData;
-        }
-     }
-     this.resources.sources = Object.assign({},originalSources);
- };
-    
- // to remove this method
- selected(sourceValue){
-   this.sourcesData= [];//this.sources[value];
-   this.apiService.getModelType(sourceValue.value)
-   .subscribe(data=>{
-      console.log(data);
-      data.forEach(item =>{
-        if(typeof(item)== "object") {
-           for (let key1 in item) {
-              if(key1 == 'properties') {                  
-                 let newPropOnj = {}
-                 for (let key2 in item[key1]) {
-                    console.log(item[key1][key2]);
-                    let varType = item[key1][key2].type
-                    // let property :  varType = 
-                    newPropOnj[key2] = item[key1][key2];
-                 }
-              }
-           }
-        }
-      });
-      this.sourcesData = data;
-      this.sourcesOptions.forEach(item=>{
-         if(item.name == sourceValue.name) {
-            item.data = data;
          }
-      })       
-     return this.sourcesData;
-   })    
-}    
+      }
+      this.resources.definition.sources = Object.assign({}, originalSources);
 
- delete(item,i){
-       if(confirm("Are sure you want to delete this source ?")) {
-       var originalSources = this.resources.sources;
-       for (let key in originalSources){
-               if(key == item){    
-                       delete originalSources[key];
-               }
-       }
-       this.resources.sources = Object.assign({},originalSources);
-               this.sourcesOptions.splice(i,1);
-       }     
- } 
-  
- UploadSourcesData() {
-       this.resourcesData.emit(this.resources);        
-  }
-    
- drop(event: CdkDragDrop<string[]>) {
-   if (!this.checkIfSourceExists(event.item.element.nativeElement.innerText)) {
-      if (event.previousContainer === event.container) {
-         moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
-      } else {
-         transferArrayItem(event.previousContainer.data,
-            event.container.data,
-            event.previousIndex,
-            event.currentIndex);
+      let resourcesState = {
+         resources: this.resources,
+         isLoadSuccess: true,
+         isUpdateSuccess: true,
+         isSaveSuccess: true
       }
-      this.tempOption.forEach((item) => {
-         if (item.name == event.item.element.nativeElement.innerText) {
-            this.apiService.getModelType(item.value)
-               .subscribe(data => {
-                  console.log(data);
-                  data.forEach(dataitem => {
-                     if (typeof (dataitem) == "object") {
-                        for (let key1 in dataitem) {
-                           if (key1 == 'properties') {
-                              let newPropObj = {};
-                              newPropObj["name"] = event.item.element.nativeElement.innerText;
-                              newPropObj['data'] = {};
-                              let newSoruceObj = {};
-                              for (let key2 in dataitem[key1]) {
-                                 newSoruceObj[key2] = '';;
-                              }
-                              newPropObj['data']['properties'] = newSoruceObj;
-                              this.sourcesOptions.forEach(sourcesOptionsitem => {
-                                 if (sourcesOptionsitem.name == item.name) {
-                                    sourcesOptionsitem.data = newPropObj['data'];
+      this.store.dispatch(new SetResourcesState(resourcesState));
+   };
+
+   // to remove this method
+   selected(sourceValue) {
+      this.sourcesData = [];//this.sources[value];
+      this.apiService.getModelType(sourceValue.value)
+         .subscribe(data => {
+            console.log(data);
+            data.forEach(item => {
+               if (typeof (item) == "object") {
+                  for (let key1 in item) {
+                     if (key1 == 'properties') {
+                        let newPropOnj = {}
+                        for (let key2 in item[key1]) {
+                           console.log(item[key1][key2]);
+                           let varType = item[key1][key2].type
+                           // let property :  varType = 
+                           newPropOnj[key2] = item[key1][key2];
+                        }
+                     }
+                  }
+               }
+            });
+            this.sourcesData = data;
+            this.sourcesOptions.forEach(item => {
+               if (item.name == sourceValue.name) {
+                  item.data = data;
+               }
+            })
+            return this.sourcesData;
+         })
+   }
+
+   delete(item, i) {
+      if (confirm("Are sure you want to delete this source ?")) {
+         var originalSources = this.resources.definition.sources;
+         for (let key in originalSources) {
+            if (key == item.name) {
+               delete originalSources[key];
+            }
+         }
+         this.resources.definition.sources = Object.assign({}, originalSources);
+         this.sourcesOptions.splice(i, 1);
+         if (!this.checkIfSourceExists(this.option, item.name)) {
+            this.tempOption.forEach(tempOptionitem => {
+               if (tempOptionitem.name == item.name) {
+                  this.option.push(tempOptionitem);
+               }
+            });
+         }
+         let newsources = {};
+         this.sourcesOptions.forEach(sourceItem => {
+            newsources[sourceItem.name] = {};
+            newsources[sourceItem.name] = sourceItem.data;
+         });
+         this.resources.definition.sources = newsources;
+         let resourcesState = {
+            resources: this.resources,
+            isLoadSuccess: true,
+            isUpdateSuccess: true,
+            isSaveSuccess: true
+         }
+         this.store.dispatch(new SetResourcesState(resourcesState));
+      }
+   }
+
+   UploadSourcesData() {
+      this.resourcesData.emit(this.resources);
+   }
+
+   drop(event: CdkDragDrop<string[]>) {
+      if (!this.checkIfSourceExists(this.sourcesOptions, event.item.element.nativeElement.innerText)) {
+         if (event.previousContainer === event.container) {
+            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
+         } else {
+            transferArrayItem(event.previousContainer.data,
+               event.container.data,
+               event.previousIndex,
+               event.currentIndex);
+         }
+         this.tempOption.forEach((item) => {
+            if (item.name == event.item.element.nativeElement.innerText) {
+               this.apiService.getModelType(item.value)
+                  .subscribe(data => {
+                     console.log(data);
+                     data.forEach(dataitem => {
+                        if (typeof (dataitem) == "object") {
+                           for (let key1 in dataitem) {
+                              if (key1 == 'properties') {
+                                 let newPropObj = {};
+                                 newPropObj["name"] = event.item.element.nativeElement.innerText;
+                                 newPropObj['data'] = {};
+                                 let newSoruceObj = {};
+                                 for (let key2 in dataitem[key1]) {
+                                    newSoruceObj[key2] = '';;
                                  }
-                              });
+                                 newPropObj['data']['properties'] = newSoruceObj;
+                                 this.sourcesOptions.forEach(sourcesOptionsitem => {
+                                    if (sourcesOptionsitem.name == item.name) {
+                                       sourcesOptionsitem.data = newPropObj['data'];
+                                    }
+                                 });
+                              }
                            }
                         }
+                     });
+                     let newsources = {};
+                     this.sourcesOptions.forEach(sourceItem => {
+                        console
+                        newsources[sourceItem.name] = {};
+                        newsources[sourceItem.name] = sourceItem.data;
+                     });
+                     this.resources.definition.sources = newsources;
+                     let resourcesState = {
+                        resources: this.resources,
+                        isLoadSuccess: true,
+                        isUpdateSuccess: true,
+                        isSaveSuccess: true
                      }
+                     this.store.dispatch(new SetResourcesState(resourcesState));
                   });
-                  let newsources= {};
-                  this.sourcesOptions.forEach(sourceItem=>{
-                     console
-                     newsources[sourceItem.name] = {};
-                     newsources[sourceItem.name] = sourceItem.data;
-                  });
-                  this.resources.definition.sources = newsources;
-                  let resourcesState = {
-                     resources: this.resources,
-                     isLoadSuccess: true,
-                     isUpdateSuccess:true,
-                     isSaveSuccess:true
-                  }  
-                  this.store.dispatch(new SetResourcesState(resourcesState));
-            });
-         }  
-      });
+            }
+         });
+      }
    }
-  }
 
-  getResources() {
-   this.apiService.getSources()
-   .subscribe(data=>{
-      console.log(data);
-      for (let key in data[0]) {
-         let sourceObj = { name: key, value: data[0][key] }
-         this.option.push(sourceObj);
-         this.tempOption.push(sourceObj); 
-     }
-   }, error=>{
-      console.log(error);
-   })
-  }
+   getResources() {
+      this.apiService.getSources()
+         .subscribe(data => {
+            console.log(data);
+            for (let key in data[0]) {
+               let sourceObj = { name: key, value: data[0][key] }
+               this.option.push(sourceObj);
+               this.tempOption.push(sourceObj);
+            }
+         }, error => {
+            console.log(error);
+         })
+   }
 
-  checkIfSourceExists(sourceName) {
-   let sourceExists: boolean = false;
-   this.sourcesOptions.forEach(item => {
-      if (item.name == sourceName) {
-         sourceExists = true;
-      }
-   });
-   return sourceExists;
-}
+   checkIfSourceExists(sourceList, sourceName) {
+      let sourceExists: boolean = false;
+      sourceList.forEach(item => {
+         if (item.name == sourceName) {
+            sourceExists = true;
+         }
+      });
+      return sourceExists;
+   }
 }
index 24aeb26..0c02381 100644 (file)
@@ -30,7 +30,7 @@ export const controllerApiConfig = Object.freeze({
 
 export const processorApiConfig = Object.freeze({
     http: Object.freeze({
-        url: process.env.API_BLUEPRINT_PROCESSOR_HTTP_BASE_URL || "http://localhost:8081/api/v1",
+        url: process.env.API_BLUEPRINT_PROCESSOR_HTTP_BASE_URL || "http://localhost:8080/api/v1",
         authToken: process.env.API_BLUEPRINT_PROCESSOR_HTTP_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw=="
     }),
     grpc: Object.freeze({
index ceb7051..df50fea 100644 (file)
@@ -90,7 +90,7 @@
                 },
                 "inputs": {
                   "script-type": "kotlin",
-                  "script-class-reference": "cba.scripts.capability.cli.Check"
+                  "script-class-reference": "cba.capability.cli.Check"
                 },
                 "outputs": {
                   "response-data": "",
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Distribution/cba_zip.xml b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Distribution/cba_zip.xml
new file mode 100755 (executable)
index 0000000..c6c3bde
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright © 2019 IBM.
+  ~
+  ~  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.
+  -->
+
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+    <!-- create a tar.gz file containing the projects dependencies -->
+    <id>cba</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>${project.basedir}</directory>
+            <includes>
+                <include>Definitions/**</include>
+                <include>Distribution/**</include>
+                <include>Environments/**</include>
+                <include>Plans/**</include>
+                <include>Others/**</include>
+                <include>Scripts/**</include>
+                <include>Templates/**</include>
+                <include>TOSCA-Metadata/**</include>
+                <include>pom.xml</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
  *  limitations under the License.
  */
 
-package cba.scripts.capability.cli
+package cba.capability.cli
 
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction
-import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor
 import org.onap.ccsdk.cds.blueprintsprocessor.ssh.sshClientService
-import org.onap.ccsdk.cds.controllerblueprints.core.*
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 
 
@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package cba.scripts.capability.cli
+package cba.capability.cli
 
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTemplateComponentScriptExecutor
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTypeComponentScriptExecutor
@@ -64,10 +64,10 @@ fun CapabilityCliDefinitions.defaultServiceTemplate() =
                 }
 
                 val checkComponent = BluePrintTypes.nodeTemplateComponentScriptExecutor(id = "check", description = "") {
-                    operation(description = "") {
+                    definedOperation(description = "") {
                         inputs {
                             type("kotlin")
-                            scriptClassReference("cba.scripts.capability.cli.Check")
+                            scriptClassReference("cba.capability.cli.Check")
                         }
                         outputs {
                             status(getAttribute("status"))
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml
new file mode 100644 (file)
index 0000000..2cb19bc
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright © 2019 IBM.
+  ~
+  ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+        <artifactId>cba-parent</artifactId>
+        <version>0.5.2-SNAPSHOT</version>
+    </parent>
+    <groupId>org.onap.ccsdk.cds.components.cba</groupId>
+    <artifactId>capability_cli</artifactId>
+    <name>CBA Capability CLI</name>
+    <description>CBA Capability CLI</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId>
+            <artifactId>cli-executor</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>cba</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <descriptors>
+                                <descriptor>Distribution/cba_zip.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
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 (file)
index ad03321..0000000
+++ /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/test-blueprint/resource-audit/Distribution/cba_zip.xml b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Distribution/cba_zip.xml
new file mode 100755 (executable)
index 0000000..c6c3bde
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright © 2019 IBM.
+  ~
+  ~  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.
+  -->
+
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+    <!-- create a tar.gz file containing the projects dependencies -->
+    <id>cba</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>${project.basedir}</directory>
+            <includes>
+                <include>Definitions/**</include>
+                <include>Distribution/**</include>
+                <include>Environments/**</include>
+                <include>Plans/**</include>
+                <include>Others/**</include>
+                <include>Scripts/**</include>
+                <include>Templates/**</include>
+                <include>TOSCA-Metadata/**</include>
+                <include>pom.xml</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/DeviceResourceDefinitions.kt b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/DeviceResourceDefinitions.kt
new file mode 100644 (file)
index 0000000..a0ca167
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package cba.resource.audit
+
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceDefinitions
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+
+const val SOURCE_SDNO = "SDN-O"
+const val SOURCE_SDNC = "SDNC"
+const val SOURCE_AAI = "AAI"
+
+val deviceResourceDefinitions = BluePrintTypes.resourceDefinitions {
+    // Port Speed Definitions
+    resourceDefinition(name = "port-speed", description = "Port Speed") {
+        property(type = "string", required = true)
+        sources {
+            sourceCapability(id = SOURCE_SDNO, description = "SDN-O Source") {
+                definedProperties {
+                    type(BluePrintConstants.SCRIPT_KOTLIN)
+                    scriptClassReference("cba.resource.audit.processor.PortSpeedRAProcessor")
+                    keyDependencies(arrayListOf("device-id"))
+                }
+            }
+            sourceDb(id = SOURCE_SDNC, description = "SDNC Controller") {
+                definedProperties {
+                    endpointSelector("processor-db")
+                    query("SELECT PORT_SPEED FROM XXXX WHERE DEVICE_ID = :device_id")
+                    inputKeyMapping {
+                        map("device_id", "\$device-id")
+                    }
+                    keyDependencies(arrayListOf("device-id"))
+                }
+            }
+            sourceRest(id = SOURCE_AAI, description = "AAI Source") {
+                definedProperties {
+                    endpointSelector("aai")
+                    urlPath("/vnf/\$device_id")
+                    path(".\$port-speed")
+                    inputKeyMapping {
+                        map("device_id", "\$device-id")
+                    }
+                    keyDependencies(arrayListOf("device-id"))
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/ResourceAuditDefinitions.kt b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/ResourceAuditDefinitions.kt
new file mode 100644 (file)
index 0000000..61783d6
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package cba.resource.audit
+
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTemplateComponentScriptExecutor
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTypeComponentScriptExecutor
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getAttribute
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getNodeTemplateAttribute
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeTypeComponent
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.serviceTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.AbstractBluePrintDefinitions
+
+class ResourceAuditDefinitions : AbstractBluePrintDefinitions() {
+    override fun serviceTemplate(): ServiceTemplate {
+        return defaultServiceTemplate()
+    }
+}
+
+fun ResourceAuditDefinitions.defaultServiceTemplate() =
+        serviceTemplate(name = "resource-audit",
+                version = "1.0.0",
+                author = "Brinda Santh Muthuramalingam",
+                tags = "brinda, tosca") {
+
+            topologyTemplate {
+
+                workflow(id = "config-collect", description = "Collect the configuration for Device") {
+                    inputs {
+                        property(id = "device-id", type = BluePrintConstants.DATA_TYPE_STRING, required = true, description = "")
+                        property(id = "sources", type = BluePrintConstants.DATA_TYPE_LIST, required = true, description = "") {
+                            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+                        }
+                    }
+                    outputs {
+                        property(id = "response-data", required = true, type = BluePrintConstants.DATA_TYPE_STRING, description = "") {
+                            value(getNodeTemplateAttribute(nodeTemplateId = "config-collector",
+                                    attributeId = ComponentScriptExecutor.ATTRIBUTE_RESPONSE_DATA))
+                        }
+                        property(id = "status", required = true, type = BluePrintConstants.DATA_TYPE_STRING, description = "") {
+                            value(BluePrintConstants.STATUS_SUCCESS)
+                        }
+                    }
+                    step(id = "config-collector", target = "config-collector", description = "Collect the Configuration")
+                }
+
+                val configCollectorComponent = BluePrintTypes.nodeTemplateComponentScriptExecutor(
+                        id = "config-collector", description = "Config collector component") {
+
+                    definedOperation(description = "Config Collector Operation") {
+                        inputs {
+                            type(BluePrintConstants.SCRIPT_KOTLIN)
+                            scriptClassReference("cba.resource.audit.functions.ConfigCollector")
+                        }
+                        outputs {
+                            status(getAttribute(ComponentScriptExecutor.ATTRIBUTE_STATUS))
+                            responseData(getAttribute(ComponentScriptExecutor.ATTRIBUTE_RESPONSE_DATA))
+                        }
+                    }
+                }
+                nodeTemplate(configCollectorComponent)
+            }
+
+            nodeType(BluePrintTypes.nodeTypeComponent())
+            nodeType(BluePrintTypes.nodeTypeComponentScriptExecutor())
+        }
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/functions/ResourceAuditFunctions.kt b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/functions/ResourceAuditFunctions.kt
new file mode 100644 (file)
index 0000000..49d0c73
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package cba.resource.audit.functions
+
+import cba.resource.audit.deviceResourceDefinitions
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+
+class ConfigCollector : AbstractScriptComponentFunction() {
+
+    val log = logger(ConfigCollector::class)
+
+    override suspend fun processNB(executionRequest: ExecutionServiceInput) {
+
+        val deviceId = bluePrintRuntimeService.getInputValue("device-id").textValue()
+        val sources = bluePrintRuntimeService.getInputValue("sources")
+
+        log.info("Processing Config Collection for device($deviceId), for sources($sources)")
+        deviceResourceDefinitions.forEach { name, resourceDefinition ->
+            log.info("collecting for the property : $name")
+            resourceDefinition.sources.forEach { sourceName, source ->
+                log.info("collecting for the Source : $sourceName")
+            }
+        }
+
+        // Set the Attributes
+        setAttribute(ComponentScriptExecutor.ATTRIBUTE_STATUS, BluePrintConstants.STATUS_SUCCESS.asJsonPrimitive())
+        setAttribute(ComponentScriptExecutor.ATTRIBUTE_RESPONSE_DATA, """{
+                      "port-speed" : "10MBS"
+        }""".trimIndent().jsonAsJsonType())
+
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
+
+    }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/processor/RAProcessor.kt b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/Scripts/kotlin/cba/resource/audit/processor/RAProcessor.kt
new file mode 100644 (file)
index 0000000..660f591
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package cba.resource.audit.processor
+
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+
+class PortSpeedRAProcessor : ResourceAssignmentProcessor() {
+    val log = logger(PortSpeedRAProcessor::class)
+    override fun getName(): String {
+        return "PortSpeedRAProcessor"
+    }
+
+    override suspend fun processNB(executionRequest: ResourceAssignment) {
+        log.info("Executing Resource PortSpeedRAProcessor")
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..d2f533c
--- /dev/null
@@ -0,0 +1,7 @@
+TOSCA-Meta-File-Version: 1.0.0
+CSAR-Version: 1.0
+Created-By: Brinda Santh
+Entry-Definitions: cba.resource.audit.ResourceAuditDefinitions.kt
+Template-Name: resource-audit
+Template-Version: 1.0.0
+Template-Tags: resource-audit
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml
new file mode 100644 (file)
index 0000000..6ec41a6
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright © 2019 IBM.
+  ~
+  ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+        <artifactId>cba-parent</artifactId>
+        <version>0.5.2-SNAPSHOT</version>
+    </parent>
+    <groupId>org.onap.ccsdk.cds.components.cba</groupId>
+    <artifactId>resource-audit</artifactId>
+    <name>CBA Resource Audit</name>
+    <description>CBA Resource Audit</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId>
+            <artifactId>resource-resolution</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>cba</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <descriptors>
+                                <descriptor>Distribution/cba_zip.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
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 (file)
index 0000000..d6a3352
--- /dev/null
@@ -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 (file)
index 0000000..6ec3b41
--- /dev/null
@@ -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 (file)
index 0000000..24f5019
--- /dev/null
@@ -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 (file)
index 0000000..02f2b49
--- /dev/null
@@ -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 (file)
index 0000000..3105484
--- /dev/null
@@ -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 (file)
index 0000000..a3fc254
--- /dev/null
@@ -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/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 (file)
index 0000000..4b0cf47
--- /dev/null
@@ -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 (file)
index 0000000..4305c7d
--- /dev/null
@@ -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 (file)
index 0000000..769d464
--- /dev/null
@@ -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 (file)
index 0000000..9e2dcc1
--- /dev/null
@@ -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 (file)
index 0000000..1162309
--- /dev/null
@@ -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/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 (file)
index 0000000..1e44cc7
--- /dev/null
@@ -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 (file)
index 0000000..4ddd7a5
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "relationship_types" : { }
+}
\ No newline at end of file
@@ -14,8 +14,6 @@
 # limitations under the License.
 # ============LICENSE_END=========================================================
 
-from org.onap.ccsdk.cds.blueprintsprocessor.functions.restconf.executor import \
-    RestconfComponentFunction
 from java.lang import Exception as JavaException
 
 from restconf_client import RestconfClient
@@ -39,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/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 (file)
index 0000000..8098b05
--- /dev/null
@@ -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 (file)
index 0000000..37029e1
--- /dev/null
@@ -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
index 3e6f710..ef030cd 100644 (file)
     <name>Components Parent</name>
     <packaging>pom</packaging>
     <properties>
-        <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
-        <grpc.version>1.18.0</grpc.version>
-        <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version>
         <eelf.version>1.0.0</eelf.version>
         <guava.version>27.0.1-jre</guava.version>
         <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
         <h2database.version>1.4.197</h2database.version>
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
-        <mockk.version>1.9</mockk.version>
         <velocity.version>1.7</velocity.version>
         <jinja.version>2.5.1</jinja.version>
     </properties>
                 <artifactId>commons-io</artifactId>
                 <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>
             <groupId>commons-io</groupId>
             <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>
index ec25853..927c1fe 100644 (file)
@@ -34,18 +34,18 @@ class RestconfClient:
         self.__component_function = restconf_component_function
 
     def web_client_service(self, identifier):
-        RestconfExecutorExtensionsKt.restconfClientService(self.__component_function, identifier)
+        return RestconfExecutorExtensionsKt.restconfClientService(self.__component_function, identifier)
 
     def resolve_and_generate_message_from_template_prefix(self, artifact_prefix):
-            return ResourceResolutionExtensionsKt.contentFromResolvedArtifact(self.component_function, artifact_prefix)
+        return ResourceResolutionExtensionsKt.contentFromResolvedArtifact(self.__component_function, artifact_prefix)
 
     def retrieve_resolved_template_from_database(self, key, artifact_template):
-        return ResourceResolutionExtensionsKt.storedContentFromResolvedArtifact(self.component_function, key,
+        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)
@@ -55,6 +55,7 @@ class RestconfClient:
         counter = 0
         url = self.__odl_status_check_url + nf_id
         self.__log.info("url for ODL status check: {}", url)
+        # TODO: allow JSON format change
         expected_result = '"netconf-node-topology:connection-status":"connected"'
         while counter < self.__odl_status_check_limit:
             result = web_client_service.exchangeResource("GET", url, "")
index 4e48730..a504ce3 100755 (executable)
             <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 (file)
index 0000000..0a57277
--- /dev/null
@@ -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 (file)
index 0000000..63d64ca
--- /dev/null
@@ -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 (file)
index 0000000..4576f27
--- /dev/null
@@ -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 (file)
index 0000000..f7ab255
--- /dev/null
@@ -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 (file)
index 0000000..37615cb
--- /dev/null
@@ -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 (file)
index 0000000..b8b80f2
--- /dev/null
@@ -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
index 16e7d3d..eaa51c0 100644 (file)
@@ -1,5 +1,6 @@
 <!--\r
   ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~ Modifications Copyright (C) 2019 Nordix Foundation.\r
   ~\r
   ~ Licensed under the Apache License, Version 2.0 (the "License");\r
   ~ you may not use this file except in compliance with the License.\r
 \r
 <configuration>\r
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">\r
-        <!-- encoders are assigned the type\r
-             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->\r
         <encoder>\r
-            <pattern>%d{HH:mm:ss.SSS} %-5level [%thread]  %logger{50} - %msg%n</pattern>\r
+            <pattern>%d{HH:mm:ss.SSS} %-5level %-40.40logger{39} : %msg%n</pattern>\r
         </encoder>\r
     </appender>\r
 \r
+    <logger name="org.springframework.web.HttpLogging" level="trace"/>\r
+    <logger name="org.springframework.web.reactive.function.client.ExchangeFunctions" level="trace"/>\r
 \r
-    <logger name="org.springframework" level="warn"/>\r
-    <logger name="org.hibernate" level="info"/>\r
-    <logger name="org.onap.ccsdk.cds.blueprintsprocessor" level="info"/>\r
+    <!-- Helpful to optimize Spring Context caching to speed-up tests\r
+         and prevent resorting to @DirtiesContext as much as possible -->\r
+    <logger name="org.springframework.test.context.cache" level="debug"/>\r
 \r
-    <root level="warn">\r
+    <!-- Please refer to https://thoughts-on-java.org/hibernate-logging-guide/\r
+         for a lengthy discussion on good Hibernate logging practices -->\r
+    <logger name="org.hibernate.SQL" level="debug"/>\r
+    <logger name="org.hibernate.type.descriptor.sql" level="trace"/>\r
+\r
+    <root level="info">\r
         <appender-ref ref="STDOUT"/>\r
     </root>\r
 \r
diff --git a/ms/blueprintsprocessor/cba-parent/pom.xml b/ms/blueprintsprocessor/cba-parent/pom.xml
new file mode 100644 (file)
index 0000000..7605791
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright © 2019 IBM.
+  ~
+  ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+        <artifactId>parent</artifactId>
+        <version>0.5.2-SNAPSHOT</version>
+        <relativePath>../parent</relativePath>
+    </parent>
+    <artifactId>cba-parent</artifactId>
+    <name>CBA Parent</name>
+    <packaging>pom</packaging>
+
+    <build>
+        <sourceDirectory>${project.basedir}/Scripts/kotlin</sourceDirectory>
+        <testSourceDirectory>${project.basedir}/Tests/kotlin</testSourceDirectory>
+        <resources>
+            <resource>
+                <directory>${project.basedir}/Environments</directory>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-maven-plugin</artifactId>
+                <version>${kotlin.maven.version}</version>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>${project.basedir}/Scripts/kotlin</sourceDir>
+                            </sourceDirs>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>test-compile</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>test-compile</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>${project.basedir}/Tests/kotlin</sourceDir>
+                            </sourceDirs>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
index fee8749..c2055f9 100644 (file)
@@ -25,7 +25,7 @@ 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.NodeTemplate
 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
-import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateImplBuilder
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateOperationImplBuilder
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.dataType
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType
@@ -89,16 +89,11 @@ fun BluePrintTypes.dataTypeDtSystemPackages(): DataType {
 /** Component Builder */
 fun BluePrintTypes.nodeTemplateComponentRemotePythonExecutor(id: String,
                                                              description: String,
-                                                             block: ComponentRemotePythonExecutorNodeTemplateImplBuilder.() -> Unit)
+                                                             block: ComponentRemotePythonExecutorNodeTemplateBuilder.() -> Unit)
         : NodeTemplate {
-    return ComponentRemotePythonExecutorNodeTemplateImplBuilder(id, description).apply(block).build()
+    return ComponentRemotePythonExecutorNodeTemplateBuilder(id, description).apply(block).build()
 }
 
-class ComponentRemotePythonExecutorNodeTemplateImplBuilder(id: String, description: String) :
-        AbstractNodeTemplateImplBuilder<ComponentRemotePythonExecutorInputAssignmentBuilder,
-                ComponentRemotePythonExecutorOutputAssignmentBuilder>(id, "component-remote-python-executor",
-                "ComponentRemotePythonExecutor", description)
-
 class DtSystemPackageDataTypeBuilder : PropertiesAssignmentBuilder() {
 
     fun type(type: String) = type(type.asJsonPrimitive())
@@ -116,48 +111,55 @@ class DtSystemPackageDataTypeBuilder : PropertiesAssignmentBuilder() {
     }
 }
 
-class ComponentRemotePythonExecutorInputAssignmentBuilder : PropertiesAssignmentBuilder() {
+class ComponentRemotePythonExecutorNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplateOperationImplBuilder<PropertiesAssignmentBuilder, ComponentRemotePythonExecutorNodeTemplateBuilder.InputsBuilder,
+                ComponentRemotePythonExecutorNodeTemplateBuilder.OutputsBuilder>(id, "component-remote-python-executor",
+                "ComponentRemotePythonExecutor", description) {
 
-    private var packageList: ArrayNode? = null
+    class InputsBuilder : PropertiesAssignmentBuilder() {
 
-    fun endpointSelector(endpointSelector: String) = endpointSelector(endpointSelector.asJsonPrimitive())
+        private var packageList: ArrayNode? = null
 
-    fun endpointSelector(endpointSelector: JsonNode) {
-        property(ComponentRemotePythonExecutor.INPUT_ENDPOINT_SELECTOR, endpointSelector)
-    }
+        fun endpointSelector(endpointSelector: String) = endpointSelector(endpointSelector.asJsonPrimitive())
 
-    fun dynamicProperties(dynamicProperties: String) = dynamicProperties(dynamicProperties.asJsonType())
+        fun endpointSelector(endpointSelector: JsonNode) {
+            property(ComponentRemotePythonExecutor.INPUT_ENDPOINT_SELECTOR, endpointSelector)
+        }
 
-    fun dynamicProperties(dynamicProperties: JsonNode) {
-        property(ComponentRemotePythonExecutor.INPUT_DYNAMIC_PROPERTIES, dynamicProperties)
-    }
+        fun dynamicProperties(dynamicProperties: String) = dynamicProperties(dynamicProperties.asJsonType())
 
-    fun argumentProperties(argumentProperties: String) = argumentProperties(argumentProperties.asJsonType())
+        fun dynamicProperties(dynamicProperties: JsonNode) {
+            property(ComponentRemotePythonExecutor.INPUT_DYNAMIC_PROPERTIES, dynamicProperties)
+        }
 
-    fun argumentProperties(argumentProperties: JsonNode) {
-        property(ComponentRemotePythonExecutor.INPUT_ARGUMENT_PROPERTIES, argumentProperties)
-    }
+        fun argumentProperties(argumentProperties: String) = argumentProperties(argumentProperties.asJsonType())
 
-    fun command(command: String) = command(command.asJsonPrimitive())
+        fun argumentProperties(argumentProperties: JsonNode) {
+            property(ComponentRemotePythonExecutor.INPUT_ARGUMENT_PROPERTIES, argumentProperties)
+        }
 
-    fun command(command: JsonNode) {
-        property(ComponentRemotePythonExecutor.INPUT_COMMAND, command)
-    }
+        fun command(command: String) = command(command.asJsonPrimitive())
 
-    fun packages(block: DtSystemPackageDataTypeBuilder.() -> Unit) {
-        if (packageList == null)
-            packageList = JacksonUtils.objectMapper.createArrayNode()
-        val dtSysyemPackagePropertyAssignments = DtSystemPackageDataTypeBuilder().apply(block).build()
-        packageList!!.add(dtSysyemPackagePropertyAssignments.asJsonType())
-    }
+        fun command(command: JsonNode) {
+            property(ComponentRemotePythonExecutor.INPUT_COMMAND, command)
+        }
 
-    override fun build(): MutableMap<String, JsonNode> {
-        val propertyAssignments = super.build()
-        if (packageList != null) {
-            propertyAssignments[ComponentRemotePythonExecutor.INPUT_PACKAGES] = packageList!!
+        fun packages(block: DtSystemPackageDataTypeBuilder.() -> Unit) {
+            if (packageList == null)
+                packageList = JacksonUtils.objectMapper.createArrayNode()
+            val dtSysyemPackagePropertyAssignments = DtSystemPackageDataTypeBuilder().apply(block).build()
+            packageList!!.add(dtSysyemPackagePropertyAssignments.asJsonType())
+        }
+
+        override fun build(): MutableMap<String, JsonNode> {
+            val propertyAssignments = super.build()
+            if (packageList != null) {
+                propertyAssignments[ComponentRemotePythonExecutor.INPUT_PACKAGES] = packageList!!
+            }
+            return propertyAssignments
         }
-        return propertyAssignments
     }
-}
 
-class ComponentRemotePythonExecutorOutputAssignmentBuilder : PropertiesAssignmentBuilder()
\ No newline at end of file
+    class OutputsBuilder : PropertiesAssignmentBuilder()
+
+}
\ No newline at end of file
index 5c4b590..18eb77b 100644 (file)
@@ -33,7 +33,7 @@ class ComponentRemotePythonExecutorDSLTest {
     fun testNodeTemplateComponentRemotePythonExecutor() {
         val nodeTemplate = BluePrintTypes.nodeTemplateComponentRemotePythonExecutor("test-nodetemplate",
                 "test nodetemplate") {
-            operation("test operation") {
+            definedOperation("test operation") {
                 inputs {
                     endpointSelector("remote-container")
                     command("python sample.py")
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt
deleted file mode 100644 (file)
index 5f3a5cd..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.
- */
-
-package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
-
-import org.jetbrains.kotlin.script.util.DependsOn
-import org.jetbrains.kotlin.script.util.Repository
-import kotlin.script.experimental.annotations.KotlinScript
-import kotlin.script.experimental.api.ScriptCompilationConfiguration
-import kotlin.script.experimental.api.defaultImports
-import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
-import kotlin.script.experimental.jvm.jvm
-
-@KotlinScript(fileExtension = "resourceassignmentprocessor.kts",
-        compilationConfiguration = ResourceAssignmentProcessorScriptConfiguration::class)
-abstract class ResourceAssignmentProcessorScript {
-
-}
-
-object ResourceAssignmentProcessorScriptConfiguration : ScriptCompilationConfiguration(
-        {
-            defaultImports(DependsOn::class, Repository::class)
-            jvm {
-                dependenciesFromCurrentContext(
-                        wholeClasspath = true
-                )
-            }
-        }
-)
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt
new file mode 100644 (file)
index 0000000..141bad6
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertyDefinitionBuilder
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
+
+/** Resource Definition DSL **/
+fun BluePrintTypes.resourceDefinitions(block: ResourceDefinitionsBuilder.() -> Unit)
+        : MutableMap<String, ResourceDefinition> {
+    return ResourceDefinitionsBuilder().apply(block).build()
+}
+
+fun BluePrintTypes.resourceDefinition(name: String, description: String,
+                                      block: ResourceDefinitionBuilder.() -> Unit): ResourceDefinition {
+    return ResourceDefinitionBuilder(name, description).apply(block).build()
+}
+
+/** Resource Mapping DSL **/
+fun BluePrintTypes.resourceAssignments(block: ResourceAssignmentsBuilder.() -> Unit)
+        : MutableMap<String, ResourceAssignment> {
+    return ResourceAssignmentsBuilder().apply(block).build()
+}
+
+fun BluePrintTypes.resourceAssignment(name: String, dictionaryName: String, dictionarySource: String,
+                                      block: ResourceAssignmentBuilder.() -> Unit): ResourceAssignment {
+    return ResourceAssignmentBuilder(name, dictionaryName, dictionarySource).apply(block).build()
+}
+
+class ResourceDefinitionsBuilder() {
+    private val resourceDefinitions: MutableMap<String, ResourceDefinition> = hashMapOf()
+
+    fun resourceDefinition(name: String, description: String,
+                           block: ResourceDefinitionBuilder.() -> Unit) {
+        val resourceDefinition = ResourceDefinitionBuilder(name, description).apply(block).build()
+        resourceDefinitions[resourceDefinition.name] = resourceDefinition
+    }
+
+    fun resourceDefinition(resourceDefinition: ResourceDefinition) {
+        resourceDefinitions[resourceDefinition.name] = resourceDefinition
+    }
+
+    fun build(): MutableMap<String, ResourceDefinition> {
+        return resourceDefinitions
+    }
+}
+
+class ResourceDefinitionBuilder(private val name: String, private val description: String) {
+    private val resourceDefinition = ResourceDefinition()
+
+    fun updatedBy(updatedBy: String) {
+        resourceDefinition.updatedBy = updatedBy
+    }
+
+    fun tags(tags: String) {
+        resourceDefinition.tags = tags
+    }
+
+    fun property(property: PropertyDefinition) {
+        resourceDefinition.property = property
+    }
+
+    fun property(type: String, required: Boolean) {
+        resourceDefinition.property = PropertyDefinitionBuilder(name, type, required, description).build()
+    }
+
+    fun property(type: String, required: Boolean,
+                 block: PropertyDefinitionBuilder.() -> Unit) {
+        resourceDefinition.property = PropertyDefinitionBuilder(name, type, required, description).apply(block).build()
+    }
+
+    fun sources(block: ResourceDefinitionSourcesBuilder.() -> Unit) {
+        resourceDefinition.sources = ResourceDefinitionSourcesBuilder().apply(block).build()
+    }
+
+    fun sources(sources: MutableMap<String, NodeTemplate>) {
+        resourceDefinition.sources = sources
+    }
+
+    fun build(): ResourceDefinition {
+        resourceDefinition.name = name
+        return resourceDefinition
+    }
+}
+
+class ResourceDefinitionSourcesBuilder {
+    var sources: MutableMap<String, NodeTemplate> = hashMapOf()
+
+    fun source(source: NodeTemplate) {
+        sources[source.id!!] = source
+    }
+
+    fun sourceInput(id: String, description: String, block: SourceInputNodeTemplateBuilder.() -> Unit) {
+        sources[id] = SourceInputNodeTemplateBuilder(id, description).apply(block).build()
+    }
+
+    fun sourceDefault(id: String, description: String, block: SourceDefaultNodeTemplateBuilder.() -> Unit) {
+        sources[id] = SourceDefaultNodeTemplateBuilder(id, description).apply(block).build()
+    }
+
+    fun sourceDb(id: String, description: String, block: SourceDbNodeTemplateBuilder.() -> Unit) {
+        sources[id] = SourceDbNodeTemplateBuilder(id, description).apply(block).build()
+    }
+
+    fun sourceRest(id: String, description: String, block: SourceRestNodeTemplateBuilder.() -> Unit) {
+        sources[id] = SourceRestNodeTemplateBuilder(id, description).apply(block).build()
+    }
+
+    fun sourceCapability(id: String, description: String, block: SourceCapabilityNodeTemplateBuilder.() -> Unit) {
+        sources[id] = SourceCapabilityNodeTemplateBuilder(id, description).apply(block).build()
+    }
+
+    fun build(): MutableMap<String, NodeTemplate> {
+        return sources
+    }
+}
+
+class ResourceAssignmentsBuilder() {
+    private val resourceAssignments: MutableMap<String, ResourceAssignment> = hashMapOf()
+
+    fun resourceAssignment(name: String, dictionaryName: String, dictionarySource: String,
+                           block: ResourceAssignmentBuilder.() -> Unit) {
+        val resourceAssignment = ResourceAssignmentBuilder(name, dictionaryName, dictionarySource).apply(block).build()
+        resourceAssignments[resourceAssignment.name] = resourceAssignment
+    }
+
+    fun resourceAssignment(resourceAssignment: ResourceAssignment) {
+        resourceAssignments[resourceAssignment.name] = resourceAssignment
+    }
+
+    fun build(): MutableMap<String, ResourceAssignment> {
+        return resourceAssignments
+    }
+}
+
+class ResourceAssignmentBuilder(private val name: String, private val dictionaryName: String,
+                                private val dictionarySource: String) {
+    private val resourceAssignment = ResourceAssignment()
+
+    fun inputParameter(inputParameter: Boolean) {
+        resourceAssignment.inputParameter = inputParameter
+    }
+
+    fun property(type: String, required: Boolean, description: String? = "") {
+        resourceAssignment.property = PropertyDefinitionBuilder(name, type, required, description).build()
+    }
+
+    fun property(type: String, required: Boolean, description: String? = "",
+                 block: PropertyDefinitionBuilder.() -> Unit) {
+        resourceAssignment.property = PropertyDefinitionBuilder(name, type, required, description).apply(block).build()
+    }
+
+    fun source(source: NodeTemplate) {
+        resourceAssignment.dictionarySourceDefinition = source
+    }
+
+    fun sourceInput(block: SourceInputNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceInputNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceDefault(block: SourceDefaultNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceDefaultNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceDb(block: SourceDbNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceDbNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceRest(block: SourceRestNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceRestNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceCapability(block: SourceCapabilityNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceCapabilityNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun dependencies(dependencies: MutableList<String>) {
+        resourceAssignment.dependencies = dependencies
+    }
+
+    fun build(): ResourceAssignment {
+        resourceAssignment.name = name
+        resourceAssignment.dictionaryName = dictionaryName
+        resourceAssignment.dictionarySource = dictionarySource
+        return resourceAssignment
+    }
+}
\ No newline at end of file
index 875b9ae..0521919 100644 (file)
@@ -53,7 +53,7 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
 
     override suspend fun processNB(executionRequest: ExecutionServiceInput) {
 
-        val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE).asInt()
+        val occurrence = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE)?.asInt() ?: 1
         val resolutionKey = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY)?.returnNullIfMissing()?.textValue() ?: ""
         val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)?.asBoolean() ?: false
         val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID)?.returnNullIfMissing()?.textValue() ?: ""
index a44750d..40ea47e 100644 (file)
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode
 import org.onap.ccsdk.cds.controllerblueprints.core.*
 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
-import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateImplBuilder
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateOperationImplBuilder
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType
 
@@ -81,89 +81,91 @@ fun BluePrintTypes.nodeTypeComponentResourceResolution(): NodeType {
 /** Component Builder */
 fun BluePrintTypes.nodeTemplateComponentResourceResolution(id: String,
                                                            description: String,
-                                                           block: ComponentResourceResolutionNodeTemplateImplBuilder.() -> Unit)
+                                                           block: ComponentResourceResolutionNodeTemplateBuilder.() -> Unit)
         : NodeTemplate {
-    return ComponentResourceResolutionNodeTemplateImplBuilder(id, description).apply(block).build()
+    return ComponentResourceResolutionNodeTemplateBuilder(id, description).apply(block).build()
 }
 
-class ComponentResourceResolutionNodeTemplateImplBuilder(id: String, description: String) :
-        AbstractNodeTemplateImplBuilder<ComponentResourceResolutionInputAssignmentBuilder,
-                ComponentResourceResolutionOutputAssignmentBuilder>(id, "component-script-executor",
+class ComponentResourceResolutionNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplateOperationImplBuilder<PropertiesAssignmentBuilder,
+                ComponentResourceResolutionNodeTemplateBuilder.InputsBuilder,
+                ComponentResourceResolutionNodeTemplateBuilder.OutputsBuilder>(id, "component-script-executor",
                 "ComponentResourceResolution",
-                description)
+                description) {
 
-class ComponentResourceResolutionInputAssignmentBuilder : PropertiesAssignmentBuilder() {
+    class InputsBuilder : PropertiesAssignmentBuilder() {
 
-    fun requestId(requestId: String) = requestId(requestId.asJsonPrimitive())
+        fun requestId(requestId: String) = requestId(requestId.asJsonPrimitive())
 
-    fun requestId(requestId: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_REQUEST_ID, requestId)
-    }
+        fun requestId(requestId: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_REQUEST_ID, requestId)
+        }
 
-    fun resourceId(resourceId: String) = resourceId(resourceId.asJsonPrimitive())
+        fun resourceId(resourceId: String) = resourceId(resourceId.asJsonPrimitive())
 
-    fun resourceId(resourceId: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_RESOURCE_ID, resourceId)
-    }
+        fun resourceId(resourceId: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_RESOURCE_ID, resourceId)
+        }
 
-    fun actionName(actionName: String) = actionName(actionName.asJsonPrimitive())
+        fun actionName(actionName: String) = actionName(actionName.asJsonPrimitive())
 
-    fun actionName(actionName: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_ACTION_NAME, actionName)
-    }
+        fun actionName(actionName: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_ACTION_NAME, actionName)
+        }
 
-    fun resolutionKey(resolutionKey: String) = resolutionKey(resolutionKey.asJsonPrimitive())
+        fun resolutionKey(resolutionKey: String) = resolutionKey(resolutionKey.asJsonPrimitive())
 
-    fun resolutionKey(resolutionKey: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_RESOLUTION_KEY, resolutionKey)
-    }
+        fun resolutionKey(resolutionKey: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_RESOLUTION_KEY, resolutionKey)
+        }
 
-    fun dynamicProperties(dynamicProperties: String) = dynamicProperties(dynamicProperties.asJsonType())
+        fun dynamicProperties(dynamicProperties: String) = dynamicProperties(dynamicProperties.asJsonType())
 
-    fun dynamicProperties(dynamicProperties: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_DYNAMIC_PROPERTIES, dynamicProperties)
-    }
+        fun dynamicProperties(dynamicProperties: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_DYNAMIC_PROPERTIES, dynamicProperties)
+        }
 
-    fun occurrence(occurrence: Int) = occurrence(occurrence.asJsonPrimitive())
+        fun occurrence(occurrence: Int) = occurrence(occurrence.asJsonPrimitive())
 
-    fun occurrence(resolutionKey: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_OCCURRENCE, resolutionKey)
-    }
+        fun occurrence(resolutionKey: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_OCCURRENCE, resolutionKey)
+        }
 
-    fun storeResult(storeResult: Boolean) = storeResult(storeResult.asJsonPrimitive())
+        fun storeResult(storeResult: Boolean) = storeResult(storeResult.asJsonPrimitive())
 
-    fun storeResult(storeResult: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_STORE_RESULT, storeResult)
-    }
+        fun storeResult(storeResult: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_STORE_RESULT, storeResult)
+        }
 
-    fun resourceType(resourceType: String) = resourceType(resourceType.asJsonPrimitive())
+        fun resourceType(resourceType: String) = resourceType(resourceType.asJsonPrimitive())
 
-    fun resourceType(resourceType: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_RESOURCE_TYPE, resourceType)
-    }
+        fun resourceType(resourceType: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_RESOURCE_TYPE, resourceType)
+        }
 
-    fun artifactPrefixNames(artifactPrefixNames: String) = artifactPrefixNames(artifactPrefixNames.jsonAsJsonType())
+        fun artifactPrefixNames(artifactPrefixNames: String) = artifactPrefixNames(artifactPrefixNames.jsonAsJsonType())
 
-    fun artifactPrefixNames(artifactPrefixNameList: List<String>) {
-        artifactPrefixNames(artifactPrefixNameList.asJsonString())
-    }
+        fun artifactPrefixNames(artifactPrefixNameList: List<String>) =
+                artifactPrefixNames(artifactPrefixNameList.asJsonString())
 
-    fun artifactPrefixNames(artifactPrefixNames: JsonNode) {
-        property(ResourceResolutionComponent.INPUT_ARTIFACT_PREFIX_NAMES, artifactPrefixNames)
+        fun artifactPrefixNames(artifactPrefixNames: JsonNode) {
+            property(ResourceResolutionComponent.INPUT_ARTIFACT_PREFIX_NAMES, artifactPrefixNames)
+        }
     }
-}
 
-class ComponentResourceResolutionOutputAssignmentBuilder : PropertiesAssignmentBuilder() {
+    class OutputsBuilder : PropertiesAssignmentBuilder() {
 
-    fun status(status: String) = status(status.asJsonPrimitive())
+        fun status(status: String) = status(status.asJsonPrimitive())
 
-    fun status(status: JsonNode) {
-        property(ResourceResolutionComponent.OUTPUT_STATUS, status)
-    }
+        fun status(status: JsonNode) {
+            property(ResourceResolutionComponent.OUTPUT_STATUS, status)
+        }
 
-    fun resourceAssignmentParams(resourceAssignmentParams: String) = resourceAssignmentParams(resourceAssignmentParams.asJsonType())
+        fun resourceAssignmentParams(resourceAssignmentParams: String) =
+                resourceAssignmentParams(resourceAssignmentParams.asJsonType())
 
-    fun resourceAssignmentParams(resourceAssignmentParams: JsonNode) {
-        property(ResourceResolutionComponent.OUTPUT_RESOURCE_ASSIGNMENT_PARAMS, resourceAssignmentParams)
+        fun resourceAssignmentParams(resourceAssignmentParams: JsonNode) {
+            property(ResourceResolutionComponent.OUTPUT_RESOURCE_ASSIGNMENT_PARAMS, resourceAssignmentParams)
+        }
     }
 }
\ No newline at end of file
index 6514df2..641175c 100644 (file)
@@ -26,6 +26,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.R
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceDefinitionUtils.createResourceAssignments
 import org.onap.ccsdk.cds.controllerblueprints.core.*
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
@@ -36,6 +37,7 @@ import org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils.BulkResourceS
 import org.slf4j.LoggerFactory
 import org.springframework.context.ApplicationContext
 import org.springframework.stereotype.Service
+import java.util.*
 
 interface ResourceResolutionService {
 
@@ -50,6 +52,14 @@ interface ResourceResolutionService {
     suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
                                  artifactPrefix: String, properties: Map<String, Any>): String
 
+    /** Resolve resources for all the sources defined in a particular resource Definition[resolveDefinition]
+     * with other [resourceDefinitions] dependencies for the sources [sources]
+     * Used to get the same resource values from multiple sources. **/
+    suspend fun resolveResourceDefinition(blueprintRuntimeService: BluePrintRuntimeService<*>,
+                                          resourceDefinitions: MutableMap<String, ResourceDefinition>,
+                                          resolveDefinition: String, sources: List<String>)
+            : MutableMap<String, JsonNode>
+
     suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>,
                                            resourceDefinitions: MutableMap<String, ResourceDefinition>,
                                            resourceAssignments: MutableList<ResourceAssignment>,
@@ -86,12 +96,12 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
                                           properties: Map<String, Any>): MutableMap<String, String> {
 
         val resourceAssignmentRuntimeService =
-            ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactNames.toString())
+                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactNames.toString())
 
         val resolvedParams: MutableMap<String, String> = hashMapOf()
         artifactNames.forEach { artifactName ->
             val resolvedContent = resolveResources(resourceAssignmentRuntimeService, nodeTemplateName,
-                artifactName, properties)
+                    artifactName, properties)
 
             resolvedParams[artifactName] = resolvedContent
         }
@@ -151,6 +161,21 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
         return resolvedContent
     }
 
+    override suspend fun resolveResourceDefinition(blueprintRuntimeService: BluePrintRuntimeService<*>,
+                                                   resourceDefinitions: MutableMap<String, ResourceDefinition>,
+                                                   resolveDefinition: String, sources: List<String>)
+            : MutableMap<String, JsonNode> {
+
+        // Populate Dummy Resource Assignments
+        val resourceAssignments = createResourceAssignments(resourceDefinitions, resolveDefinition, sources)
+
+        resolveResourceAssignments(blueprintRuntimeService, resourceDefinitions, resourceAssignments,
+                UUID.randomUUID().toString(), hashMapOf())
+
+        // Get the data from Resource Assignments
+        return ResourceAssignmentUtils.generateResourceForAssignments(resourceAssignments)
+    }
+
     /**
      * Iterate the Batch, get the Resource Assignment, dictionary Name, Look for the Resource definition for the
      * name, then get the type of the Resource Definition, Get the instance for the Resource Type and process the
@@ -165,7 +190,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
         val bulkSequenced = BulkResourceSequencingUtils.process(resourceAssignments)
 
         // Check the BlueprintRuntime Service Should be ResourceAssignmentRuntimeService
-        val resourceAssignmentRuntimeService = if (!(blueprintRuntimeService is ResourceAssignmentRuntimeService)) {
+        val resourceAssignmentRuntimeService = if (blueprintRuntimeService !is ResourceAssignmentRuntimeService) {
             ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, artifactPrefix)
         } else {
             blueprintRuntimeService
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceDSL.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceDSL.kt
new file mode 100644 (file)
index 0000000..182f3a1
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
+
+import com.fasterxml.jackson.databind.JsonNode
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor
+import org.onap.ccsdk.cds.controllerblueprints.core.*
+import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplatePropertyImplBuilder
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType
+import kotlin.reflect.KClass
+
+fun BluePrintTypes.nodeTypeSourceInput(): NodeType {
+    return nodeType(id = "source-input", version = BluePrintConstants.DEFAULT_VERSION_NUMBER,
+            derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_RESOURCE_SOURCE,
+            description = "This is Input Resource Source Node Type") {}
+}
+
+fun BluePrintTypes.nodeTypeSourceDefault(): NodeType {
+    return nodeType(id = "source-default", version = BluePrintConstants.DEFAULT_VERSION_NUMBER,
+            derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_RESOURCE_SOURCE,
+            description = "This is Default Resource Source Node Type") {}
+}
+
+fun BluePrintTypes.nodeTypeSourceDb(): NodeType {
+    return nodeType(id = "source-db", version = BluePrintConstants.DEFAULT_VERSION_NUMBER,
+            derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_RESOURCE_SOURCE,
+            description = "This is Database Resource Source Node Type") {
+        property("type", BluePrintConstants.DATA_TYPE_STRING,
+                true, "") {
+            defaultValue("SQL".asJsonPrimitive())
+            constrain {
+                validValues(arrayListOf("SQL".asJsonPrimitive(), "PLSQL".asJsonPrimitive()))
+            }
+        }
+        property("endpoint-selector", BluePrintConstants.DATA_TYPE_STRING,
+                false, "")
+        property("query", BluePrintConstants.DATA_TYPE_STRING,
+                true, "")
+        property("input-key-mapping", BluePrintConstants.DATA_TYPE_MAP,
+                true, "") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+        property("output-key-mapping", BluePrintConstants.DATA_TYPE_MAP,
+                false, "") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+        property("key-dependencies", BluePrintConstants.DATA_TYPE_LIST,
+                true, "Resource Resolution dependency dictionary names.") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+    }
+}
+
+fun BluePrintTypes.nodeTypeSourceRest(): NodeType {
+    return nodeType(id = "source-rest", version = BluePrintConstants.DEFAULT_VERSION_NUMBER,
+            derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_RESOURCE_SOURCE,
+            description = "This is Rest Resource Source Node Type") {
+        property("type", BluePrintConstants.DATA_TYPE_STRING,
+                true, "") {
+            defaultValue("JSON".asJsonPrimitive())
+            constrain {
+                validValues(arrayListOf("JSON".asJsonPrimitive(), "XML".asJsonPrimitive()))
+            }
+        }
+        property("verb", BluePrintConstants.DATA_TYPE_STRING,
+                true, "") {
+            defaultValue("GET".asJsonPrimitive())
+            constrain {
+                validValues(arrayListOf("GET".asJsonPrimitive(), "POST".asJsonPrimitive(),
+                        "DELETE".asJsonPrimitive(), "PUT".asJsonPrimitive()))
+            }
+        }
+        property("payload", BluePrintConstants.DATA_TYPE_STRING,
+                false, "") {
+            defaultValue("".asJsonPrimitive())
+        }
+        property("endpoint-selector", BluePrintConstants.DATA_TYPE_STRING,
+                false, "")
+        property("url-path", BluePrintConstants.DATA_TYPE_STRING,
+                true, "")
+        property("path", BluePrintConstants.DATA_TYPE_STRING,
+                true, "")
+        property("expression-type", BluePrintConstants.DATA_TYPE_STRING,
+                false, "") {
+            defaultValue("JSON_PATH".asJsonPrimitive())
+            constrain {
+                validValues(arrayListOf("JSON_PATH".asJsonPrimitive(), "JSON_POINTER".asJsonPrimitive()))
+            }
+        }
+        property("input-key-mapping", BluePrintConstants.DATA_TYPE_MAP,
+                true, "") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+        property("output-key-mapping", BluePrintConstants.DATA_TYPE_MAP,
+                false, "") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+        property("key-dependencies", BluePrintConstants.DATA_TYPE_LIST,
+                true, "Resource Resolution dependency dictionary names.") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+    }
+}
+
+fun BluePrintTypes.nodeTypeSourceCapability(): NodeType {
+    return nodeType(id = "source-capability", version = BluePrintConstants.DEFAULT_VERSION_NUMBER,
+            derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_RESOURCE_SOURCE,
+            description = "This is Component Resource Source Node Type") {
+        property(ComponentScriptExecutor.INPUT_SCRIPT_TYPE, BluePrintConstants.DATA_TYPE_STRING,
+                true, "Request Id, Unique Id for the request.") {
+            defaultValue(BluePrintConstants.SCRIPT_KOTLIN)
+            constrain {
+                validValues(arrayListOf(BluePrintConstants.SCRIPT_KOTLIN.asJsonPrimitive(),
+                        BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive(),
+                        BluePrintConstants.SCRIPT_JYTHON.asJsonPrimitive()))
+            }
+        }
+        property(ComponentScriptExecutor.INPUT_SCRIPT_CLASS_REFERENCE, BluePrintConstants.DATA_TYPE_STRING,
+                true, "Kotlin Script class name or jython script name.")
+        property("key-dependencies", BluePrintConstants.DATA_TYPE_LIST,
+                true, "Resource Resolution dependency dictionary names.") {
+            entrySchema(BluePrintConstants.DATA_TYPE_STRING)
+        }
+    }
+}
+
+/** Node Template Source Input **/
+fun BluePrintTypes.nodeTemplateSourceInput(id: String, description: String,
+                                           block: SourceInputNodeTemplateBuilder.() -> Unit): NodeTemplate {
+    return SourceInputNodeTemplateBuilder(id, description).apply(block).build()
+}
+
+class SourceInputNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplatePropertyImplBuilder<PropertiesAssignmentBuilder>(id,
+                "source-input", description)
+
+/** Node Template Source Default **/
+fun BluePrintTypes.nodeTemplateSourceDefault(id: String, description: String,
+                                             block: SourceDefaultNodeTemplateBuilder.() -> Unit): NodeTemplate {
+    return SourceDefaultNodeTemplateBuilder(id, description).apply(block).build()
+}
+
+class SourceDefaultNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplatePropertyImplBuilder<PropertiesAssignmentBuilder>(id,
+                "source-default", description)
+
+/** Node Template Source DB **/
+fun BluePrintTypes.nodeTemplateSourceDb(id: String, description: String,
+                                        block: SourceDbNodeTemplateBuilder.() -> Unit): NodeTemplate {
+    return SourceDbNodeTemplateBuilder(id, description).apply(block).build()
+}
+
+class SourceDbNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplatePropertyImplBuilder<SourceDbNodeTemplateBuilder.PropertiesBuilder>(id,
+                "source-db", description) {
+
+    class PropertiesBuilder : PropertiesAssignmentBuilder() {
+        fun type(type: String) = type(type.asJsonPrimitive())
+
+        fun type(type: JsonNode) {
+            property("type", type)
+        }
+
+        fun endpointSelector(endpointSelector: String) = endpointSelector(endpointSelector.asJsonPrimitive())
+
+        fun endpointSelector(endpointSelector: JsonNode) {
+            property("endpoint-selector", endpointSelector)
+        }
+
+        fun query(query: String) = query(query.asJsonPrimitive())
+
+        fun query(query: JsonNode) {
+            property("query", query)
+        }
+
+        fun inputKeyMapping(block: KeyMappingBuilder.() -> Unit) {
+            val map = KeyMappingBuilder().apply(block).build()
+            property("input-key-mapping", map.asJsonType())
+        }
+
+        fun outputKeyMapping(block: KeyMappingBuilder.() -> Unit) {
+            val map = KeyMappingBuilder().apply(block).build()
+            property("output-key-mapping", map.asJsonType())
+        }
+
+        fun keyDependencies(keyDependencies: String) = keyDependencies(keyDependencies.asJsonType())
+
+        fun keyDependencies(keyDependencies: List<String>) = keyDependencies(keyDependencies.asJsonString())
+
+        fun keyDependencies(keyDependencies: JsonNode) {
+            property("key-dependencies", keyDependencies)
+        }
+    }
+}
+
+class KeyMappingBuilder() {
+    val map: MutableMap<String, String> = hashMapOf()
+    fun map(key: String, value: String) {
+        map[key] = value
+    }
+
+    fun build(): MutableMap<String, String> {
+        return map
+    }
+}
+
+
+/** Node Template Source Rest **/
+fun BluePrintTypes.nodeTemplateSourceRest(id: String, description: String,
+                                          block: SourceRestNodeTemplateBuilder.() -> Unit): NodeTemplate {
+    return SourceRestNodeTemplateBuilder(id, description).apply(block).build()
+}
+
+class SourceRestNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplatePropertyImplBuilder<SourceRestNodeTemplateBuilder.PropertiesBuilder>(id,
+                "source-rest", description) {
+
+    class PropertiesBuilder : PropertiesAssignmentBuilder() {
+        fun type(type: String) = type(type.asJsonPrimitive())
+
+        fun type(type: JsonNode) {
+            property("type", type)
+        }
+
+        fun endpointSelector(endpointSelector: String) = endpointSelector(endpointSelector.asJsonPrimitive())
+
+        fun endpointSelector(endpointSelector: JsonNode) {
+            property("endpoint-selector", endpointSelector)
+        }
+
+        fun verb(verb: String) = verb(verb.asJsonPrimitive())
+
+        fun verb(verb: JsonNode) {
+            property("verb", verb)
+        }
+
+        fun payload(payload: String) = payload(payload.asJsonPrimitive())
+
+        fun payload(payload: JsonNode) {
+            property("payload", payload)
+        }
+
+        fun urlPath(urlPath: String) = urlPath(urlPath.asJsonPrimitive())
+
+        fun urlPath(urlPath: JsonNode) {
+            property("url-path", urlPath)
+        }
+
+        fun path(path: String) = path(path.asJsonPrimitive())
+
+        fun path(path: JsonNode) {
+            property("path", path)
+        }
+
+        fun expressionType(expressionType: String) = expressionType(expressionType.asJsonPrimitive())
+
+        fun expressionType(expressionType: JsonNode) {
+            property("expression-type", expressionType)
+        }
+
+        fun inputKeyMapping(block: KeyMappingBuilder.() -> Unit) {
+            val map = KeyMappingBuilder().apply(block).build()
+            property("input-key-mapping", map.asJsonType())
+        }
+
+        fun outputKeyMapping(block: KeyMappingBuilder.() -> Unit) {
+            val map = KeyMappingBuilder().apply(block).build()
+            property("output-key-mapping", map.asJsonType())
+        }
+
+        fun keyDependencies(keyDependencies: String) = keyDependencies(keyDependencies.asJsonType())
+
+        fun keyDependencies(keyDependencies: List<String>) = keyDependencies(keyDependencies.asJsonString())
+
+        fun keyDependencies(keyDependencies: JsonNode) {
+            property("key-dependencies", keyDependencies)
+        }
+    }
+}
+
+/** Node Template Source Rest **/
+fun BluePrintTypes.nodeTemplateSourceCapability(id: String, description: String,
+                                                block: SourceCapabilityNodeTemplateBuilder.() -> Unit): NodeTemplate {
+    return SourceCapabilityNodeTemplateBuilder(id, description).apply(block).build()
+}
+
+class SourceCapabilityNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplatePropertyImplBuilder<SourceCapabilityNodeTemplateBuilder.PropertiesBuilder>(id,
+                "source-capability", description) {
+
+    class PropertiesBuilder : PropertiesAssignmentBuilder() {
+        fun type(type: String) = type(type.asJsonPrimitive())
+
+        fun type(type: JsonNode) {
+            property(ComponentScriptExecutor.INPUT_SCRIPT_TYPE, type)
+        }
+
+        fun scriptClassReference(scriptClassReference: KClass<*>) {
+            scriptClassReference(scriptClassReference.qualifiedName!!)
+        }
+
+        fun scriptClassReference(scriptClassReference: String) = scriptClassReference(scriptClassReference.asJsonPrimitive())
+
+        fun scriptClassReference(scriptClassReference: JsonNode) {
+            property(ComponentScriptExecutor.INPUT_SCRIPT_CLASS_REFERENCE, scriptClassReference)
+        }
+
+        fun keyDependencies(keyDependencies: String) = keyDependencies(keyDependencies.asJsonType())
+
+        fun keyDependencies(keyDependencies: List<String>) = keyDependencies(keyDependencies.asJsonString())
+
+        fun keyDependencies(keyDependencies: JsonNode) {
+            property("key-dependencies", keyDependencies)
+        }
+    }
+}
\ No newline at end of file
index 49cb83e..0ea71ec 100644 (file)
@@ -27,14 +27,12 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.config.ConfigurableBeanFactory
-import org.springframework.context.ApplicationContext
 import org.springframework.context.annotation.Scope
 import org.springframework.stereotype.Service
 
 @Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-capability")
 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-open class CapabilityResourceResolutionProcessor(private val applicationContext: ApplicationContext,
-                                                 private var componentFunctionScriptingService: ComponentFunctionScriptingService)
+open class CapabilityResourceResolutionProcessor(private var componentFunctionScriptingService: ComponentFunctionScriptingService)
     : ResourceAssignmentProcessor() {
 
     private val log = LoggerFactory.getLogger(CapabilityResourceResolutionProcessor::class.java)
@@ -47,12 +45,14 @@ open class CapabilityResourceResolutionProcessor(private val applicationContext:
 
     override suspend fun processNB(resourceAssignment: ResourceAssignment) {
 
-        val resourceDefinition = resourceDictionaries[resourceAssignment.dictionaryName]
-                ?: throw BluePrintProcessorException("couldn't get resource definition for ${resourceAssignment.dictionaryName}")
+        val dName = resourceAssignment.dictionaryName!!
+        val dSource = resourceAssignment.dictionarySource!!
+        val resourceDefinition = resourceDefinition(resourceAssignment.dictionaryName!!)
 
-        val resourceSource = resourceDefinition.sources[resourceAssignment.dictionarySource]
-                ?: throw BluePrintProcessorException("couldn't get resource definition " +
-                        "${resourceAssignment.dictionaryName} source(${resourceAssignment.dictionarySource})")
+        /** Check Resource Assignment has the source definitions, If not get from Resource Definition **/
+        val resourceSource = resourceAssignment.dictionarySourceDefinition
+                ?: resourceDefinition?.sources?.get(dSource)
+                ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
 
         val resourceSourceProps = checkNotNull(resourceSource.properties) { "failed to get $resourceSource properties" }
         /**
@@ -96,10 +96,6 @@ open class CapabilityResourceResolutionProcessor(private val applicationContext:
                 .scriptInstance<ResourceAssignmentProcessor>(raRuntimeService.bluePrintContext(), scriptType,
                         scriptClassReference)
 
-        instanceDependencies.forEach { instanceDependency ->
-            scriptPropertyInstances[instanceDependency] = applicationContext
-                    .getBean(instanceDependency)
-        }
         return scriptComponent
     }
 
index 987390f..600de13 100644 (file)
@@ -18,8 +18,6 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor
 
 import com.fasterxml.jackson.databind.node.JsonNodeFactory
-import com.fasterxml.jackson.databind.node.MissingNode
-import com.fasterxml.jackson.databind.node.NullNode
 import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibGenericService
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.BluePrintDBLibPropertySevice
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.PrimaryDBLibGenericService
@@ -41,7 +39,7 @@ import java.util.*
  *
  * @author Kapil Singal
  */
-@Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-processor-db")
+@Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-db")
 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropertySevice: BluePrintDBLibPropertySevice,
                                                private val primaryDBLibGenericService: PrimaryDBLibGenericService)
@@ -50,7 +48,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
     private val logger = LoggerFactory.getLogger(DatabaseResourceAssignmentProcessor::class.java)
 
     override fun getName(): String {
-        return "${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-processor-db"
+        return "${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-db"
     }
 
     override suspend fun processNB(resourceAssignment: ResourceAssignment) {
@@ -60,7 +58,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
             // Check if It has Input
             try {
                 val value = raRuntimeService.getInputValue(resourceAssignment.name)
-                if (value !is NullNode && value !is MissingNode) {
+                if (value.returnNullIfMissing() != null) {
                     logger.info("processor-db source template key (${resourceAssignment.name}) found from input and value is ($value)")
                     ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value)
                 } else {
@@ -79,11 +77,13 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
     }
 
     private fun setValueFromDB(resourceAssignment: ResourceAssignment) {
-        val dName = resourceAssignment.dictionaryName
-        val dSource = resourceAssignment.dictionarySource
-        val resourceDefinition = resourceDictionaries[dName]
-                ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dName")
-        val resourceSource = resourceDefinition.sources[dSource]
+        val dName = resourceAssignment.dictionaryName!!
+        val dSource = resourceAssignment.dictionarySource!!
+        val resourceDefinition = resourceDefinition(dName)
+
+        /** Check Resource Assignment has the source definitions, If not get from Resource Definition **/
+        val resourceSource = resourceAssignment.dictionarySourceDefinition
+                ?: resourceDefinition?.sources?.get(dSource)
                 ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
         val resourceSourceProperties = checkNotNull(resourceSource.properties) {
             "failed to get source properties for $dName "
@@ -188,7 +188,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
                 val row = rows[0]
                 val objectNode = JacksonUtils.objectMapper.createObjectNode()
                 for (mapping in outputKeyMapping.entries) {
-                    val dbColumnValue = checkNotNull(row[mapping.key])
+                    val dbColumnValue = checkNotNull(row[mapping.value])
                     val propertyTypeForDataType = ResourceAssignmentUtils.getPropertyType(raRuntimeService, type, mapping.key)
                     JacksonUtils.populatePrimitiveValues(mapping.key, dbColumnValue, propertyTypeForDataType, objectNode)
                 }
index 1abcea8..2a7d19b 100644 (file)
@@ -38,7 +38,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
     private val log = LoggerFactory.getLogger(ResourceAssignmentProcessor::class.java)
 
     lateinit var raRuntimeService: ResourceAssignmentRuntimeService
-    lateinit var resourceDictionaries: MutableMap<String, ResourceDefinition>
+    var resourceDictionaries: MutableMap<String, ResourceDefinition> = hashMapOf()
 
     var scriptPropertyInstances: MutableMap<String, Any> = hashMapOf()
     lateinit var scriptType: String
@@ -62,9 +62,8 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
         return value
     }
 
-    open fun resourceDefinition(name: String): ResourceDefinition {
-        return resourceDictionaries[name]
-                ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)")
+    open fun resourceDefinition(name: String): ResourceDefinition? {
+        return if (resourceDictionaries.containsKey(name)) resourceDictionaries[name] else null
     }
 
     open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, JsonNode> {
index 3bf0b35..57e0286 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor
 
-import com.fasterxml.jackson.databind.node.ArrayNode
 import com.fasterxml.jackson.databind.node.MissingNode
 import com.fasterxml.jackson.databind.node.NullNode
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR
@@ -56,29 +55,30 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
             // Check if It has Input
             val value = getFromInput(resourceAssignment)
             if (value == null || value is MissingNode || value is NullNode) {
-                val dName = resourceAssignment.dictionaryName
-                val dSource = resourceAssignment.dictionarySource
-                val resourceDefinition = resourceDictionaries[dName]
-                    ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dName")
+                val dName = resourceAssignment.dictionaryName!!
+                val dSource = resourceAssignment.dictionarySource!!
+                val resourceDefinition = resourceDefinition(dName)
 
-                val resourceSource = resourceDefinition.sources[dSource]
-                    ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
+                /** Check Resource Assignment has the source definitions, If not get from Resource Definitions **/
+                val resourceSource = resourceAssignment.dictionarySourceDefinition
+                        ?: resourceDefinition?.sources?.get(dSource)
+                        ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
 
                 val resourceSourceProperties =
-                    checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
+                        checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
 
                 val sourceProperties =
-                    JacksonUtils.getInstanceFromMap(resourceSourceProperties, RestResourceSource::class.java)
+                        JacksonUtils.getInstanceFromMap(resourceSourceProperties, RestResourceSource::class.java)
 
                 val path = nullToEmpty(sourceProperties.path)
                 val inputKeyMapping =
-                    checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
+                        checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
                 val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping).toMutableMap()
 
                 // Resolving content Variables
                 val payload = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.payload), resolvedInputKeyMapping)
                 val urlPath =
-                    resolveFromInputKeyMapping(checkNotNull(sourceProperties.urlPath), resolvedInputKeyMapping)
+                        resolveFromInputKeyMapping(checkNotNull(sourceProperties.urlPath), resolvedInputKeyMapping)
                 val verb = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.verb), resolvedInputKeyMapping)
 
                 logger.info("$dSource dictionary information : ($urlPath), ($inputKeyMapping), (${sourceProperties.outputKeyMapping})")
@@ -91,12 +91,11 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                 val outputKeyMapping = sourceProperties.outputKeyMapping
                 if (responseStatusCode in 200..299 && outputKeyMapping.isNullOrEmpty()) {
                     logger.info("AS>> outputKeyMapping==null, will not populateResource")
-                }
-                else if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
+                } else if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
                     populateResource(resourceAssignment, sourceProperties, responseBody, path)
                 } else {
                     val errMsg =
-                        "Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath) response_code: ($responseStatusCode)"
+                            "Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath) response_code: ($responseStatusCode)"
                     logger.warn(errMsg)
                     throw BluePrintProcessorException(errMsg)
                 }
@@ -106,7 +105,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
         } catch (e: Exception) {
             ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message)
             throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}",
-                e)
+                    e)
         }
     }
 
@@ -161,13 +160,13 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                         outputKeyMapping.map {
                             val responseKeyValue = responseSingleJsonNode.get(it.key)
                             val propertyTypeForDataType = ResourceAssignmentUtils
-                                .getPropertyType(raRuntimeService, entrySchemaType, it.key)
+                                    .getPropertyType(raRuntimeService, entrySchemaType, it.key)
 
                             logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), " +
                                     "type  ({$propertyTypeForDataType})")
 
                             JacksonUtils.populateJsonNodeValues(it.value,
-                                responseKeyValue, propertyTypeForDataType, arrayChildNode)
+                                    responseKeyValue, propertyTypeForDataType, arrayChildNode)
                         }
                         arrayNode.add(arrayChildNode)
                     }
@@ -185,7 +184,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                 outputKeyMapping.map {
                     val responseKeyValue = responseNode.get(it.key)
                     val propertyTypeForDataType = ResourceAssignmentUtils
-                        .getPropertyType(raRuntimeService, entrySchemaType, it.key)
+                            .getPropertyType(raRuntimeService, entrySchemaType, it.key)
 
                     logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), type  ({$propertyTypeForDataType})")
                     JacksonUtils.populateJsonNodeValues(it.value, responseKeyValue, propertyTypeForDataType, objectNode)
index 8a8bfbf..f8024d9 100644 (file)
@@ -19,7 +19,6 @@ 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.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
@@ -70,7 +69,8 @@ class ResourceAssignmentUtils {
             try {
                 if (resourceProp.type.isNotEmpty()) {
                     logger.info("Setting Resource Value ($value) for Resource Name " +
-                            "(${resourceAssignment.name}) of type (${resourceProp.type})")
+                            "(${resourceAssignment.name}), definition(${resourceAssignment.dictionaryName}) " +
+                            "of type (${resourceProp.type})")
                     setResourceValue(resourceAssignment, raRuntimeService, value)
                     resourceAssignment.updatedDate = Date()
                     resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
@@ -106,7 +106,7 @@ class ResourceAssignmentUtils {
                 "Failed to populate mandatory resource resource mapping $resourceAssignment"
             }
             if (resourceProp.required != null && resourceProp.required!!
-                    && (resourceProp.value == null || resourceProp.value !is NullNode)) {
+                    && (resourceProp.value == null || resourceProp.value!!.returnNullIfMissing() == null)) {
                 logger.error("failed to populate mandatory resource mapping ($resourceAssignment)")
                 throw BluePrintProcessorException("failed to populate mandatory resource mapping ($resourceAssignment)")
             }
@@ -137,6 +137,21 @@ class ResourceAssignmentUtils {
             return result
         }
 
+        @Throws(BluePrintProcessorException::class)
+        fun generateResourceForAssignments(assignments: List<ResourceAssignment>): MutableMap<String, JsonNode> {
+            val data: MutableMap<String, JsonNode> = hashMapOf()
+            assignments.forEach {
+                if (isNotEmpty(it.name) && it.property != null) {
+                    val rName = it.name
+                    val type = nullToEmpty(it.property?.type).toLowerCase()
+                    val value = useDefaultValueIfNull(it, rName)
+                    logger.trace("Generating Resource name ($rName), type ($type), value ($value)")
+                    data[rName] = value
+                }
+            }
+            return data
+        }
+
         private fun useDefaultValueIfNull(resourceAssignment: ResourceAssignment, resourceAssignmentName: String): JsonNode {
             if (resourceAssignment.property?.value == null) {
                 val defaultValue = "\${$resourceAssignmentName}"
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt
new file mode 100644 (file)
index 0000000..15a8c6c
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString
+import org.onap.ccsdk.cds.controllerblueprints.core.asListOfString
+import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
+
+object ResourceDefinitionUtils {
+
+    fun definitionDependencies(definition: ResourceDefinition, sources: List<String>): Set<String> {
+        val dependencies: MutableSet<String> = mutableSetOf()
+        definition.sources.forEach { (sourceName, source) ->
+            if (sources.contains(sourceName)) {
+                val keyDependenciesExists = source.properties?.containsKey("key-dependencies") ?: false
+                if (keyDependenciesExists) {
+                    dependencies.addAll(source.properties!!["key-dependencies"]!!.asListOfString())
+                }
+            }
+        }
+        return dependencies
+    }
+
+    /** Create a processing resource assignments for the resource definition  */
+    fun createResourceAssignments(resourceDefinitions: MutableMap<String, ResourceDefinition>,
+                                  resolveDefinition: String, sources: List<String>)
+            : MutableList<ResourceAssignment> {
+        /** Check if resolve definition is defined in the resource definition Map */
+        val resourceDefinition = resourceDefinitions[resolveDefinition]
+                ?: throw BluePrintProcessorException("failed to get resolve definition($resolveDefinition)")
+
+        val resourceAssignments: MutableList<ResourceAssignment> = arrayListOf()
+        /** Get the dependency property fields for the the resource definition to resolve */
+        val definitionDependencies = definitionDependencies(resourceDefinition, sources)
+        definitionDependencies.forEach { definitionDependencyName ->
+            val definitionDependency = resourceDefinitions[definitionDependencyName]
+                    ?: throw BluePrintProcessorException("failed to get dependency definition($definitionDependencyName)")
+
+            val resourceAssignment = ResourceAssignment().apply {
+                name = definitionDependency.name
+                dictionaryName = definitionDependency.name
+                /** The assumption is al resource are already resolved and shall get as input source */
+                dictionarySource = "input"
+                property = definitionDependency.property
+            }
+            resourceAssignments.add(resourceAssignment)
+        }
+
+        resourceDefinition.sources.forEach { (sourceName, source) ->
+            if (sources.contains(sourceName)) {
+                val resourceAssignment = ResourceAssignment().apply {
+                    name = "$sourceName:${resourceDefinition.name}"
+                    dictionaryName = resourceDefinition.name
+                    dictionarySource = sourceName
+                    dictionarySourceDefinition = source
+                    // Clone the PropertyDefinition, otherwise property value will be overridden
+                    property = JacksonUtils
+                            .readValue(resourceDefinition.property.asJsonString(), PropertyDefinition::class.java)
+                    val keyDependenciesExists = source.properties?.containsKey("key-dependencies") ?: false
+                    if (keyDependenciesExists) {
+                        dependencies = source.properties!!["key-dependencies"]!!.asListOfString().toMutableList()
+                    }
+                }
+                resourceAssignments.add(resourceAssignment)
+            }
+        }
+        // Populate Resource Definition's dependencies as Input Resource Assignment
+        return resourceAssignments
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSLTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSLTest.kt
new file mode 100644 (file)
index 0000000..f8f0e99
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+
+class ResourceDefinitionDSLTest {
+
+    @Test
+    fun testResourceDefinitionDSL() {
+        val testResourceDefinition = BluePrintTypes.resourceDefinition("service-instance-id",
+                "VFW Service Instance Name") {
+            tags("service-instance-name, vfw, resources")
+            updatedBy("brindasanth@onap.com")
+            property("string", true)
+            sources {
+                sourceInput("input", "") {}
+                sourceDefault("default", "") {}
+                sourceDb("sdnctl", "") {
+                    definedProperties {
+                        type("SQL")
+                        query("SELECT name FROM SERVICE_INSTANCE WHERE id = \$id")
+                        endpointSelector("db-source-endpoint")
+                        inputKeyMapping {
+                            map("id", "\$service-instance-id")
+                        }
+                        outputKeyMapping {
+                            map("service-instance-name", "\$name")
+                        }
+                        keyDependencies(arrayListOf("service-instance-id"))
+                    }
+                }
+                sourceRest("odl-mdsal", "") {
+                    definedProperties {
+                        type("JSON")
+                        endpointSelector("rest-source-endpoint")
+                        expressionType("JSON_PATH")
+                        urlPath("/service-instance/\$id")
+                        path(".\$name")
+                        verb("GET")
+                        payload("sample payload")
+                        inputKeyMapping {
+                            map("id", "\$service-instance-id")
+                        }
+                        outputKeyMapping {
+                            map("service-instance-name", "\$name")
+                        }
+                        keyDependencies(arrayListOf("service-instance-id"))
+                    }
+                }
+                sourceCapability("custom-component", "") {
+                    definedProperties {
+                        type("kotlin")
+                        scriptClassReference("Scripts/ServiceInstance.kt")
+                        keyDependencies(arrayListOf("service-instance-id"))
+                    }
+                }
+            }
+        }
+        //println(resourceDefinition.asJsonString(true))
+        assertNotNull(testResourceDefinition, "failed to generate testResourceDefinition")
+
+        val testResourceDefinitions = BluePrintTypes.resourceDefinitions {
+            resourceDefinition(testResourceDefinition)
+        }
+        assertNotNull(testResourceDefinitions, "failed to generate testResourceDefinitions")
+        assertEquals(1, testResourceDefinitions.size, "testResourceDefinitions size doesn't match")
+    }
+
+    @Test
+    fun testResourceAssignment() {
+        val testResourceAssignment = BluePrintTypes.resourceAssignment("instance-name",
+                "service-instance-name", "odl-mdsal") {
+            inputParameter(true)
+            property("string", true)
+            dependencies(arrayListOf("service-instance-id"))
+        }
+        //println(resourceAssignment.asJsonString(true))
+        assertNotNull(testResourceAssignment, "failed to generate resourceAssignment")
+
+        val testResourceAssignments = BluePrintTypes.resourceAssignments {
+            resourceAssignment(testResourceAssignment)
+            resourceAssignment("instance-name1",
+                    "service-instance-name", "odl-mdsal") {
+                inputParameter(true)
+                property("string", true)
+                dependencies(arrayListOf("service-instance-id"))
+            }
+        }
+        //println(testResourceAssignments.asJsonString(true))
+        assertNotNull(testResourceAssignments, "failed to generate testResourceAssignments")
+        assertEquals(2, testResourceAssignments.size, "testResourceAssignments size doesn't match")
+    }
+}
\ No newline at end of file
index d056678..671acff 100644 (file)
@@ -33,7 +33,7 @@ class ResourceResolutionComponentDSLTest {
     @Test
     fun testNodeTemplateComponentResourceResolution() {
         val nodeTemplate = BluePrintTypes.nodeTemplateComponentResourceResolution("resource-resolve", "") {
-            operation("Resolve resources") {
+            definedOperation("Resolve resources") {
                 inputs {
                     actionName("resolve")
                     requestId("1234")
index f1ad030..775c501 100644 (file)
@@ -18,6 +18,8 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
 
+import io.mockk.every
+import io.mockk.mockk
 import kotlinx.coroutines.runBlocking
 import org.junit.Assert
 import org.junit.Before
@@ -30,12 +32,18 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.PayloadUtils
 import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.*
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintError
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
+import org.springframework.context.ApplicationContext
 import org.springframework.context.annotation.ComponentScan
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
@@ -84,8 +92,8 @@ class ResourceResolutionServiceTest {
     fun testRegisteredSource() {
         val sources = resourceResolutionService.registeredResourceSources()
         assertNotNull(sources, "failed to get registered sources")
-        assertTrue(sources.containsAll(arrayListOf("source-input", "source-default", "source-processor-db",
-            "source-rest")), "failed to get registered sources : $sources")
+        assertTrue(sources.containsAll(arrayListOf("source-input", "source-default", "source-db",
+                "source-rest", "source-capability")), "failed to get registered sources : $sources")
     }
 
     @Test
@@ -96,27 +104,27 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
 
             val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
-                    "testResolveResource")
+                    ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
+                            "testResolveResource")
 
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
-                "resource-assignment",
-                "baseconfig",
-                props)
+                    "resource-assignment",
+                    "baseconfig",
+                    props)
 
         }
     }
@@ -128,23 +136,23 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
             val artefactNames = listOf("baseconfig", "another")
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(bluePrintRuntimeService,
-                "resource-assignment",
-                artefactNames,
-                props)
+                    "resource-assignment",
+                    artefactNames,
+                    props)
         }
 
     }
@@ -156,27 +164,27 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
             val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
-                    "testResolveResourcesWithMappingAndTemplate")
+                    ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
+                            "testResolveResourcesWithMappingAndTemplate")
 
             val artifactPrefix = "another"
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
-                "resource-assignment",
-                artifactPrefix,
-                props)
+                    "resource-assignment",
+                    artifactPrefix,
+                    props)
         }
     }
 
@@ -190,27 +198,81 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
             val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
-                    "testResolveResourcesWithMappingAndTemplate")
+                    ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
+                            "testResolveResourcesWithMappingAndTemplate")
 
             val artifactPrefix = "another"
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
-                "resource-assignment",
-                artifactPrefix,
-                props)
+                    "resource-assignment",
+                    artifactPrefix,
+                    props)
+        }
+    }
+
+    @Test
+    fun testResourceResolutionForDefinition() {
+        val resourceDefinitions = BluePrintTypes.resourceDefinitions {
+            resourceDefinition(name = "port-speed", description = "Port Speed") {
+                property(type = "string", required = true)
+                sources {
+                    sourceCapability(id = "sdno", description = "SDNO Source") {
+                        definedProperties {
+                            type(BluePrintConstants.SCRIPT_KOTLIN)
+                            scriptClassReference(MockCapabilityScriptRA::class.qualifiedName!!)
+                            keyDependencies(arrayListOf("device-id"))
+                        }
+                    }
+                    sourceDb(id = "sdnc", description = "SDNC Controller") {
+                        definedProperties {
+                            endpointSelector("processor-db")
+                            query("SELECT PORT_SPEED FROM XXXX WHERE DEVICE_ID = :device_id")
+                            inputKeyMapping {
+                                map("device_id", "\$device-id")
+                            }
+                            keyDependencies(arrayListOf("device-id"))
+                        }
+                    }
+                }
+            }
+            resourceDefinition(name = "device-id", description = "Device Id") {
+                property(type = "string", required = true) {
+                    sources {
+                        sourceInput(id = "input", description = "Dependency Source") {}
+                    }
+                }
+            }
+        }
+        runBlocking {
+            val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
+            every { raRuntimeService.bluePrintContext() } returns mockk<BluePrintContext>()
+            every { raRuntimeService.getBluePrintError() } returns BluePrintError()
+            every { raRuntimeService.setBluePrintError(any())} returns Unit
+            every { raRuntimeService.getInputValue("device-id") } returns "123456".asJsonPrimitive()
+
+            val applicationContext = mockk<ApplicationContext>()
+            every { applicationContext.getBean("rr-processor-source-capability") } returns MockCapabilityScriptRA()
+            every { applicationContext.getBean("rr-processor-source-db") } returns MockCapabilityScriptRA()
+            every { applicationContext.getBean("rr-processor-source-input") } returns MockCapabilityScriptRA()
+
+            val sources = arrayListOf<String>("sdno", "sdnc")
+
+            val resourceResolutionService = ResourceResolutionServiceImpl(applicationContext, mockk(), mockk(), mockk())
+            val resolvedResources = resourceResolutionService.resolveResourceDefinition(raRuntimeService,
+                    resourceDefinitions, "port-speed", sources)
+            assertNotNull(resolvedResources, "failed to resolve the resources")
         }
     }
 }
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceDSLTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceDSLTest.kt
new file mode 100644 (file)
index 0000000..2eb2085
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import kotlin.test.Test
+import kotlin.test.assertNotNull
+
+class ResourceSourceDSLTest {
+
+    @Test
+    fun testNodeTypeSourceInput() {
+        val nodeType = BluePrintTypes.nodeTypeSourceInput()
+        //println(nodeType.asJsonString(true))
+        assertNotNull(nodeType, "failed to generate nodeTypeSourceInput")
+    }
+
+    @Test
+    fun testNodeTypeSourceDefault() {
+        val nodeType = BluePrintTypes.nodeTypeSourceDefault()
+        //println(nodeType.asJsonString(true))
+        assertNotNull(nodeType, "failed to generate nodeTypeSourceDefault")
+    }
+
+    @Test
+    fun testNodeTypeSourceDb() {
+        val nodeType = BluePrintTypes.nodeTypeSourceDb()
+        //println(nodeType.asJsonString(true))
+        assertNotNull(nodeType, "failed to generate nodeTypeSourceDb")
+    }
+
+    @Test
+    fun testNodeTypeSourceRest() {
+        val nodeType = BluePrintTypes.nodeTypeSourceRest()
+        //println(nodeType.asJsonString(true))
+        assertNotNull(nodeType, "failed to generate nodeTypeSourceRest")
+    }
+
+    @Test
+    fun testNodeTypeSourceCapability() {
+        val nodeType = BluePrintTypes.nodeTypeSourceCapability()
+        //println(nodeType.asJsonString(true))
+        assertNotNull(nodeType, "failed to generate nodeTypeSourceCapability")
+    }
+
+    @Test
+    fun testNodeTemplateSourceInput() {
+        val nodeTemplate = BluePrintTypes.nodeTemplateSourceInput("InputSystem", "") {
+
+        }
+        //println(nodeTemplate.asJsonString(true))
+        assertNotNull(nodeTemplate, "failed to generate nodeTemplateSourceInput")
+    }
+
+    @Test
+    fun testNodeTemplateSourceDefault() {
+        val nodeTemplate = BluePrintTypes.nodeTemplateSourceDefault("DefaultSystem", "") {
+
+        }
+        //println(nodeTemplate.asJsonString(true))
+        assertNotNull(nodeTemplate, "failed to generate nodeTemplateSourceDefault")
+    }
+
+    @Test
+    fun testNodeTemplateSourceDb() {
+        val nodeTemplate = BluePrintTypes.nodeTemplateSourceDb("DbSystem", "") {
+            definedProperties {
+                type("SQL")
+                query("SELECT * FROM DB WHERE name = \$name")
+                endpointSelector("db-source-endpoint")
+                inputKeyMapping {
+                    map("name", "\$name")
+                }
+                outputKeyMapping {
+                    map("field_name", "\$fieldValue")
+                }
+                keyDependencies(arrayListOf("name"))
+            }
+        }
+        //println(nodeTemplate.asJsonString(true))
+        assertNotNull(nodeTemplate, "failed to generate nodeTemplateSourceDb")
+    }
+
+    @Test
+    fun testNodeTemplateSourceRest() {
+        val nodeTemplate = BluePrintTypes.nodeTemplateSourceRest("restSystem", "") {
+            definedProperties {
+                type("JSON")
+                endpointSelector("rest-source-endpoint")
+                expressionType("JSON_PATH")
+                urlPath("/location")
+                path(".\$name")
+                verb("GET")
+                payload("sample payload")
+                inputKeyMapping {
+                    map("name", "\$name")
+                }
+                outputKeyMapping {
+                    map("field_name", "\$fieldValue")
+                }
+                keyDependencies(arrayListOf("name"))
+            }
+        }
+        //println(nodeTemplate.asJsonString(true))
+        assertNotNull(nodeTemplate, "failed to generate nodeTemplateSourceRest")
+    }
+
+    @Test
+    fun testNodeTemplateSourceCapability() {
+        val nodeTemplate = BluePrintTypes.nodeTemplateSourceCapability("capabiltySystem", "") {
+            definedProperties {
+                type("kotlin")
+                scriptClassReference("Scripts/Sample.kt")
+                keyDependencies(arrayListOf("name"))
+            }
+        }
+        //println(nodeTemplate.asJsonString(true))
+        assertNotNull(nodeTemplate, "failed to generate nodeTemplateSourceCapability")
+    }
+}
\ No newline at end of file
index 4a4bcc0..f020f29 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor
 
+import io.mockk.coEvery
+import io.mockk.every
+import io.mockk.mockk
 import kotlinx.coroutines.runBlocking
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceAssignment
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts.BlueprintJythonService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts.PythonExecutorProperty
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintScriptsServiceImpl
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
 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 org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
-import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintScriptsServiceImpl
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
 import org.springframework.test.context.junit4.SpringRunner
+import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
 
 @RunWith(SpringRunner::class)
 @ContextConfiguration(classes = [CapabilityResourceResolutionProcessor::class, ComponentFunctionScriptingService::class,
@@ -50,44 +59,36 @@ class CapabilityResourceResolutionProcessorTest {
     @Autowired
     lateinit var capabilityResourceResolutionProcessor: CapabilityResourceResolutionProcessor
 
-    @Ignore
     @Test
     fun `test kotlin capability`() {
         runBlocking {
-
-            val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext(
-                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
-
-            val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext)
-
-            capabilityResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService
-            capabilityResourceResolutionProcessor.resourceDictionaries = hashMapOf()
-
-
-            val scriptPropertyInstances: MutableMap<String, Any> = mutableMapOf()
-            scriptPropertyInstances["mock-service1"] = MockCapabilityService()
-            scriptPropertyInstances["mock-service2"] = MockCapabilityService()
-
-            val instanceDependencies: List<String> = listOf()
-
-            val resourceAssignmentProcessor = capabilityResourceResolutionProcessor
-                    .scriptInstance("kotlin",
-                            "ResourceAssignmentProcessor_cba\$ScriptResourceAssignmentProcessor", instanceDependencies)
-
-            assertNotNull(resourceAssignmentProcessor, "couldn't get kotlin script resource assignment processor")
-
-            val resourceAssignment = ResourceAssignment().apply {
-                name = "ra-name"
-                dictionaryName = "ra-dict-name"
-                dictionarySource = "capability"
-                property = PropertyDefinition().apply {
-                    type = "string"
+            val componentFunctionScriptingService = mockk<ComponentFunctionScriptingService>()
+            coEvery {
+                componentFunctionScriptingService
+                        .scriptInstance<ResourceAssignmentProcessor>(any(), any(), any())
+            } returns MockCapabilityScriptRA()
+
+            val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
+            every { raRuntimeService.bluePrintContext() } returns mockk<BluePrintContext>()
+
+            val capabilityResourceResolutionProcessor = CapabilityResourceResolutionProcessor(componentFunctionScriptingService)
+            capabilityResourceResolutionProcessor.raRuntimeService = raRuntimeService
+
+            val resourceAssignment = BluePrintTypes.resourceAssignment(name = "test-property", dictionaryName = "ra-dict-name",
+                    dictionarySource = "capability") {
+                property("string", true, "")
+                sourceCapability {
+                    definedProperties {
+                        type("internal")
+                        scriptClassReference(MockCapabilityScriptRA::class.qualifiedName!!)
+                        keyDependencies(arrayListOf("dep-property"))
+                    }
                 }
             }
-
-            val processorName = resourceAssignmentProcessor.applyNB(resourceAssignment)
-            assertNotNull(processorName, "couldn't get kotlin script resource assignment processor name")
-            println(processorName)
+            val status = capabilityResourceResolutionProcessor.applyNB(resourceAssignment)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals("assigned-data".asJsonPrimitive(), resourceAssignment.property!!.value,
+                    "assigned value miss match")
         }
     }
 
@@ -127,4 +128,21 @@ class CapabilityResourceResolutionProcessorTest {
 
 open class MockCapabilityService {
 
+}
+
+open class MockCapabilityScriptRA : ResourceAssignmentProcessor() {
+    val log = logger(MockCapabilityScriptRA::class)
+
+    override fun getName(): String {
+        return "MockCapabilityScriptRA"
+    }
+
+    override suspend fun processNB(executionRequest: ResourceAssignment) {
+        log.info("executing RA mock capability : ${executionRequest.name}")
+        executionRequest.property!!.value = "assigned-data".asJsonPrimitive()
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
 }
\ No newline at end of file
index efefe02..fd889bf 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.db
 
-import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.BluePrintDBLibPropertySevice
+import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.PrimaryDBLibGenericService
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.ComponentScan
@@ -39,15 +40,15 @@ open class BluePrintDBLibConfiguration(private var bluePrintProperties: BluePrin
 /**
  * Exposed Dependency Service by this SSH Lib Module
  */
-//TODO("right now not wired with name ")
 fun BluePrintDependencyService.dbLibPropertyService(): BluePrintDBLibPropertySevice =
-        instance(DBLibConstants.SERVICE_BLUEPRINT_DB_LIB_PROPERTY)
+        instance(BluePrintDBLibPropertySevice::class)
+
+fun BluePrintDependencyService.primaryDBLibGenericService(): BluePrintDBLibGenericService =
+        instance(PrimaryDBLibGenericService::class)
 
 
 class DBLibConstants {
     companion object {
-        //TODO("right now not wired with name ")
-        const val SERVICE_BLUEPRINT_DB_LIB_PROPERTY = "blueprint-db-lib-property-service"
         const val PREFIX_DB_PRIMARY: String = "blueprintsprocessor.db.primary"
 
         //list of database
@@ -62,7 +63,5 @@ class DBLibConstants {
         const val DRIVER_MYSQL_DB = "com.mysql.jdbc.Driver"
         const val DRIVER_ORACLE_DB = "oracle.jdbc.driver.OracleDriver"
         const val DRIVER_POSTGRES_DB = "org.postgresql.Driver"
-
-
     }
 }
\ No newline at end of file
index cf2ca55..2ae5042 100644 (file)
@@ -32,7 +32,7 @@ class BluePrintDBLibPropertySevice(private var bluePrintProperties: BluePrintPro
     }
 
     fun JdbcTemplate(selector: String): BluePrintDBLibGenericService {
-        val prefix = "blueprintsprocessor.database.$selector"
+        val prefix = "blueprintsprocessor.db.$selector"
         val dBConnetionProperties = dBDataSourceProperties(prefix)
         return blueprintDBDataSourceService(dBConnetionProperties)
     }
index da4d993..4f68657 100644 (file)
@@ -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)
index 602033a..facbec5 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.kafka.clients.consumer.ConsumerConfig
 import org.apache.kafka.common.serialization.StringDeserializer
 import org.junit.After
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers
@@ -65,7 +66,8 @@ import java.io.File
 import java.nio.file.Files
 import java.nio.file.Paths
 import kotlin.test.assertNotNull
-
+//FIXME("testReceive method is failing in server build, It is not stable, may be timing issue.")
+@Ignore
 @RunWith(SpringRunner::class)
 @EnableAutoConfiguration
 @ContextConfiguration(classes = [MessagingControllerTest::class, SecurityProperties::class])
index de6a8bd..89338b7 100644 (file)
@@ -23,9 +23,10 @@ import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
-import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateImplBuilder
+import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateOperationImplBuilder
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder
 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType
+import kotlin.reflect.KClass
 
 /** Component Extensions **/
 
@@ -65,49 +66,55 @@ fun BluePrintTypes.nodeTypeComponentScriptExecutor(): NodeType {
 /** Component Builder */
 fun BluePrintTypes.nodeTemplateComponentScriptExecutor(id: String,
                                                        description: String,
-                                                       block: ComponentScriptExecutorNodeTemplateImplBuilder.() -> Unit)
+                                                       block: ComponentScriptExecutorNodeTemplateBuilder.() -> Unit)
         : NodeTemplate {
-    return ComponentScriptExecutorNodeTemplateImplBuilder(id, description).apply(block).build()
+    return ComponentScriptExecutorNodeTemplateBuilder(id, description).apply(block).build()
 }
 
-class ComponentScriptExecutorNodeTemplateImplBuilder(id: String, description: String) :
-        AbstractNodeTemplateImplBuilder<ComponentScriptExecutorInputAssignmentBuilder,
-                ComponentScriptExecutorOutputAssignmentBuilder>(id, "component-script-executor",
+class ComponentScriptExecutorNodeTemplateBuilder(id: String, description: String) :
+        AbstractNodeTemplateOperationImplBuilder<PropertiesAssignmentBuilder,
+                ComponentScriptExecutorNodeTemplateBuilder.InputsBuilder,
+                ComponentScriptExecutorNodeTemplateBuilder.OutputsBuilder>(id, "component-script-executor",
                 "ComponentScriptExecutor",
-                description)
+                description) {
 
-class ComponentScriptExecutorInputAssignmentBuilder : PropertiesAssignmentBuilder() {
+    class InputsBuilder : PropertiesAssignmentBuilder() {
 
-    fun type(type: String) = type(type.asJsonPrimitive())
+        fun type(type: String) = type(type.asJsonPrimitive())
 
-    fun type(type: JsonNode) {
-        property(ComponentScriptExecutor.INPUT_SCRIPT_TYPE, type)
-    }
+        fun type(type: JsonNode) {
+            property(ComponentScriptExecutor.INPUT_SCRIPT_TYPE, type)
+        }
+
+        fun scriptClassReference(scriptClassReference: KClass<*>) {
+            scriptClassReference(scriptClassReference.qualifiedName!!)
+        }
 
-    fun scriptClassReference(scriptClassReference: String) = scriptClassReference(scriptClassReference.asJsonPrimitive())
+        fun scriptClassReference(scriptClassReference: String) = scriptClassReference(scriptClassReference.asJsonPrimitive())
 
-    fun scriptClassReference(scriptClassReference: JsonNode) {
-        property(ComponentScriptExecutor.INPUT_SCRIPT_CLASS_REFERENCE, scriptClassReference)
-    }
+        fun scriptClassReference(scriptClassReference: JsonNode) {
+            property(ComponentScriptExecutor.INPUT_SCRIPT_CLASS_REFERENCE, scriptClassReference)
+        }
 
-    fun dynamicProperties(dynamicProperties: String) = dynamicProperties(dynamicProperties.asJsonType())
+        fun dynamicProperties(dynamicProperties: String) = dynamicProperties(dynamicProperties.asJsonType())
 
-    fun dynamicProperties(dynamicProperties: JsonNode) {
-        property(ComponentScriptExecutor.INPUT_DYNAMIC_PROPERTIES, dynamicProperties)
+        fun dynamicProperties(dynamicProperties: JsonNode) {
+            property(ComponentScriptExecutor.INPUT_DYNAMIC_PROPERTIES, dynamicProperties)
+        }
     }
-}
 
-class ComponentScriptExecutorOutputAssignmentBuilder : PropertiesAssignmentBuilder() {
+    class OutputsBuilder : PropertiesAssignmentBuilder() {
 
-    fun status(status: String) = status(status.asJsonPrimitive())
+        fun status(status: String) = status(status.asJsonPrimitive())
 
-    fun status(status: JsonNode) {
-        property(ComponentScriptExecutor.OUTPUT_STATUS, status)
-    }
+        fun status(status: JsonNode) {
+            property(ComponentScriptExecutor.OUTPUT_STATUS, status)
+        }
 
-    fun responseData(responseData: String) = responseData(responseData.asJsonType())
+        fun responseData(responseData: String) = responseData(responseData.asJsonType())
 
-    fun responseData(responseData: JsonNode) {
-        property(ComponentScriptExecutor.OUTPUT_RESPONSE_DATA, responseData)
+        fun responseData(responseData: JsonNode) {
+            property(ComponentScriptExecutor.OUTPUT_RESPONSE_DATA, responseData)
+        }
     }
 }
\ No newline at end of file
index da21970..554df8b 100755 (executable)
     <name>Blueprints Processor Parent</name>
     <description>Blueprints Processor Parent</description>
     <properties>
-        <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
-        <grpc.version>1.18.0</grpc.version>
         <sshd.version>2.2.0</sshd.version>
         <jsch.version>0.1.55</jsch.version>
-        <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version>
         <spring.kafka.version>2.2.6.RELEASE</spring.kafka.version>
         <kafka.version>2.2.0</kafka.version>
         <eelf.version>1.0.0</eelf.version>
         <h2database.version>1.4.197</h2database.version>
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
         <powermock.version>1.7.4</powermock.version>
-        <mockk.version>1.9</mockk.version>
         <dmaap.client.version>1.1.5</dmaap.client.version>
         <jinja.version>2.5.1</jinja.version>
         <velocity.version>1.7</velocity.version>
+        <json.unit.version>2.8.0</json.unit.version>
         <mockkserver.version>5.5.1</mockkserver.version>
         <jsoup.version>1.10.3</jsoup.version>
     </properties>
                 <artifactId>commons-io</artifactId>
                 <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>
                 <artifactId>guava</artifactId>
                 <version>${guava.version}</version>
             </dependency>
+            <dependency>
+                <groupId>net.javacrumbs.json-unit</groupId>
+                <artifactId>json-unit-json-path</artifactId>
+                <version>${json.unit.version}</version>
+                <scope>compile</scope>
+            </dependency>
             <dependency>
                 <groupId>org.python</groupId>
                 <artifactId>jython-standalone</artifactId>
             <groupId>commons-io</groupId>
             <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>
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-json-path</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
index 725b0c3..c66afab 100755 (executable)
@@ -42,6 +42,7 @@
 
     <modules>
         <module>parent</module>
+        <module>cba-parent</module>
         <module>modules</module>
         <module>functions</module>
         <module>application</module>
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintExtensionFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintExtensionFunctions.kt
new file mode 100644 (file)
index 0000000..dafd076
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core
+
+import org.onap.ccsdk.cds.controllerblueprints.core.annotations.*
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ConstraintClause
+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.dsl.*
+import kotlin.reflect.KClass
+import kotlin.reflect.KProperty1
+import kotlin.reflect.KType
+import kotlin.reflect.full.declaredMemberProperties
+
+fun <T : KClass<*>> T.asBluePrintsDataTypes(): DataType {
+    val annotation = this.annotations.filter { it is BluePrintsDataType }.single() as BluePrintsDataType
+    checkNotNull(annotation) { "BluePrintsDataType annotation definition not found" }
+    val dataType = DataType().apply {
+        id = annotation.name
+        version = annotation.version
+        derivedFrom = annotation.derivedFrom
+        description = annotation.description
+    }
+    dataType.properties = this.asPropertyDefinitionMap()
+    return dataType
+}
+
+fun <T : KClass<*>> T.asPropertyDefinitionMap(): MutableMap<String, PropertyDefinition> {
+    val properties: MutableMap<String, PropertyDefinition> = hashMapOf()
+    this.declaredMemberProperties.forEach { member ->
+        properties[member.name] = member.asPropertyDefinition()
+    }
+    return properties
+}
+
+fun <T> KProperty1<T, *>.asPropertyDefinition(): PropertyDefinition {
+    val property = PropertyDefinition()
+    property.id = this.name
+    val getter = this.getter
+    property.required = !this.returnType.isMarkedNullable
+    property.type = this.returnType.asBluePrintsDataType(this.name)
+    if (this.returnType.arguments.isNotEmpty()) {
+        property.entrySchema = this.returnType.entitySchema()
+    }
+    this.annotations.forEach { fieldAnnotation ->
+        //println("Field : ${this.name} : Annotation : $fieldAnnotation")
+        when (fieldAnnotation) {
+            is BluePrintsProperty ->
+                property.description = fieldAnnotation.description
+            is PropertyDefaultValue ->
+                property.value = fieldAnnotation.value.asJsonType(property.type)
+            is BluePrintsConstrain -> {
+                if (property.constraints == null) property.constraints = arrayListOf()
+                property.constraints!!.add(fieldAnnotation.asBluePrintConstraintClause())
+            }
+            is InputExpression -> {
+                property.value = getInput(fieldAnnotation.propertyName)
+            }
+            is PropertyExpression -> {
+                property.value = getNodeTemplateProperty(fieldAnnotation.modelableEntityName,
+                        fieldAnnotation.propertyName, fieldAnnotation.subPropertyName)
+            }
+            is AttributeExpression -> {
+                property.value = getNodeTemplateAttribute(fieldAnnotation.modelableEntityName,
+                        fieldAnnotation.attributeName, fieldAnnotation.subAttributeName)
+            }
+            is ArtifactExpression -> {
+                property.value = getNodeTemplateArtifact(fieldAnnotation.modelableEntityName,
+                        fieldAnnotation.artifactName)
+            }
+            is OperationOutputExpression -> {
+                property.value = getNodeTemplateOperationOutput(fieldAnnotation.modelableEntityName,
+                        fieldAnnotation.interfaceName, fieldAnnotation.propertyName, fieldAnnotation.subPropertyName)
+            }
+            is DSLExpression -> {
+                property.value = dslExpression(fieldAnnotation.propertyName)
+            }
+        }
+    }
+    return property
+}
+
+internal fun BluePrintsConstrain.asBluePrintConstraintClause(): ConstraintClause {
+    TODO()
+}
+
+internal fun <T : KType> T.entitySchema(): EntrySchema {
+    val entrySchema = EntrySchema()
+    if (this.arguments.size == 1) {
+        entrySchema.type = this.arguments[0].type!!.asBluePrintsDataType("")
+    } else if (this.arguments.size == 2) {
+        entrySchema.type = this.arguments[1].type!!.asBluePrintsDataType("")
+    }
+    return entrySchema
+}
+
+internal fun <T : KType> T.asBluePrintsDataType(propertyName: String): String {
+    val simpleName = (this.classifier as? KClass<*>)?.java?.simpleName
+            ?: throw BluePrintException("filed to get simple name.")
+    return when (simpleName) {
+        "String", "Date" -> BluePrintConstants.DATA_TYPE_STRING
+        "int" -> BluePrintConstants.DATA_TYPE_INTEGER
+        "Boolean" -> BluePrintConstants.DATA_TYPE_BOOLEAN
+        "Float" -> BluePrintConstants.DATA_TYPE_FLOAT
+        "Double" -> BluePrintConstants.DATA_TYPE_DOUBLE
+        "List" ->  BluePrintConstants.DATA_TYPE_LIST
+        "Map" -> BluePrintConstants.DATA_TYPE_MAP
+        "Object", "JsonNode", "ObjectNode", "ArrayNode" -> BluePrintConstants.DATA_TYPE_JSON
+        else -> simpleName
+    }
+}
\ No newline at end of file
index 2717c3b..c77427b 100644 (file)
@@ -21,9 +21,10 @@ import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.node.*
 import org.apache.commons.lang3.ObjectUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
-import org.slf4j.LoggerFactory
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JsonParserUtils
+import org.slf4j.LoggerFactory
 import org.slf4j.helpers.MessageFormatter
+import java.lang.Float
 import kotlin.reflect.KClass
 
 /**
@@ -93,6 +94,19 @@ fun <T : Any?> T.asJsonPrimitive(): JsonNode {
     }
 }
 
+/** Based on Blueprint DataType Convert string value to JsonNode Type **/
+fun String.asJsonType(bpDataType: String): JsonNode {
+    return when (bpDataType.toLowerCase()) {
+        BluePrintConstants.DATA_TYPE_STRING -> this.asJsonPrimitive()
+        BluePrintConstants.DATA_TYPE_BOOLEAN -> java.lang.Boolean.valueOf(this).asJsonPrimitive()
+        BluePrintConstants.DATA_TYPE_INTEGER -> Integer.valueOf(this).asJsonPrimitive()
+        BluePrintConstants.DATA_TYPE_FLOAT -> Float.valueOf(this).asJsonPrimitive()
+        BluePrintConstants.DATA_TYPE_DOUBLE -> java.lang.Double.valueOf(this).asJsonPrimitive()
+        // For List, Map and Complex Types.
+        else -> this.jsonAsJsonType()
+    }
+}
+
 /**
  * Utility to convert Complex or Primitive object to Json Type.
  */
@@ -156,6 +170,16 @@ fun ArrayNode.asListOfString(): List<String> {
     return JacksonUtils.getListFromJsonNode(this, String::class.java)
 }
 
+fun <T> JsonNode.asType(clazzType: Class<T>): T {
+    return JacksonUtils.readValue(this, clazzType)
+            ?: throw BluePrintException("couldn't convert JsonNode of type $clazzType")
+}
+
+fun JsonNode.asListOfString(): List<String> {
+    check(this is ArrayNode) { "JsonNode is not of type ArrayNode" }
+    return this.asListOfString()
+}
+
 fun JsonNode.returnNullIfMissing(): JsonNode? {
     return if (this is NullNode || this is MissingNode) {
         null
@@ -255,6 +279,9 @@ fun isNotBlank(value: String?): Boolean {
     return value != null && value.isNotBlank()
 }
 
+fun <T : String> T?.emptyTONull(): String? {
+    return if (this == null || this.isEmpty()) null else this
+}
 
 fun nullToEmpty(value: String?): String {
     return if (isNotEmpty(value)) value!! else ""
index 18091e6..518e9b2 100644 (file)
@@ -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/annotations/BluePrintsAnnotations.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/annotations/BluePrintsAnnotations.kt
new file mode 100644 (file)
index 0000000..94392b9
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core.annotations
+
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import kotlin.reflect.KClass
+
+@Target(AnnotationTarget.CLASS)
+annotation class BluePrintsDataType(
+        val name: String,
+        val version: String = BluePrintConstants.DEFAULT_VERSION_NUMBER,
+        val description: String,
+        val derivedFrom: String = "tosca.datatypes.root"
+)
+
+@Target(AnnotationTarget.CLASS)
+annotation class BluePrintsWorkflowInput
+
+@Target(AnnotationTarget.CLASS)
+annotation class BluePrintsWorkflowOutput
+
+@Target(AnnotationTarget.CLASS)
+annotation class BluePrintsNodeType(val propertiesType: KClass<*>, val attributesType: KClass<*>,
+                                    val inputsType: KClass<*>, val outputsType: KClass<*>)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class BluePrintsProperty(
+        val name: String = "",
+        val description: String = ""
+)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+@Repeatable
+annotation class BluePrintsConstrain()
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class PropertyDefaultValue(val value: String)
+
+annotation class PropertyValidValue(val value: String)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class InputExpression(
+        val propertyName: String
+)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class PropertyExpression(
+        val modelableEntityName: String = "SELF",
+        val reqOrCapEntityName: String = "",
+        val propertyName: String,
+        val subPropertyName: String = ""
+)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class AttributeExpression(
+        val modelableEntityName: String = "SELF",
+        val reqOrCapEntityName: String = "",
+        val attributeName: String,
+        val subAttributeName: String = ""
+)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class ArtifactExpression(
+        val modelableEntityName: String = "SELF",
+        val artifactName: String,
+        val location: String = "LOCAL_FILE",
+        val remove: Boolean = false
+)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class OperationOutputExpression(
+        val modelableEntityName: String = "SELF",
+        val interfaceName: String,
+        val operationName: String,
+        val propertyName: String,
+        val subPropertyName: String = ""
+)
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY)
+annotation class DSLExpression(
+        val propertyName: String
+)
\ No newline at end of file
 
 package org.onap.ccsdk.cds.controllerblueprints.core.dsl
 
-abstract class AbstractNodeTemplateImplBuilder<In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder>(
+abstract class AbstractNodeTemplateOperationImplBuilder<Prop : PropertiesAssignmentBuilder,
+        In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder>(
         id: String, type: String, private val interfaceName: String, description: String
-) : NodeTemplateBuilder(id, type, description) {
+) : AbstractNodeTemplatePropertyImplBuilder<Prop>(id, type, description) {
 
-    open fun operation(description: String, block: OperationAssignmentBuilder<In, Out>.() -> Unit) {
+    open fun definedOperation(description: String, block: OperationAssignmentBuilder<In, Out>.() -> Unit) {
         typedOperation<In, Out>(interfaceName, description, block)
     }
 }
+
+abstract class AbstractNodeTemplatePropertyImplBuilder<Prop : PropertiesAssignmentBuilder>(
+        id: String, type: String, description: String
+) : NodeTemplateBuilder(id, type, description) {
+
+    open fun definedProperties(block: Prop.() -> Unit) {
+        typedProperties<Prop>(block)
+    }
+}
index c88408f..01c6a13 100644 (file)
@@ -19,6 +19,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core.dsl
 import com.fasterxml.jackson.databind.JsonNode
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.cds.controllerblueprints.core.data.*
 import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType
 
@@ -63,56 +64,66 @@ fun relationshipType(id: String, version: String, derivedFrom: String, descripti
     return RelationshipTypeBuilder(id, version, derivedFrom, description).apply(block).build()
 }
 
+// DSL Function
+fun dslExpression(key: String): JsonNode {
+    return ("*$key").asJsonPrimitive()
+}
 // Input Function
 
-fun getInput(inputKey: String): JsonNode {
+fun getInput(inputKey: String, jsonPath: String? = null): JsonNode {
     return """{"get_input": "$inputKey"}""".jsonAsJsonType()
 }
 
-fun getAttribute(attributeId: String): JsonNode {
-    return """{"get_attribute": ["SELF", "$attributeId"]}""".jsonAsJsonType()
-}
-
-fun getAttribute(attributeId: String, jsonPath: String): JsonNode {
-    return """{"get_attribute": ["SELF", "$attributeId", "$jsonPath"]}""".jsonAsJsonType()
+fun getAttribute(attributeId: String, jsonPath: String? = null): JsonNode {
+    return getNodeTemplateAttribute("SELF", attributeId, jsonPath)
 }
 
 fun getNodeTemplateAttribute(nodeTemplateId: String, attributeId: String): JsonNode {
-    return """{"get_attribute": ["$nodeTemplateId", "$attributeId"]}""".jsonAsJsonType()
+    return getNodeTemplateAttribute(nodeTemplateId, attributeId, null)
 }
 
-fun getNodeTemplateAttribute(nodeTemplateId: String, attributeId: String, jsonPath: String): JsonNode {
-    return """{"get_attribute": ["$nodeTemplateId", "$attributeId", "$jsonPath]}""".jsonAsJsonType()
+fun getNodeTemplateAttribute(nodeTemplateId: String, attributeId: String, jsonPath: String?): JsonNode {
+    return if (jsonPath.isNullOrEmpty() || jsonPath.isNullOrBlank()) {
+        """{"get_attribute": ["$nodeTemplateId", "$attributeId"]}""".jsonAsJsonType()
+    } else {
+        """{"get_attribute": ["$nodeTemplateId", "$attributeId", "$jsonPath"]}""".jsonAsJsonType()
+    }
 }
 
 // Property Function
 
-fun getProperty(propertyId: String): JsonNode {
-    return """{"get_property": ["SELF", "$propertyId"]}""".jsonAsJsonType()
-}
-
-fun getProperty(propertyId: String, jsonPath: String): JsonNode {
-    return """{"get_property": ["SELF", "$propertyId", "$jsonPath"]}""".jsonAsJsonType()
+fun getProperty(propertyId: String, jsonPath: String? = null): JsonNode {
+    return getNodeTemplateProperty("SELF", propertyId, jsonPath)
 }
 
 fun getNodeTemplateProperty(nodeTemplateName: String, propertyId: String): JsonNode {
-    return """{"get_property": ["$nodeTemplateName", "$propertyId"]}""".jsonAsJsonType()
+    return getNodeTemplateProperty(nodeTemplateName, propertyId, null)
 }
 
-fun getNodeTemplateProperty(nodeTemplateName: String, propertyId: String, jsonPath: String): JsonNode {
-    return """{"get_property": ["$nodeTemplateName", "$propertyId", "$jsonPath]}""".jsonAsJsonType()
+fun getNodeTemplateProperty(nodeTemplateName: String, propertyId: String, jsonPath: String?): JsonNode {
+    return if (jsonPath.isNullOrEmpty() || jsonPath.isNullOrBlank()) {
+        """{"get_property": ["$nodeTemplateName", "$propertyId"]}""".jsonAsJsonType()
+    } else {
+        """{"get_property": ["$nodeTemplateName", "$propertyId", "$jsonPath"]}""".jsonAsJsonType()
+    }
 }
 
 // Artifact Function
 
 fun getArtifact(artifactId: String): JsonNode {
-    return """{"get_artifact": ["SELF", "$artifactId"]}""".jsonAsJsonType()
+    return getNodeTemplateArtifact("SELF", artifactId)
 }
 
 fun getNodeTemplateArtifact(nodeTemplateName: String, artifactId: String): JsonNode {
     return """{"get_artifact": ["$nodeTemplateName", "$artifactId"]}""".jsonAsJsonType()
 }
 
+// Operation Function
+
+fun getNodeTemplateOperationOutput(nodeTemplateName: String, interfaceName: String, propertyId: String,
+                                   jsonPath: String? = null): JsonNode {
+    return """{"get_operation_output": ["$nodeTemplateName", "$interfaceName", "process","$propertyId","$jsonPath" ]}""".trimMargin().jsonAsJsonType()
+}
 
 /** Blueprint Type Extensions */
 
index c9f7d50..06d3421 100644 (file)
@@ -17,9 +17,9 @@
 package org.onap.ccsdk.cds.controllerblueprints.core.dsl
 
 import com.fasterxml.jackson.databind.JsonNode
-import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
-import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.*
 import org.onap.ccsdk.cds.controllerblueprints.core.data.*
+import kotlin.reflect.KClass
 
 class ServiceTemplateBuilder(private val name: String,
                              private val version: String,
@@ -54,6 +54,14 @@ class ServiceTemplateBuilder(private val name: String,
         imports.add(importDefinition)
     }
 
+    fun dsl(id: String, kclass: KClass<*>) {
+        dsl(id, kclass.asPropertyDefinitionMap().asJsonNode())
+    }
+
+    fun dataType(dataType: KClass<*>) {
+        dataType(dataType.asBluePrintsDataTypes())
+    }
+
     fun dsl(id: String, content: Any) {
         dsl(id, content.asJsonType())
     }
index 685473f..7f49a99 100644 (file)
@@ -108,6 +108,13 @@ open class NodeTemplateBuilder(private val id: String,
         properties = PropertiesAssignmentBuilder().apply(block).build()
     }
 
+    open fun <Prop : PropertiesAssignmentBuilder> typedProperties(block: Prop.() -> Unit) {
+        if (properties == null)
+            properties = hashMapOf()
+        val instance: Prop = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Prop>).createInstance()
+        properties = instance.apply(block).build()
+    }
+
     open fun <In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder> typedOperation(
             interfaceName: String, description: String = "",
             block: OperationAssignmentBuilder<In, Out>.() -> Unit) {
index f98cf58..6d46ac7 100644 (file)
 package org.onap.ccsdk.cds.controllerblueprints.core.dsl
 
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.asPropertyDefinitionMap
 import org.onap.ccsdk.cds.controllerblueprints.core.data.Activity
 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
 import org.onap.ccsdk.cds.controllerblueprints.core.data.Step
 import org.onap.ccsdk.cds.controllerblueprints.core.data.Workflow
+import kotlin.reflect.KClass
 
 class WorkflowBuilder(private val id: String, private val description: String) {
 
@@ -46,6 +48,10 @@ class WorkflowBuilder(private val id: String, private val description: String) {
         steps!![id] = StepBuilder(id, target, description).apply(block).build()
     }
 
+    fun inputs(kClazz: KClass<*>) {
+        inputs = kClazz.asPropertyDefinitionMap()
+    }
+
     fun inputs(block: PropertiesDefinitionBuilder.() -> Unit) {
         inputs = PropertiesDefinitionBuilder().apply(block).build()
     }
@@ -54,6 +60,10 @@ class WorkflowBuilder(private val id: String, private val description: String) {
         outputs = PropertiesDefinitionBuilder().apply(block).build()
     }
 
+    fun outputs(kClazz: KClass<*>) {
+        outputs = kClazz.asPropertyDefinitionMap()
+    }
+
     fun build(): Workflow {
         workflow.id = id
         workflow.description = description
index fdaf25c..776e041 100644 (file)
@@ -18,6 +18,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service
 
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.springframework.context.ApplicationContext
+import kotlin.reflect.KClass
 
 /**
  * Generic Bluepring Dependency Service, which will be used mainly in scripts.
@@ -44,4 +45,9 @@ object BluePrintDependencyService {
         return applicationContext.getBean(type)
                 ?: throw BluePrintProcessorException("failed to get instance($type)")
     }
+
+    inline fun <reified T> instance(type: KClass<*>): T {
+        return applicationContext.getBean(type.java) as? T
+                ?: throw BluePrintProcessorException("failed to get instance($type)")
+    }
 }
\ No newline at end of file
index 8517be8..2f082db 100755 (executable)
@@ -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.
 
 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())
index 9b1b66b..768f875 100644 (file)
@@ -238,11 +238,14 @@ class JacksonUtils {
 
         fun populatePrimitiveValues(key: String, value: Any, primitiveType: String, objectNode: ObjectNode) {
             when (primitiveType.toLowerCase()) {
-                BluePrintConstants.DATA_TYPE_BOOLEAN -> objectNode.put(key, (value as BooleanNode).booleanValue())
-                BluePrintConstants.DATA_TYPE_INTEGER -> objectNode.put(key, (value as IntNode).intValue())
-                BluePrintConstants.DATA_TYPE_FLOAT -> objectNode.put(key, (value as FloatNode).floatValue())
-                BluePrintConstants.DATA_TYPE_DOUBLE -> objectNode.put(key, (value as DoubleNode).doubleValue())
-                else -> objectNode.put(key, (value as TextNode).textValue())
+                BluePrintConstants.DATA_TYPE_STRING,
+                BluePrintConstants.DATA_TYPE_BOOLEAN,
+                BluePrintConstants.DATA_TYPE_INTEGER,
+                BluePrintConstants.DATA_TYPE_FLOAT,
+                BluePrintConstants.DATA_TYPE_DOUBLE,
+                BluePrintConstants.DATA_TYPE_TIMESTAMP ->
+                    objectNode.set(key, value.asJsonPrimitive())
+                else -> objectNode.set(key, value.asJsonType())
             }
         }
 
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/annotations/BluePrintsAnnotationsTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/annotations/BluePrintsAnnotationsTest.kt
new file mode 100644 (file)
index 0000000..c24ed03
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core.annotations
+
+import com.fasterxml.jackson.databind.JsonNode
+import org.onap.ccsdk.cds.controllerblueprints.core.asBluePrintsDataTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asPropertyDefinitionMap
+import kotlin.test.Test
+import kotlin.test.assertNotNull
+
+class BluePrintsAnnotationsTest {
+
+    @Test
+    fun testBluePrintWorkflowData() {
+        val wfInput = TestBluePrintsWorkflowInput::class.asPropertyDefinitionMap()
+        //println(wfInput.asJsonString(true))
+        assertNotNull(wfInput, "failed to generate wfInput property map")
+
+        val wfOutput = TestBluePrintsWorkflowOutput::class.asPropertyDefinitionMap()
+        //println(wfOutput.asJsonString(true))
+        assertNotNull(wfInput, "failed to generate wfOutput property map")
+    }
+
+    @Test
+    fun testBluePrintDataType() {
+        val dataTypes = TestBluePrintsDataType::class.asBluePrintsDataTypes()
+        //println(dataTypes.asJsonString(true))
+        assertNotNull(dataTypes, "failed to generate dataTypes definition")
+    }
+}
+
+@BluePrintsDataType(name = "dt-test-datatype", description = "I am test",
+        version = "1.0.0", derivedFrom = "tosca.datatypes.root")
+data class TestBluePrintsDataType(
+        @BluePrintsProperty(description = "this stringData")
+        var stringData: String,
+        @BluePrintsProperty(description = "this stringDataWithValue")
+        @PropertyDefaultValue(value = "USA")
+        val stringDataWithValue: String,
+        @BluePrintsProperty(description = "this intDataWithValue")
+        @PropertyDefaultValue(value = "30")
+        val intDataWithValue: Int,
+        @BluePrintsProperty(description = "this booleanDataWithValue")
+        @PropertyDefaultValue(value = "true")
+        val booleanDataWithValue: Boolean,
+        @BluePrintsProperty(description = "this anyData")
+        val anyData: Any,
+        @BluePrintsProperty(description = "this jsonDataWithValue")
+        @PropertyDefaultValue(value = """{"data" : "1234"}""")
+        val jsonDataWithValue: JsonNode?,
+        @BluePrintsProperty(description = "listData")
+        val listData: MutableList<String>,
+        @BluePrintsProperty(description = "this mapData")
+        val mapData: MutableMap<String, String> = hashMapOf(),
+        @BluePrintsProperty(description = "this complexData")
+        val complexData: TestBluePrintsChildDataType?,
+        @BluePrintsProperty(description = "this complexDataList")
+        val complexDataList: MutableList<TestBluePrintsChildDataType>
+)
+
+data class TestBluePrintsChildDataType(val name: String)
+
+
+@BluePrintsWorkflowInput
+data class TestBluePrintsWorkflowInput(
+        @BluePrintsProperty(description = "this sample name")
+        @PropertyDefaultValue(value = "Brinda")
+        var name: String,
+        @BluePrintsProperty(description = "this sample name")
+        val place: String
+)
+
+@BluePrintsWorkflowOutput
+data class TestBluePrintsWorkflowOutput(
+        @BluePrintsProperty(description = "this is dslExpression")
+        @DSLExpression("field1")
+        var dslExpression: String,
+
+        @BluePrintsProperty(description = "this is withNodeAttributeExpression")
+        @AttributeExpression(modelableEntityName = "sample-node", attributeName = "response-data")
+        var withNodeAttributeExpression: String,
+
+        @BluePrintsProperty(description = "this is withNodeAttributeExpressionSubAttribute")
+        @AttributeExpression(modelableEntityName = "sample-node", attributeName = "response-data",
+                subAttributeName = ".\$field1")
+        var withNodeAttributeExpressionSubAttribute: String,
+
+        @BluePrintsProperty(description = "this is withAttributeExpressionSubAttribute")
+        @AttributeExpression(attributeName = "response-data", subAttributeName = ".\$field1")
+        var withAttributeExpressionSubAttribute: String,
+
+        @BluePrintsProperty(description = "this is withAttributeExpression")
+        @AttributeExpression(attributeName = "response-data")
+        var withAttributeExpression: String,
+
+        @BluePrintsProperty(description = "this is withAArtifactExpression")
+        @ArtifactExpression(modelableEntityName = "test-node", artifactName = "content-template")
+        var withAArtifactExpression: String,
+
+        @BluePrintsProperty(description = "this status")
+        val status: String = "success"
+)
\ No newline at end of file
index ba2f070..ec8f24d 100644 (file)
@@ -218,7 +218,11 @@ class BluePrintDSLTest {
 
         val testNodeTemplateInstance = BluePrintTypes.nodeTemplateComponentTestExecutor(id = "test-node-template",
                 description = "") {
-            operation("") {
+            definedProperties {
+                prop1("i am property1")
+                prop2("i am property2")
+            }
+            definedOperation("") {
                 implementation(360)
                 inputs {
                     request("i am request")
@@ -235,16 +239,26 @@ class BluePrintDSLTest {
 
 fun BluePrintTypes.nodeTemplateComponentTestExecutor(id: String,
                                                      description: String,
-                                                     block: TestNodeTemplateImplBuilder.() -> Unit)
+                                                     block: TestNodeTemplateOperationImplBuilder.() -> Unit)
         : NodeTemplate {
-    return TestNodeTemplateImplBuilder(id, description).apply(block).build()
+    return TestNodeTemplateOperationImplBuilder(id, description).apply(block).build()
 }
 
-class TestNodeTemplateImplBuilder(id: String, description: String) :
-        AbstractNodeTemplateImplBuilder<TestInput, TestOutput>(id, "component-test-executor",
+class TestNodeTemplateOperationImplBuilder(id: String, description: String) :
+        AbstractNodeTemplateOperationImplBuilder<TestProperty, TestInput, TestOutput>(id, "component-test-executor",
                 "ComponentTestExecutor",
                 description)
 
+class TestProperty : PropertiesAssignmentBuilder() {
+    fun prop1(prop1: String) {
+        property("prop1", prop1.asJsonPrimitive())
+    }
+
+    fun prop2(prop2: String) {
+        property("prop2", prop2.asJsonPrimitive())
+    }
+}
+
 class TestInput : PropertiesAssignmentBuilder() {
     fun request(request: String) {
         property("request", request.asJsonPrimitive())
index 9780bbd..b3436a9 100644 (file)
@@ -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 {
index a2f1e23..c222de9 100644 (file)
@@ -58,6 +58,12 @@ open class ResourceAssignment {
     @JsonProperty("dictionary-source")
     var dictionarySource: String? = null
 
+    /** Modified Source definition,  Capability Source will use for script reference changes,
+     * Rest Source will use for extra headers etc **/
+    @JsonProperty("dictionary-source-definition")
+    var dictionarySourceDefinition: NodeTemplate? = null
+
+    /** Duplicate field : Shall be used directly from Dictionary Source definition dependencies. **/
     @JsonProperty("dependencies")
     var dependencies: MutableList<String>? = null
 
index dbd5b7d..60fe6a7 100644 (file)
 package org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils
 
 import org.apache.commons.collections.CollectionUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.asListOfString
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.TopologicalSortingUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.slf4j.LoggerFactory
-import java.util.ArrayList
+import java.util.*
+
 /**
  * BulkResourceSequencingUtils.
  *
  * @author Brinda Santh
  */
 object BulkResourceSequencingUtils {
-    private val log= LoggerFactory.getLogger(BulkResourceSequencingUtils::class.java)
+    private val log = LoggerFactory.getLogger(BulkResourceSequencingUtils::class.java)
 
     @JvmStatic
     fun process(resourceAssignments: MutableList<ResourceAssignment>): List<List<ResourceAssignment>> {
@@ -46,7 +48,13 @@ object BulkResourceSequencingUtils {
         // Preepare Sorting Map
         val topologySorting = TopologicalSortingUtils<ResourceAssignment>()
         resourceAssignmentMap.forEach { _, resourceAssignment ->
-            if (CollectionUtils.isNotEmpty(resourceAssignment.dependencies)) {
+            // Get the dependencies from the assignment sources, if not get from the Resource Assignment dependencies
+            if (resourceAssignment.dictionarySourceDefinition != null) {
+                val dependencies = resourceAssignment.dictionarySourceDefinition?.properties?.get("key-dependencies")?.asListOfString()
+                dependencies?.forEach { dependency ->
+                    topologySorting.add(resourceAssignmentMap[dependency]!!, resourceAssignment)
+                }
+            } else if (CollectionUtils.isNotEmpty(resourceAssignment.dependencies)) {
                 for (dependency in resourceAssignment.dependencies!!) {
                     topologySorting.add(resourceAssignmentMap[dependency]!!, resourceAssignment)
                 }
index d4753e1..a0f8ca9 100644 (file)
@@ -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())
         }
 
index 1f872c2..d09479b 100644 (file)
@@ -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")
index f2f4ff1..2e9dcb2 100644 (file)
     <name>Controller Blueprints Parent</name>
     <packaging>pom</packaging>
     <properties>
-        <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
-        <grpc.version>1.18.0</grpc.version>
-        <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version>
         <eelf.version>1.0.0</eelf.version>
         <guava.version>27.0.1-jre</guava.version>
         <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
         <h2database.version>1.4.197</h2database.version>
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
         <powermock.version>1.7.4</powermock.version>
-        <mockk.version>1.9</mockk.version>
         <jinja.version>2.5.1</jinja.version>
         <velocity.version>1.7</velocity.version>
     </properties>
                 <artifactId>commons-io</artifactId>
                 <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>
             <groupId>commons-io</groupId>
             <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>