diff options
206 files changed, 6794 insertions, 2853 deletions
diff --git a/cds-ui/client/angular.json b/cds-ui/client/angular.json index c5800f050..2bf255ddf 100644 --- a/cds-ui/client/angular.json +++ b/cds-ui/client/angular.json @@ -31,7 +31,10 @@ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "./node_modules/material-design-icons/iconfont/material-icons.css", "./node_modules/font-awesome/css/font-awesome.css", - "./node_modules/bootstrap/dist/css/bootstrap.min.css" + "./node_modules/bootstrap/dist/css/bootstrap.min.css", + "./node_modules/jointjs/css/layout.css", + "./node_modules/jointjs/css/themes/material.css", + "./node_modules/jointjs/css/themes/default.css" ], "scripts": [ "./node_modules/ace-builds/src-min/ace.js", @@ -43,7 +46,11 @@ "./node_modules/ace-builds/src-min/mode-kotlin.js", "./node_modules/ace-builds/src-min/mode-text.js", "./node_modules/ace-builds/src-min/mode-velocity.js", - "./node_modules/ace-builds/src-min/mode-yaml.js" + "./node_modules/ace-builds/src-min/mode-yaml.js", + "./node_modules/jquery/dist/jquery.js", + "./node_modules/lodash/index.js", + "./node_modules/backbone/backbone.js", + "./node_modules/jointjs/dist/joint.js" ] }, "configurations": { diff --git a/cds-ui/client/package.json b/cds-ui/client/package.json index 2e19d29fe..4da70110e 100644 --- a/cds-ui/client/package.json +++ b/cds-ui/client/package.json @@ -29,14 +29,18 @@ "@ngrx/store-devtools": "^6.1.2", "@types/d3": "^5.7.0", "ang-jsoneditor": "1.6.1", + "backbone": "^1.4.0", + "bootstrap": "^4.3.1", "core-js": "^2.5.4", "d3": "^5.9.1", - "bootstrap": "^4.3.1", "file-saver": "^2.0.1", "font-awesome": "^4.7.0", "hammerjs": "^2.0.8", + "jointjs": "^3.0.4", + "jquery": "^3.1.1", "jsoneditor": "^5.31.1", "jszip": "^3.2.0", + "lodash": "^3.10.1", "material-design-icons": "^3.0.1", "ng2-ace-editor": "^0.3.9", "rxjs": "6.3.3", @@ -49,9 +53,13 @@ "@angular/cli": "7.1.0", "@angular/compiler-cli": "7.1.0", "@angular/language-service": "7.1.0", - "@types/node": "8.9.4", + "@types/backbone": "^1.4.1", "@types/jasmine": "2.8.8", "@types/jasminewd2": "2.0.3", + "@types/jointjs": "^2.0.0", + "@types/jquery": "^3.3.31", + "@types/lodash": "^3.10.1", + "@types/node": "^8.10.54", "codelyzer": "4.5.0", "jasmine-core": "2.99.1", "jasmine-spec-reporter": "4.2.1", diff --git a/cds-ui/client/src/app/app-routing.module.ts b/cds-ui/client/src/app/app-routing.module.ts index 01ecfe48b..998194274 100644 --- a/cds-ui/client/src/app/app-routing.module.ts +++ b/cds-ui/client/src/app/app-routing.module.ts @@ -42,6 +42,10 @@ const routes: Routes = [ { path: 'controller-catalog', loadChildren: './feature-modules/controller-catalog/controller-catalog.module#ControllerCatalogModule' + }, + { + path: 'blueprint-designer', + loadChildren: './feature-modules/blueprint-designer/blueprint-designer.module#BlueprintDesignerModule' } ] } diff --git a/cds-ui/client/src/app/app.module.ts b/cds-ui/client/src/app/app.module.ts index e4cc4a15d..998a80077 100644 --- a/cds-ui/client/src/app/app.module.ts +++ b/cds-ui/client/src/app/app.module.ts @@ -33,6 +33,7 @@ import { SharedModule } from './common/shared/shared.module'; import { CoreModule } from './common/core/core.module'; import { AppMaterialModule } from './common/modules/app-material.module'; import { ResourceDefinitionModule } from './feature-modules/resource-definition/resource-definition.module'; +import { BlueprintDesignerModule } from './feature-modules/blueprint-designer/blueprint-designer.module'; @NgModule({ declarations: [ @@ -48,7 +49,8 @@ import { ResourceDefinitionModule } from './feature-modules/resource-definition/ AppMaterialModule, SharedModule, CoreModule, - ResourceDefinitionModule + ResourceDefinitionModule, + BlueprintDesignerModule ], providers: [], bootstrap: [AppComponent] diff --git a/cds-ui/client/src/app/common/shared/components/home/home.component.html b/cds-ui/client/src/app/common/shared/components/home/home.component.html index beff353ef..2f1ec45ec 100644 --- a/cds-ui/client/src/app/common/shared/components/home/home.component.html +++ b/cds-ui/client/src/app/common/shared/components/home/home.component.html @@ -53,6 +53,7 @@ limitations under the License. </nav> --> <a mat-list-item [routerLink]="['/resource-definition']">Resource Definition</a> <a mat-list-item [routerLink]="['/controller-catalog']">Controller Catalog</a> + <a mat-list-item [routerLink]="['/blueprint-designer']">Blueprint Designer</a> </mat-nav-list> </mat-sidenav> diff --git a/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer-routing.module.ts b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer-routing.module.ts new file mode 100644 index 000000000..6b0749603 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer-routing.module.ts @@ -0,0 +1,38 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +*/ + +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { BlueprintDesignerComponent } from './blueprint-designer.component'; + + +const routes: Routes = [ + { + path: '', + component: BlueprintDesignerComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class BlueprintDesignerRoutingModule { } diff --git a/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.html b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.html new file mode 100644 index 000000000..11a5d72d3 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.html @@ -0,0 +1,21 @@ +<!-- ============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +--> + +<div id="paper" style="height: 100%; width: 100%"></div> diff --git a/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.scss b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.scss new file mode 100644 index 000000000..93f5c9dea --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.scss @@ -0,0 +1,20 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +*/
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.spec.ts b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.spec.ts new file mode 100644 index 000000000..1972e75b7 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.spec.ts @@ -0,0 +1,46 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +*/ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlueprintDesignerComponent } from './blueprint-designer.component'; + +describe('BlueprintDesignerComponent', () => { + let component: BlueprintDesignerComponent; + let fixture: ComponentFixture<BlueprintDesignerComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BlueprintDesignerComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BlueprintDesignerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.ts b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.ts new file mode 100644 index 000000000..ac9637722 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.component.ts @@ -0,0 +1,71 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +*/ + +import { Component, OnInit } from '@angular/core'; +import * as $ from 'jquery'; +import * as _ from 'lodash'; +import * as joint from '../../../../node_modules/jointjs/dist/joint.js'; + +@Component({ + selector: 'app-blueprint-designer', + templateUrl: './blueprint-designer.component.html', + styleUrls: ['./blueprint-designer.component.scss'] +}) +export class BlueprintDesignerComponent implements OnInit { + + public graph: any; + public paper: any; + + constructor() { } + + ngOnInit() { + // this.createGraph(); + } + + createGraph() { + this.graph = new joint.dia.Graph, + this.paper = new joint.dia.Paper({ + el: $('#paper'), + model: this.graph, + height: 700, + width: 1000, + gridSize: 2, + drawGrid: true + }); + + this.paper = new joint.dia.Paper({ + el: document.getElementById('paper'), + width: 1000, + height: 1000, + model: this.graph, + gridSize: 2, + drawGrid: true + }); + + this.paper.setGrid({ + name: 'dot', + args: + { color: 'black', thickness: 2, scaleFactor: 8 } + + }).drawGrid(); + } + +} diff --git a/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.module.ts b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.module.ts new file mode 100644 index 000000000..f338f790d --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint-designer/blueprint-designer.module.ts @@ -0,0 +1,34 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { BlueprintDesignerComponent } from './blueprint-designer.component'; +import { BlueprintDesignerRoutingModule } from './blueprint-designer-routing.module' + +@NgModule({ + declarations: [BlueprintDesignerComponent], + imports: [ + CommonModule, + BlueprintDesignerRoutingModule + ] +}) +export class BlueprintDesignerModule { } diff --git a/cds-ui/server/src/clients/blueprint-management-service-grpc-client.ts b/cds-ui/server/src/clients/blueprint-management-service-grpc-client.ts index b66b2a771..8975f4501 100644 --- a/cds-ui/server/src/clients/blueprint-management-service-grpc-client.ts +++ b/cds-ui/server/src/clients/blueprint-management-service-grpc-client.ts @@ -17,7 +17,7 @@ import * as fs from 'fs'; import * as uuidv1 from 'uuid/v1'; const grpc = require('grpc'); import * as protoLoader from '@grpc/proto-loader'; -import {processorApiConfig} from '../config/app-config'; +import { processorApiConfig } from '../config/app-config'; const PROTO_PATH = processorApiConfig.grpc.bluePrintManagement.protoPath; @@ -44,7 +44,7 @@ metadata.add('Authorization', processorApiConfig.grpc.authToken); class BluePrintManagementServiceGrpcClient { - async uploadBlueprint(filePath: string): Promise<any> { + async uploadBlueprint(filePath: string, actionName: string): Promise<any> { let input = { commonHeader: { @@ -55,6 +55,11 @@ class BluePrintManagementServiceGrpcClient { }, fileChunk: { chunk: fs.readFileSync(filePath) + }, + actionIdentifiers: { + mode: "sync", + blueprintName: "cds.zip", + actionName: actionName } } @@ -80,6 +85,34 @@ class BluePrintManagementServiceGrpcClient { }); } + + async downloadBlueprint(blueprintName: string,blueprintVersion: string): Promise<any> { + + let input = { + commonHeader: { + timestamp: new Date(), + originatorId: "cds-ui", + requestId: uuidv1(), + subRequestId: "1234-56", + }, + actionIdentifiers: { + mode: "sync", + blueprintName: blueprintName, + blueprintVersion: blueprintVersion + } + } + + return new Promise<any>((resolve, reject) => { + stub.downloadBlueprint(input, metadata, (err: any, output: any) => { + if (err) { + reject(err); + return; + } + resolve(output); + }); + }); + + } } export const bluePrintManagementServiceGrpcClient = new BluePrintManagementServiceGrpcClient(); diff --git a/cds-ui/server/src/config/app-config.ts b/cds-ui/server/src/config/app-config.ts index a2cebe59d..9b253b8fc 100644 --- a/cds-ui/server/src/config/app-config.ts +++ b/cds-ui/server/src/config/app-config.ts @@ -15,9 +15,9 @@ */ export const appConfig = Object.freeze({ action: Object.freeze({ - deployBlueprint: Object.freeze({ + // deployBlueprint: Object.freeze({ grpcEnabled: process.env.APP_ACTION_DEPLOY_BLUEPRINT_GRPC_ENABLED || true - }) + // }) }) }); diff --git a/cds-ui/server/src/controllers/blueprint-rest.controller.ts b/cds-ui/server/src/controllers/blueprint-rest.controller.ts index 789589837..1eef6fbcb 100644 --- a/cds-ui/server/src/controllers/blueprint-rest.controller.ts +++ b/cds-ui/server/src/controllers/blueprint-rest.controller.ts @@ -98,15 +98,26 @@ export class BlueprintRestController { ): Promise<Response> { return new Promise((resolve, reject) => { this.getFileFromMultiPartForm(request).then(file => { - this.uploadFileToBlueprintController(file, "/blueprint-model/", response).then(resp => { - resolve(resp); - }, err => { - reject(err); - }); + // if (appConfig.action.deployBlueprint.grpcEnabled) + if (appConfig.action.grpcEnabled) + return this.uploadFileToBlueprintProcessorGrpc(file, "DRAFT", response); + else + return this.uploadFileToBlueprintController(file, "/blueprint-model/", response); }, err => { reject(err); }); }); + // return new Promise((resolve, reject) => { + // this.getFileFromMultiPartForm(request).then(file => { + // this.uploadFileToBlueprintController(file, "/blueprint-model/", response).then(resp => { + // resolve(resp); + // }, err => { + // reject(err); + // }); + // }, err => { + // reject(err); + // }); + // }); } @post('/controllerblueprint/publish') @@ -127,15 +138,26 @@ export class BlueprintRestController { ): Promise<Response> { return new Promise((resolve, reject) => { this.getFileFromMultiPartForm(request).then(file => { - this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response).then(resp => { - resolve(resp); - }, err => { - reject(err); - }); + // if (appConfig.action.deployBlueprint.grpcEnabled) + if (appConfig.action.grpcEnabled) + return this.uploadFileToBlueprintProcessorGrpc(file, "PUBLISH", response); + else + return this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response); }, err => { reject(err); }); }); + // return new Promise((resolve, reject) => { + // this.getFileFromMultiPartForm(request).then(file => { + // this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response).then(resp => { + // resolve(resp); + // }, err => { + // reject(err); + // }); + // }, err => { + // reject(err); + // }); + // }); } @post('/controllerblueprint/enrich-blueprint') @@ -156,13 +178,17 @@ export class BlueprintRestController { ): Promise<Response> { return new Promise((resolve, reject) => { this.getFileFromMultiPartForm(request).then(file => { - this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response).then(resp => { - resolve(resp); - }, err => { - reject(err); - }); - }, err => { - reject(err); + if (appConfig.action.grpcEnabled) + return this.uploadFileToBlueprintProcessorGrpc(file, "ENRICH", response); + else + return this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response) + // this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response).then(resp => { + // resolve(resp); + // }, err => { + // reject(err); + // }); + // }, err => { + // reject(err); }); }); } @@ -173,9 +199,14 @@ export class BlueprintRestController { @param.path.string('version') version: string, @inject(RestBindings.Http.RESPONSE) response: Response, ): Promise<Response> { - return this.downloadFileFromBlueprintController("/blueprint-model/download/by-name/" + name + "/version/" + version, response); + + if (appConfig.action.grpcEnabled) + return this.downloadFileFromBlueprintProcessorGrpc(name, version, response); + else + return this.downloadFileFromBlueprintController("/blueprint-model/download/by-name/" + name + "/version/" + version, response); } + async getFileFromMultiPartForm(request: Request): Promise<multiparty.File> { return new Promise((resolve, reject) => { let form = new multiparty.Form(); @@ -209,8 +240,9 @@ export class BlueprintRestController { ): Promise<Response> { return new Promise((resolve, reject) => { this.getFileFromMultiPartForm(request).then(file => { - if (appConfig.action.deployBlueprint.grpcEnabled) - return this.uploadFileToBlueprintProcessorGrpc(file, response); + // if (appConfig.action.deployBlueprint.grpcEnabled) + if (appConfig.action.grpcEnabled) + return this.uploadFileToBlueprintProcessorGrpc(file, "PUBLISH", response); else return this.uploadFileToBlueprintProcessor(file, "/execution-service/upload/", response); }, err => { @@ -289,9 +321,9 @@ export class BlueprintRestController { }) } - async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, response: Response): Promise<Response> { + async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, actionName: string, response: Response): Promise<Response> { return new Promise<Response>((resolve, reject) => { - bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path).then(output => { + bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path, actionName).then(output => { response.send(output.status.message); resolve(response); }, err => { @@ -300,4 +332,16 @@ export class BlueprintRestController { }); }); } + async downloadFileFromBlueprintProcessorGrpc(blueprintName: string, blueprintVersion: string, response: Response): Promise<Response> { + return new Promise<Response>((resolve, reject) => { + bluePrintManagementServiceGrpcClient.downloadBlueprint(blueprintName, blueprintVersion) + .then(output => { + response.send(output.status.message); + resolve(response); + }, err => { + response.status(500).send(err); + resolve(response); + }); + }); + } }
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json index b3d719faa..71e5fa63d 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json @@ -773,4 +773,4 @@ "derived_from" : "tosca.datatypes.Dynamic" } } -}
\ No newline at end of file +} diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json index f7da40904..7172e3a05 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json @@ -63,7 +63,7 @@ "properties" : { "type" : "JSON", "verb" : "PUT", - "url-path" : "/restconf/config/GENERIC-RESOURCE-API:services/service/$vnf-id/service-data/vnfs/vnf/$service-instance-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", + "url-path" : "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", "path" : "", "payload" : "{\n\"GENERIC-RESOURCE-API:param\": [\n{\n\"GENERIC-RESOURCE-API:name\": \"vdns_vf_module_id\",\n\"GENERIC-RESOURCE-API:value\": \"$vf-module-id\"\n}\n]\n}", "input-key-mapping" : { @@ -1263,7 +1263,7 @@ "properties" : { "verb" : "GET", "type" : "JSON", - "url-path" : "/restconf/config/GENERIC-RESOURCE-API:services/service/$vnf-id/service-data/vnfs/vnf/$service-instance-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", + "url-path" : "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", "path" : "/param/0/value", "input-key-mapping" : { "service-instance-id" : "service-instance-id", @@ -1439,11 +1439,11 @@ } } }, - "vf-module-name" : { - "tags" : "vf-module-name", - "name" : "vf-module-name", + "vf_module_name" : { + "tags" : "vf_module_name", + "name" : "vf_module_name", "property" : { - "description" : "vf-module-name", + "description" : "vf_module_name", "type" : "string" }, "updated-by" : "Singal, Kapil <ks220y@att.com>", diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py b/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py index 34fd1404d..388c63ffb 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py @@ -40,11 +40,11 @@ class ConfigDeploy(NetconfComponentFunction): #if not response.isSuccess():
# og.error(response.errorMessage)
nc.discard_change()
- nc.edit_config(message_content=payloadInterface, edit_default_peration="none")
- nc.edit_config(message_content=payloadHostname, edit_default_peration="none")
- nc.validate()
+ nc.edit_config(message_content=payloadInterface, edit_default_peration="merge")
+ nc.edit_config(message_content=payloadHostname, edit_default_peration="merge")
+ #nc.validate()
nc.commit()
- #nc.commit(confirmed = True, confirm_timeout=15)
+ nc.get_config() #nc.commit(confirmed = True, confirm_timeout=15)
nc.unlock()
nc.disconnect()
diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-template.vtl index 9e73a318e..10e448466 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-template.vtl @@ -1,9 +1,9 @@ - { - "vdns-instance": [ - { - "ip-addr": "$vdns_int_private_ip_0", - "oam-ip-addr": "$vdns_onap_private_ip_0", - "enabled": false - } - ] -}
\ No newline at end of file +<vlb-business-vnf-onap-plugin xmlns="urn:opendaylight:params:xml:ns:yang:vlb-business-vnf-onap-plugin"> +<vdns-instances> +<vdns-instance> +<ip-addr>$vdns_int_private_ip_0</ip-addr> +<oam-ip-addr>$vdns_onap_private_ip_0</oam-ip-addr> +<enabled>false</enabled> +</vdns-instance> +</vdns-instances> +</vlb-business-vnf-onap-plugin> diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-template.vtl index 7ec446f30..d33625739 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-template.vtl @@ -1,9 +1,9 @@ -{ - "vdns-instance": [ - { - "ip-addr": "$vdns_int_private_ip_0", - "oam-ip-addr": "$vdns_onap_private_ip_0", - "enabled": true - } - ] -}
\ No newline at end of file +<vlb-business-vnf-onap-plugin xmlns="urn:opendaylight:params:xml:ns:yang:vlb-business-vnf-onap-plugin"> +<vdns-instances> +<vdns-instance> +<ip-addr>$vdns_int_private_ip_0</ip-addr> +<oam-ip-addr>$vdns_onap_private_ip_0</oam-ip-addr> +<enabled>true</enabled> +</vdns-instance> +</vdns-instances> +</vlb-business-vnf-onap-plugin> diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt index 9552b6136..7bda62810 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt +++ b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt @@ -19,6 +19,7 @@ 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.ssh.sshClientService +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException 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 diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json index 4945da889..a47c13c47 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json +++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json @@ -14,6 +14,14 @@ "entry_schema": { "type": "string" } + }, + "status": { + "required": true, + "type": "string" + }, + "response-data": { + "required": false, + "type": "json" } }, "capabilities" : { diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json index 192106e95..fe0f59243 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json +++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json @@ -83,6 +83,14 @@ "execute-command-logs" ] } + }, + "execute-command-status": { + "type": "string", + "value": { "get_attribute": ["execute-remote-python", "status"]} + }, + "execute-command-payload": { + "type": "json", + "value": { "get_attribute": ["execute-remote-python", "response-data"]} } } }, diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/python/SamplePython.py b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/python/SamplePython.py index 5e20e2291..fae5855cf 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/python/SamplePython.py +++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/python/SamplePython.py @@ -2,4 +2,14 @@ import sys -print(sys.argv[1])
\ No newline at end of file +#Optional : import this utility class if returning payload +from cds_utils.payload_coder import send_response_data_payload + +# Do your work... using try .. except to handle errors and return False if error +print(sys.argv[1]) + +# Optional : return a JSON payload to the be published under the response-data output attribute +send_response_data_payload({"étudiant": ["Mélanie", "Joséphine"]}) + +# Always return a boolean indicating success or not.. +sys.exit(True)
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/TOSCA-Metadata/TOSCA.meta index 5ca8aa031..2c3a91f28 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/TOSCA-Metadata/TOSCA.meta +++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/TOSCA-Metadata/TOSCA.meta @@ -2,4 +2,5 @@ TOSCA-Meta-File-Version: 1.0.0 CSAR-Version: 1.0 Created-By: Brinda Santh <brindasanth@in.ibm.com> Entry-Definitions: Definitions/remote_scripts.json -Template-Tags: Brinda Santh, remote_scripts
\ No newline at end of file +Template-Tags: Brinda Santh, remote_scripts +Content-Type: application/vnd.oasis.bpmn diff --git a/components/model-catalog/definition-type/starter-type/node_type/component-remote-python-executor.json b/components/model-catalog/definition-type/starter-type/node_type/component-remote-python-executor.json index 1c8011382..acaea4e7b 100644 --- a/components/model-catalog/definition-type/starter-type/node_type/component-remote-python-executor.json +++ b/components/model-catalog/definition-type/starter-type/node_type/component-remote-python-executor.json @@ -2,6 +2,10 @@ "description": "This is Remote Python Execution Component.", "version": "1.0.0", "attributes": { + "status": { + "required": true, + "type": "string" + }, "prepare-environment-logs": { "required": false, "type": "string" diff --git a/components/model-catalog/proto-definition/proto/CommandExecutor.proto b/components/model-catalog/proto-definition/proto/CommandExecutor.proto index fd2d4f305..ac6921965 100644 --- a/components/model-catalog/proto-definition/proto/CommandExecutor.proto +++ b/components/model-catalog/proto-definition/proto/CommandExecutor.proto @@ -40,6 +40,7 @@ message ExecutionOutput { repeated string response = 2; ResponseStatus status = 3; google.protobuf.Timestamp timestamp = 4; + string payload = 5; } enum ResponseStatus { @@ -55,6 +56,7 @@ message Packages { enum PackageType { pip = 0; ansible_galaxy = 1; + utilities = 2; } service CommandExecutorService { diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/active-streams.json b/components/model-catalog/resource-dictionary/starter-dictionary/active-streams.json new file mode 100644 index 000000000..d136fbf8d --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/active-streams.json @@ -0,0 +1,18 @@ +{ + "tags": "active-streams", + "name": "active-streams", + "property": { + "description": "active-streams", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/cloud_env.json b/components/model-catalog/resource-dictionary/starter-dictionary/cloud_env.json index 1877c1253..28cac3bb5 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/cloud_env.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/cloud_env.json @@ -1,37 +1,38 @@ { - "tags": "cloud_env", - "name": "cloud_env", - "property": { - "description": "cloud_env", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/cloud_env", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "cloud_env": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "cloud_env", + "name": "cloud_env", + "property": { + "description": "cloud_env", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/cloud_env", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "cloud_env": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/create-md-sal-vnf-param.json b/components/model-catalog/resource-dictionary/starter-dictionary/create-md-sal-vnf-param.json new file mode 100644 index 000000000..e19e67c05 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/create-md-sal-vnf-param.json @@ -0,0 +1,49 @@ +{ + "tags": "create-md-sal-vnf-param", + "name": "create-md-sal-vnf-param", + "property": { + "description": "create-md-sal-vnf-param", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "sdnc": { + "type": "source-rest", + "properties": { + "type": "JSON", + "verb": "PUT", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", + "path": "", + "payload": "{\n\"GENERIC-RESOURCE-API:param\": [\n{\n\"GENERIC-RESOURCE-API:name\": \"vdns_vf_module_id\",\n\"GENERIC-RESOURCE-API:value\": \"$vf-module-id\"\n}\n]\n}", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id", + "vf-module-id": "vf-module-id" + }, + "output-key-mapping": {}, + "key-dependencies": [ + "vf-module-id", + "service-instance-id", + "vnf-id" + ] + } + }, + "aai-data": { + "type": "source-rest", + "properties": { + "verb": "PATCH", + "type": "JSON", + "url-path": "/aai/v14/network/generic-vnfs/generic-vnf/$vnf-id/nm-profile-name", + "payload": "{\"nm-profile-name\":\"$vf-module-id\"}", + "path": "", + "input-key-mapping": { + "vnf-id": "vnf-id" + }, + "output-key-mapping": {}, + "key-dependencies": [ + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_ip.json b/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_ip.json index c0d42dfd0..9339cd263 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_ip.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_ip.json @@ -1,37 +1,38 @@ { - "tags": "dcae_collector_ip", - "name": "dcae_collector_ip", - "property": { - "description": "dcae_collector_ip", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/dcae_collector_ip", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "dcae_collector_ip": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "dcae_collector_ip", + "name": "dcae_collector_ip", + "property": { + "description": "dcae_collector_ip", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/dcae_collector_ip", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "dcae_collector_ip": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_port.json b/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_port.json index 1191d800b..85b561e41 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_port.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/dcae_collector_port.json @@ -1,37 +1,38 @@ { - "tags": "dcae_collector_port", - "name": "dcae_collector_port", - "property": { - "description": "dcae_collector_port", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/dcae_collector_port", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "dcae_collector_port": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "dcae_collector_port", + "name": "dcae_collector_port", + "property": { + "description": "dcae_collector_port", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/dcae_collector_port", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "dcae_collector_port": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/demo_artifacts_version.json b/components/model-catalog/resource-dictionary/starter-dictionary/demo_artifacts_version.json index 3884e1e53..63f8a3563 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/demo_artifacts_version.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/demo_artifacts_version.json @@ -1,37 +1,38 @@ { - "tags": "demo_artifacts_version", - "name": "demo_artifacts_version", - "property": { - "description": "demo_artifacts_version", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/demo_artifacts_version", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "demo_artifacts_version": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "demo_artifacts_version", + "name": "demo_artifacts_version", + "property": { + "description": "demo_artifacts_version", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/demo_artifacts_version", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "demo_artifacts_version": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/flavor_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/flavor_name.json new file mode 100644 index 000000000..ad7f3a706 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/flavor_name.json @@ -0,0 +1,38 @@ +{ + "tags": "flavor_name", + "name": "flavor_name", + "property": { + "description": "flavor_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/flavor_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "flavor_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/gre_ipaddr.json b/components/model-catalog/resource-dictionary/starter-dictionary/gre_ipaddr.json index 92f7abe6e..a917350cf 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/gre_ipaddr.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/gre_ipaddr.json @@ -1,37 +1,38 @@ { - "tags": "gre_ipaddr", - "name": "gre_ipaddr", - "property": { - "description": "gre_ipaddr", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/gre_ipaddr", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "gre_ipaddr": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "gre_ipaddr", + "name": "gre_ipaddr", + "property": { + "description": "gre_ipaddr", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/gre_ipaddr", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "gre_ipaddr": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/image_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/image_name.json index f8816b15a..9891caa2f 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/image_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/image_name.json @@ -1,33 +1,38 @@ { - "name": "image_name", - "tags": "image_name", - "updated-by": "Singal, Kapil <ks220y@att.com>", - "property": { - "type": "string", - "description": "image_name" - }, - "sources": { - "input": { - "type": "source-input" - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/image_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "image_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "image_name", + "name": "image_name", + "property": { + "description": "image_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/image_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "image_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/install_script_version.json b/components/model-catalog/resource-dictionary/starter-dictionary/install_script_version.json index 39bbb1880..1f5f79eb1 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/install_script_version.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/install_script_version.json @@ -1,37 +1,38 @@ { - "tags": "install_script_version", - "name": "install_script_version", - "property": { - "description": "install_script_version", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/install_script_version", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "install_script_version": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "install_script_version", + "name": "install_script_version", + "property": { + "description": "install_script_version", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/install_script_version", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "install_script_version": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_net_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_net_id.json index acde1255f..2c2c18b66 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_net_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_net_id.json @@ -1,37 +1,38 @@ { - "tags": "int_pktgen_private_net_id", - "name": "int_pktgen_private_net_id", - "property": { - "description": "int_pktgen_private_net_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_pktgen_private_net_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "int_pktgen_private_net_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "int_pktgen_private_net_id", + "name": "int_pktgen_private_net_id", + "property": { + "description": "int_pktgen_private_net_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_pktgen_private_net_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "int_pktgen_private_net_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_subnet_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_subnet_id.json index c30bef838..6f2203f53 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_subnet_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_pktgen_private_subnet_id.json @@ -1,37 +1,38 @@ { - "tags": "int_pktgen_private_subnet_id", - "name": "int_pktgen_private_subnet_id", - "property": { - "description": "int_pktgen_private_subnet_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_pktgen_private_subnet_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "int_pktgen_private_subnet_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "int_pktgen_private_subnet_id", + "name": "int_pktgen_private_subnet_id", + "property": { + "description": "int_pktgen_private_subnet_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_pktgen_private_subnet_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "int_pktgen_private_subnet_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_private1_net_cidr.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_private1_net_cidr.json new file mode 100644 index 000000000..f450143c5 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_private1_net_cidr.json @@ -0,0 +1,50 @@ +{ + "tags": "int_private1_net_cidr", + "name": "int_private1_net_cidr", + "property": { + "description": "int_private1_net_cidr", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private1_net_cidr", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "int_private1_net_cidr": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private1\"", + "input-key-mapping": {}, + "output-key-mapping": { + "int_private1_net_cidr": "prefix" + } + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_private1_subnet_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_private1_subnet_id.json new file mode 100644 index 000000000..938f51a7e --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_private1_subnet_id.json @@ -0,0 +1,15 @@ +{ + "tags": "int_private1_subnet_id", + "name": "int_private1_subnet_id", + "property": { + "description": "int_private1_subnet_id", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input", + "properties": {} + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_private2_net_cidr.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_private2_net_cidr.json new file mode 100644 index 000000000..e018614ea --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_private2_net_cidr.json @@ -0,0 +1,50 @@ +{ + "tags": "int_private2_net_cidr", + "name": "int_private2_net_cidr", + "property": { + "description": "int_private2_net_cidr", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private2\"", + "output-key-mapping": { + "int_private2_net_cidr": "prefix" + }, + + "input-key-mapping": {} + } + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private2_net_cidr", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "int_private2_net_cidr": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_private2_subnet_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_private2_subnet_id.json new file mode 100644 index 000000000..1ec9eb30a --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_private2_subnet_id.json @@ -0,0 +1,15 @@ +{ + "tags": "int_private2_subnet_id", + "name": "int_private2_subnet_id", + "property": { + "description": "int_private2_subnet_id", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input", + "properties": {} + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_private_net_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_private_net_id.json index 4aa07f3cb..f424da218 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/int_private_net_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_private_net_id.json @@ -1,37 +1,38 @@ { - "tags": "int_private_net_id", - "name": "int_private_net_id", - "property": { - "description": "int_private_net_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private_net_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "int_private_net_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "int_private_net_id", + "name": "int_private_net_id", + "property": { + "description": "int_private_net_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private_net_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "int_private_net_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/int_private_subnet_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/int_private_subnet_id.json index d9e02b546..be6f87701 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/int_private_subnet_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/int_private_subnet_id.json @@ -1,37 +1,38 @@ { - "tags": "int_private_subnet_id", - "name": "int_private_subnet_id", - "property": { - "description": "int_private_subnet_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private_subnet_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "int_private_subnet_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "int_private_subnet_id", + "name": "int_private_subnet_id", + "property": { + "description": "int_private_subnet_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/int_private_subnet_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "int_private_subnet_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/key_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/key_name.json index 2633f1d41..909cffb38 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/key_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/key_name.json @@ -1,33 +1,38 @@ { - "name": "key_name", - "tags": "key_name", - "updated-by": "Singal, Kapil <ks220y@att.com>", - "property": { - "type": "string", - "description": "key_name" - }, - "sources": { - "input": { - "type": "source-input" - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/key_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "key_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "key_name", + "name": "key_name", + "property": { + "description": "key_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/key_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "key_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/keypair.json b/components/model-catalog/resource-dictionary/starter-dictionary/keypair.json index 2b464a8d7..5a7fb2194 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/keypair.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/keypair.json @@ -1,37 +1,38 @@ { - "tags": "keypair", - "name": "keypair", - "property": { - "description": "keypair", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/keypair", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "keypair": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "keypair", + "name": "keypair", + "property": { + "description": "keypair", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/keypair", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "keypair": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/management-prefix-id.json b/components/model-catalog/resource-dictionary/starter-dictionary/management-prefix-id.json index 279ca92c9..0050bb60d 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/management-prefix-id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/management-prefix-id.json @@ -1,49 +1,50 @@ { - "tags": "management-prefix-id", - "name": "management-prefix-id", - "property": { - "description": "management-prefix-id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/management-prefix-id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "management-prefix-id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"management\"", - "input-key-mapping": {}, - "output-key-mapping": { - "management-prefix-id": "prefix_id" - } - } - } - } -} + "tags": "management-prefix-id", + "name": "management-prefix-id", + "property": { + "description": "management-prefix-id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/management-prefix-id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "management-prefix-id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"management\"", + "input-key-mapping": {}, + "output-key-mapping": { + "management-prefix-id": "prefix_id" + } + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/name_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/name_0.json index 433a3b724..59d8f9511 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/name_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/name_0.json @@ -1,15 +1,15 @@ { - "name" : "name_0", - "tags" : "name_0", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "name_0", - "type" : "string" - }, - "sources" : { - "input" : { - "type" : "source-input", - "properties" : { } - } - } + "tags": "name_0", + "name": "name_0", + "property": { + "description": "name_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input", + "properties": {} + } + } }
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/nb_api_version.json b/components/model-catalog/resource-dictionary/starter-dictionary/nb_api_version.json index 55784fec5..c089dea9c 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/nb_api_version.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/nb_api_version.json @@ -1,37 +1,38 @@ { - "tags": "nb_api_version", - "name": "nb_api_version", - "property": { - "description": "nb_api_version", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nb_api_version", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "nb_api_version": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "nb_api_version", + "name": "nb_api_version", + "property": { + "description": "nb_api_version", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nb_api_version", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "nb_api_version": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/nexus_artifact_repo.json b/components/model-catalog/resource-dictionary/starter-dictionary/nexus_artifact_repo.json index f1173e4a2..1cb2224b7 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/nexus_artifact_repo.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/nexus_artifact_repo.json @@ -1,37 +1,38 @@ { - "tags": "nexus_artifact_repo", - "name": "nexus_artifact_repo", - "property": { - "description": "nexus_artifact_repo", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nexus_artifact_repo", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "nexus_artifact_repo": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "nexus_artifact_repo", + "name": "nexus_artifact_repo", + "property": { + "description": "nexus_artifact_repo", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/nexus_artifact_repo", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "nexus_artifact_repo": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/nf-role.json b/components/model-catalog/resource-dictionary/starter-dictionary/nf-role.json index 90f5b4943..f666cf42d 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/nf-role.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/nf-role.json @@ -1,30 +1,31 @@ { - "name" : "nf-role", - "tags" : "nf-role", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vnf/nf-role", - "type" : "string" - }, - "sources" : { - "default": { - "type": "source-default", - "properties": { - } - }, - "processor-db" : { - "type" : "source-db", - "properties" : { - "type" : "SQL", - "query" : "select sdnctl.VF_MODEL.nf_role as vf_model_role from sdnctl.VF_MODEL where sdnctl.VF_MODEL.customization_uuid=:vnfmodelcustomizationuuid", - "input-key-mapping" : { - "vnfmodelcustomizationuuid" : "vnf-model-customization-uuid" - }, - "output-key-mapping" : { - "nf-role" : "vf_model_role" - }, - "key-dependencies" : [ "vnf-model-customization-uuid" ] - } - } - } -} + "tags": "nf-role", + "name": "nf-role", + "property": { + "description": "vnf/nf-role", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select sdnctl.VF_MODEL.nf_role as vf_model_role from sdnctl.VF_MODEL where sdnctl.VF_MODEL.customization_uuid=:vnfmodelcustomizationuuid", + "input-key-mapping": { + "vnfmodelcustomizationuuid": "vnf-model-customization-uuid" + }, + "output-key-mapping": { + "nf-role": "vf_model_role" + }, + "key-dependencies": [ + "vnf-model-customization-uuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/nfc-naming-code.json b/components/model-catalog/resource-dictionary/starter-dictionary/nfc-naming-code.json index 55d81776d..0a578c9cf 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/nfc-naming-code.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/nfc-naming-code.json @@ -1,35 +1,35 @@ { - "tags": "nfc-naming-code", - "name": "nfc-naming-code", - "property": { - "description": "nfc-naming-code", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select nfc_naming_code as nfc_naming_code from sdnctl.VFC_MODEL where customization_uuid=:vfccustomizationuuid", - "input-key-mapping": { - "vfccustomizationuuid": "vfccustomizationuuid" - }, - "output-key-mapping": { - "nfc-naming-code": "nfc_naming_code" - }, - "key-dependencies": [ - "vfccustomizationuuid" - ] - } - } - } -} + "tags": "nfc-naming-code", + "name": "nfc-naming-code", + "property": { + "description": "nfc-naming-code", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select nfc_naming_code as nfc_naming_code from sdnctl.VFC_MODEL where customization_uuid=:vfccustomizationuuid", + "input-key-mapping": { + "vfccustomizationuuid": "vfccustomizationuuid" + }, + "output-key-mapping": { + "nfc-naming-code": "nfc_naming_code" + }, + "key-dependencies": [ + "vfccustomizationuuid" + ], + "endpoint-selector": "dynamic-db-source" + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_cidr.json b/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_cidr.json index 83144eb41..9c9d677a7 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_cidr.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_cidr.json @@ -1,49 +1,50 @@ { - "tags": "onap_private_net_cidr", - "name": "onap_private_net_cidr", - "property": { - "description": "onap_private_net_cidr", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_cidr", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "onap_private_net_cidr": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"management\"", - "input-key-mapping": {}, - "output-key-mapping": { - "onap_private_net_cidr": "prefix" - } - } - } - } -} + "tags": "onap_private_net_cidr", + "name": "onap_private_net_cidr", + "property": { + "description": "onap_private_net_cidr", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"management\"", + "input-key-mapping": {}, + "output-key-mapping": { + "onap_private_net_cidr": "prefix" + } + } + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_cidr", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "onap_private_net_cidr": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_id.json index f2bcb9a11..8c98843e1 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_net_id.json @@ -1,38 +1,38 @@ { - "tags": "onap_private_net_id", - "name": "onap_private_net_id", - "property": { - "description": "onap_private_net_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "onap_private_net_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - - } + "tags": "onap_private_net_id", + "name": "onap_private_net_id", + "property": { + "description": "onap_private_net_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_net_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "onap_private_net_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_subnet_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_subnet_id.json index 034899342..e55b0bdef 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_subnet_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/onap_private_subnet_id.json @@ -1,37 +1,38 @@ { - "tags": "onap_private_subnet_id", - "name": "onap_private_subnet_id", - "property": { - "description": "onap_private_subnet_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_subnet_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "onap_private_subnet_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "onap_private_subnet_id", + "name": "onap_private_subnet_id", + "property": { + "description": "onap_private_subnet_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/onap_private_subnet_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "onap_private_subnet_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/pg_int.json b/components/model-catalog/resource-dictionary/starter-dictionary/pg_int.json index 2747b689d..f7ba07655 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/pg_int.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/pg_int.json @@ -1,37 +1,38 @@ { - "tags": "pg_int", - "name": "pg_int", - "property": { - "description": "pg_int", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pg_int", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "pg_int": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "pg_int", + "name": "pg_int", + "property": { + "description": "pg_int", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pg_int", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "pg_int": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_cidr.json b/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_cidr.json index dc86efa1a..0eaaf9b36 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_cidr.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_cidr.json @@ -1,50 +1,50 @@ - { - "tags": "pktgen_private_net_cidr", - "name": "pktgen_private_net_cidr", - "property": { - "description": "pktgen_private_net_cidr", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pktgen_private_net_cidr", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "pktgen_private_net_cidr": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - }, - - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private2\"", - "input-key-mapping": {}, - "output-key-mapping": { - "onap_private_net_cidr": "prefix" - } - } - } - } - } +{ + "tags": "pktgen_private_net_cidr", + "name": "pktgen_private_net_cidr", + "property": { + "description": "pktgen_private_net_cidr", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private2\"", + "output-key-mapping": { + "pktgen_private_net_cidr": "prefix" + }, + + "input-key-mapping": {} + } + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pktgen_private_net_cidr", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "pktgen_private_net_cidr": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_id.json index 9c8c61080..c72117ffe 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/pktgen_private_net_id.json @@ -1,37 +1,38 @@ - { - "tags": "pktgen_private_net_id", - "name": "pktgen_private_net_id", - "property": { - "description": "pktgen_private_net_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pktgen_private_net_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "pktgen_private_net_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - } +{ + "tags": "pktgen_private_net_id", + "name": "pktgen_private_net_id", + "property": { + "description": "pktgen_private_net_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pktgen_private_net_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "pktgen_private_net_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/private1-prefix-id.json b/components/model-catalog/resource-dictionary/starter-dictionary/private1-prefix-id.json index 53f43a8fa..b3b9412d6 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/private1-prefix-id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/private1-prefix-id.json @@ -1,49 +1,50 @@ { - "tags": "private1-prefix-id", - "name": "private1-prefix-id", - "property": { - "description": "private1-prefix-id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/private1-prefix-id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "private1-prefix-id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"private1\"", - "input-key-mapping": {}, - "output-key-mapping": { - "private1-prefix-id": "prefix_id" - } - } - } - } -} + "tags": "private1-prefix-id", + "name": "private1-prefix-id", + "property": { + "description": "private1-prefix-id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/private1-prefix-id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "private1-prefix-id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"private1\"", + "input-key-mapping": {}, + "output-key-mapping": { + "private1-prefix-id": "prefix_id" + } + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/private2-prefix-id.json b/components/model-catalog/resource-dictionary/starter-dictionary/private2-prefix-id.json index 8498dd372..02dade7c4 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/private2-prefix-id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/private2-prefix-id.json @@ -1,49 +1,50 @@ { - "tags": "private2-prefix-id", - "name": "private2-prefix-id", - "property": { - "description": "private2-prefix-id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/private2-prefix-id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "private2-prefix-id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"private2\"", - "input-key-mapping": {}, - "output-key-mapping": { - "private2-prefix-id": "prefix_id" - } - } - } - } -} + "tags": "private2-prefix-id", + "name": "private2-prefix-id", + "property": { + "description": "private2-prefix-id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/private2-prefix-id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "private2-prefix-id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix_id as prefix_id from sdnctl.IPAM_IP_POOL where description = \"private2\"", + "input-key-mapping": {}, + "output-key-mapping": { + "private2-prefix-id": "prefix_id" + } + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/pub_key.json b/components/model-catalog/resource-dictionary/starter-dictionary/pub_key.json index b7c1da775..cb25ed47c 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/pub_key.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/pub_key.json @@ -1,37 +1,38 @@ { - "tags": "pub_key", - "name": "pub_key", - "property": { - "description": "pub_key", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pub_key", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "pub_key": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "pub_key", + "name": "pub_key", + "property": { + "description": "pub_key", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/pub_key", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "pub_key": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/public_net_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/public_net_id.json index 34c37677b..66e7aeeec 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/public_net_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/public_net_id.json @@ -1,38 +1,38 @@ - { - "tags": "public_net_id", - "name": "public_net_id", - "property": { - "description": "public_net_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/public_net_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "public_net_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - - } +{ + "tags": "public_net_id", + "name": "public_net_id", + "property": { + "description": "public_net_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/public_net_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "public_net_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/put-active-streams.json b/components/model-catalog/resource-dictionary/starter-dictionary/put-active-streams.json new file mode 100644 index 000000000..56237d815 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/put-active-streams.json @@ -0,0 +1,40 @@ +{ + "name": "put-active-streams", + "tags": "put-active-streams", + "property": { + "description": "put-active-streams", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "PUT", + "type": "JSON", + "url-path": "$vpg_onap_private_ip_0:8183/restconf/config/stream-count:stream-count/streams", + "path": "/param/0/value", + "input-key-mapping": { + "vpg_onap_private_ip_0": "vpg_onap_private_ip_0", + "active-streams": "active-streams" + }, + "output-key-mapping": { + + }, + "key-dependencies": [ + "vpg_onap_private_ip_0", + "active-streams" + ], + "endpoint-selector": "vpkg-rest-api", + "payload": "{\"streams\": {\"active-streams\": $active-streams}}" + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/sec_group.json b/components/model-catalog/resource-dictionary/starter-dictionary/sec_group.json index 0dca85995..deb0a59b9 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/sec_group.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/sec_group.json @@ -1,38 +1,38 @@ - { - "tags": "sec_group", - "name": "sec_group", - "property": { - "description": "sec_group", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/sec_group", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "sec_group": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - - } +{ + "tags": "sec_group", + "name": "sec_group", + "property": { + "description": "sec_group", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/sec_group", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "sec_group": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/service-instance-id.json b/components/model-catalog/resource-dictionary/starter-dictionary/service-instance-id.json index 4b1f4f38f..533b8042a 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/service-instance-id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/service-instance-id.json @@ -1,45 +1,43 @@ { - "name" : "service-instance-id", - "tags" : "service-instance-id, tosca.datatypes.Root, data_type", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "To be provided", - "type" : "string" - }, - "sources" : { - "input" : { - "type" : "source-input", - "properties" : { } - }, - "any-db": { - "type": "source-db", - "properties": { - "query": "SELECT artifact_name FROM BLUEPRINT_MODEL where artifact_version=\"1.0.0\"", - "input-key-mapping": { - }, - "output-key-mapping": { - "service-instance-id": "artifact_name" - } - } - }, - "processor-db": { - "type": "source-db", - "properties": { - "query": "SELECT artifact_name FROM BLUEPRINT_MODEL where artifact_version=\"1.0.0\"", - "input-key-mapping": { - }, - "output-key-mapping": { - "service-instance-id": "artifact_name" - } - } - }, - "capability": { - "type": "source-capability", - "properties": { - "script-type": "jython", - "script-class-reference": "SampleRAProcessor", - "instance-dependencies": [] - } - } - } -} + "tags": "service-instance-id, tosca.datatypes.Root, data_type", + "name": "service-instance-id", + "property": { + "description": "To be provided", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input", + "properties": {} + }, + "any-db": { + "type": "source-db", + "properties": { + "query": "SELECT artifact_name FROM BLUEPRINT_RUNTIME where artifact_version=\"1.0.0\"", + "input-key-mapping": {}, + "output-key-mapping": { + "service-instance-id": "artifact_name" + } + } + }, + "processor-db": { + "type": "source-db", + "properties": { + "query": "SELECT artifact_name FROM BLUEPRINT_RUNTIME where artifact_version=\"1.0.0\"", + "input-key-mapping": {}, + "output-key-mapping": { + "service-instance-id": "artifact_name" + } + } + }, + "capability": { + "type": "source-capability", + "properties": { + "script-type": "jython", + "script-class-reference": "SampleRAProcessor", + "instance-dependencies": [] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_flavor_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_flavor_name.json index 445bc4732..31f55b32d 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_flavor_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_flavor_name.json @@ -1,39 +1,38 @@ - { - - "tags": "vdns_flavor_name", - "name": "vdns_flavor_name", - "property": { - "description": "vdns_flavor_name", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_flavor_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vdns_flavor_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - - } +{ + "tags": "vdns_flavor_name", + "name": "vdns_flavor_name", + "property": { + "description": "vdns_flavor_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_flavor_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vdns_flavor_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_image_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_image_name.json index d1d9d0604..7ba8f2706 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_image_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_image_name.json @@ -1,37 +1,38 @@ { - "tags": "vdns_image_name", - "name": "vdns_image_name", - "property": { - "description": "vdns_image_name", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_image_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vdns_image_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vdns_image_name", + "name": "vdns_image_name", + "property": { + "description": "vdns_image_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_image_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vdns_image_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_int_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_int_private_ip_0.json index 902cd27aa..6c3f7f473 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_int_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_int_private_ip_0.json @@ -1,37 +1,40 @@ { - "tags": "vdns_int_private_ip_0", - "name": "vdns_int_private_ip_0", - "property": { - "description": "vdns_int_private_ip_0", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_int_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vdns_int_private_ip_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vdns_int_private_ip_0", + "name": "vdns_int_private_ip_0", + "property": { + "description": "vdns_int_private_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vf-modules/vf-module/$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param/vdns_int_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id", + "vdns_vf_module_id": "vdns_vf_module_id" + }, + "output-key-mapping": { + "vdns_int_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id", + "vdns_vf_module_id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_name_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_name_0.json index efc741897..693d7f15f 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_name_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_name_0.json @@ -1,38 +1,38 @@ - { - "tags": "vdns_name_0", - "name": "vdns_name_0", - "property": { - "description": "vdns_name_0", - "type": "string" - }, - "updated-by": "Singal, Kapil <ks220y@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_name_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vdns_name_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - - } +{ + "tags": "vdns_name_0", + "name": "vdns_name_0", + "property": { + "description": "vdns_name_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_name_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vdns_name_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_onap_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_onap_private_ip_0.json index d6f1e37e7..96aa4e81a 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_onap_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_onap_private_ip_0.json @@ -1,37 +1,40 @@ { - "tags": "vdns_onap_private_ip_0", - "name": "vdns_onap_private_ip_0", - "property": { - "description": "vdns_onap_private_ip_0", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_onap_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vdns_onap_private_ip_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vdns_onap_private_ip_0", + "name": "vdns_onap_private_ip_0", + "property": { + "description": "vdns_onap_private_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vf-modules/vf-module/$vdns_vf_module_id/vf-module-data/vf-module-topology/vf-module-parameters/param/vdns_onap_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id", + "vdns_vf_module_id": "vdns_vf_module_id" + }, + "output-key-mapping": { + "vdns_onap_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id", + "vdns_vf_module_id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vdns_vf_module_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_vf_module_id.json new file mode 100644 index 000000000..d428268b6 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vdns_vf_module_id.json @@ -0,0 +1,53 @@ +{ + "tags": "vdns_vf_module_id", + "name": "vdns_vf_module_id", + "property": { + "description": "vdns_vf_module_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vdns_vf_module_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vdns_vf_module_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + }, + "aai-data": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/aai/v14/network/generic-vnfs/generic-vnf/$vnf-id", + "path": "", + "input-key-mapping": { + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vdns_vf_module_id": "nm-profile-name" + }, + "key-dependencies": [ + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-label.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-label.json index 55526b12b..7e52d0801 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-label.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-label.json @@ -1,34 +1,35 @@ { - "tags": "vf-module-label", - "name": "vf-module-label", - "property": { - "description": "vf-module-label", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "type": "SQL", - "query": "select sdnctl.VF_MODULE_MODEL.vf_module_label as vf_module_label from sdnctl.VF_MODULE_MODEL where sdnctl.VF_MODULE_MODEL.customization_uuid=:customizationid", - "input-key-mapping": { - "customizationid": "vf-module-model-customization-uuid" - }, - "output-key-mapping": { - "vf-module-label": "vf_module_label" - }, - "key-dependencies": [ - "vf-module-model-customization-uuid" - ] - } - } - } -} + "tags": "vf-module-label", + "name": "vf-module-label", + "property": { + "description": "vf-module-label", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select sdnctl.VF_MODULE_MODEL.vf_module_label as vf_module_label from sdnctl.VF_MODULE_MODEL where sdnctl.VF_MODULE_MODEL.customization_uuid=:customizationid", + "input-key-mapping": { + "customizationid": "vf-module-model-customization-uuid" + }, + "output-key-mapping": { + "vf-module-label": "vf_module_label" + }, + "key-dependencies": [ + "vf-module-model-customization-uuid" + ], + "endpoint-selector": "dynamic-db-source" + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-model-customization-uuid.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-model-customization-uuid.json index 232d6580b..6443235c8 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-model-customization-uuid.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-model-customization-uuid.json @@ -1,18 +1,18 @@ { - "tags": "vf-module-model-customization-uuid", - "name": "vf-module-model-customization-uuid", - "property": { - "description": "vf-module-model-customization-uuid", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - } - } + "tags": "vf-module-model-customization-uuid", + "name": "vf-module-model-customization-uuid", + "property": { + "description": "vf-module-model-customization-uuid", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + } + } }
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-name.json new file mode 100644 index 000000000..0cd9da12a --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-name.json @@ -0,0 +1,18 @@ +{ + "tags": "vf-module-name", + "name": "vf-module-name", + "property": { + "description": "vf_module_name", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-type.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-type.json index dcef02774..06f36104a 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-type.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf-module-type.json @@ -1,34 +1,35 @@ { - "tags": "vf-module-type", - "name": "vf-module-type", - "property": { - "description": "vf-module-type", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "type": "SQL", - "query": "select vf_module_type as vf_module_type from sdnctl.VF_MODULE_MODEL where customization_uuid=:customizationid", - "input-key-mapping": { - "customizationid": "vf-module-model-customization-uuid" - }, - "output-key-mapping": { - "vf-module-type": "vf_module_type" - }, - "key-dependencies": [ - "vf-module-model-customization-uuid" - ] - } - } - } -} + "tags": "vf-module-type", + "name": "vf-module-type", + "property": { + "description": "vf-module-type", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select vf_module_type as vf_module_type from sdnctl.VF_MODULE_MODEL where customization_uuid=:customizationid", + "output-key-mapping": { + "vf-module-type": "vf_module_type" + }, + + "input-key-mapping": { + "customizationid": "vf-module-model-customization-uuid" + }, + "key-dependencies": [ + "vf-module-model-customization-uuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf-naming-policy.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf-naming-policy.json index 6c9639cae..7af89e193 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vf-naming-policy.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf-naming-policy.json @@ -1,30 +1,52 @@ { - "name" : "vf-naming-policy", - "tags" : "vf-naming-policy", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vf-naming-policy", - "type" : "string" - }, - "sources" : { - "default": { - "type": "source-default", - "properties": { - } - }, - "processor-db" : { - "type" : "source-db", - "properties" : { - "type" : "SQL", - "query" : "select sdnctl.VF_MODEL.naming_policy as vf_naming_policy from sdnctl.VF_MODEL where sdnctl.VF_MODEL.customization_uuid=:vnf_model_customization_uuid", - "input-key-mapping" : { - "vnf_model_customization_uuid" : "vnf-model-customization-uuid" - }, - "output-key-mapping" : { - "vf-naming-policy" : "vf_naming_policy" - }, - "key-dependencies" : [ "vnf-model-customization-uuid" ] - } - } - } -} + "tags": "vf-naming-policy", + "name": "vf-naming-policy", + "property": { + "description": "vf-naming-policy", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vf-naming-policy", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vf-naming-policy": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.VF_MODEL.naming_policy as vf_naming_policy from sdnctl.VF_MODEL where sdnctl.VF_MODEL.customization_uuid=:vnf_model_customization_uuid", + "input-key-mapping": { + "vnf_model_customization_uuid": "vnf-model-customization-uuid" + }, + "output-key-mapping": { + "vf-naming-policy": "vf_naming_policy" + }, + "key-dependencies": [ + "vnf-model-customization-uuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf-nf-code.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf-nf-code.json index 1bf36ef39..e4d4e6d5a 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vf-nf-code.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf-nf-code.json @@ -1,25 +1,27 @@ { - "name" : "vf-nf-code", - "tags" : "vf-nf-code", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vf-nf-code", - "type" : "string" - }, - "sources" : { - "processor-db" : { - "type" : "source-db", - "properties" : { - "type" : "SQL", - "query" : "select sdnctl.VF_MODEL.nf_code as vf_nf_code from sdnctl.VF_MODEL where sdnctl.VF_MODEL.customization_uuid=:customizationid", - "input-key-mapping" : { - "customizationid" : "vnf-model-customization-uuid" - }, - "output-key-mapping" : { - "vf-nf-code" : "vf_nf_code" - }, - "key-dependencies" : [ "vnf-model-customization-uuid" ] - } - } - } -} + "tags": "vf-nf-code", + "name": "vf-nf-code", + "property": { + "description": "vf-nf-code", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select sdnctl.VF_MODEL.nf_code as vf_nf_code from sdnctl.VF_MODEL where sdnctl.VF_MODEL.customization_uuid=:customizationid", + "input-key-mapping": { + "customizationid": "vnf-model-customization-uuid" + }, + "output-key-mapping": { + "vf-nf-code": "vf_nf_code" + }, + "key-dependencies": [ + "vnf-model-customization-uuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vf_module_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/vf_module_id.json index ff0c59773..231d2c5a5 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vf_module_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vf_module_id.json @@ -1,19 +1,18 @@ - { - "tags": "vf_module_id", - "name": "vf_module_id", - "property": { - "description": "vf_module_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - } - } - - }
\ No newline at end of file +{ + "tags": "vf_module_id", + "name": "vf_module_id", + "property": { + "description": "vf_module_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "default": { + "type": "source-default", + "properties": {} + }, + "input": { + "type": "source-input" + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfccustomizationuuid.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfccustomizationuuid.json index bd8f5e123..694f0e733 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vfccustomizationuuid.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfccustomizationuuid.json @@ -1,35 +1,35 @@ { - "tags": "vfccustomizationuuid", - "name": "vfccustomizationuuid", - "property": { - "description": "vfccustomizationuuid", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.VF_MODULE_TO_VFC_MAPPING.vfc_customization_uuid as vnf_customid from sdnctl.VF_MODULE_TO_VFC_MAPPING where vm_count = 1 and sdnctl.VF_MODULE_TO_VFC_MAPPING.vf_module_customization_uuid=:vfmodulecustomizationuuid", - "input-key-mapping": { - "vfmodulecustomizationuuid": "vf-module-model-customization-uuid" - }, - "output-key-mapping": { - "vfccustomizationuuid": "vnf_customid" - }, - "key-dependencies": [ - "vf-module-model-customization-uuid" - ] - } - } - } -} + "tags": "vfccustomizationuuid", + "name": "vfccustomizationuuid", + "property": { + "description": "vfccustomizationuuid", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.VF_MODULE_TO_VFC_MAPPING.vfc_customization_uuid as vnf_customid from sdnctl.VF_MODULE_TO_VFC_MAPPING where vm_count = 1 and sdnctl.VF_MODULE_TO_VFC_MAPPING.vf_module_customization_uuid=:vfmodulecustomizationuuid", + "input-key-mapping": { + "vfmodulecustomizationuuid": "vf-module-model-customization-uuid" + }, + "output-key-mapping": { + "vfccustomizationuuid": "vnf_customid" + }, + "key-dependencies": [ + "vf-module-model-customization-uuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_flavor_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_flavor_name.json new file mode 100644 index 000000000..bd539cde5 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_flavor_name.json @@ -0,0 +1,38 @@ +{ + "tags": "vfw_flavor_name", + "name": "vfw_flavor_name", + "property": { + "description": "vfw_flavor_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_flavor_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_flavor_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_image_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_image_name.json new file mode 100644 index 000000000..4878d572f --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_image_name.json @@ -0,0 +1,38 @@ +{ + "tags": "vfw_image_name", + "name": "vfw_image_name", + "property": { + "description": "vfw_image_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_image_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_image_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private1_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private1_ip_0.json new file mode 100644 index 000000000..7374f6fb9 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private1_ip_0.json @@ -0,0 +1,38 @@ +{ + "tags": "vfw_int_private1_ip_0", + "name": "vfw_int_private1_ip_0", + "property": { + "description": "vfw_int_private1_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_int_private1_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_int_private1_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private2_floating_ip.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private2_floating_ip.json new file mode 100644 index 000000000..d6ef22116 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private2_floating_ip.json @@ -0,0 +1,38 @@ +{ + "tags": "vfw_int_private2_floating_ip", + "name": "vfw_int_private2_floating_ip", + "property": { + "description": "vfw_int_private2_floating_ip", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_int_private2_floating_ip", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_int_private2_floating_ip": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private2_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private2_ip_0.json new file mode 100644 index 000000000..c45e549bb --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_int_private2_ip_0.json @@ -0,0 +1,38 @@ +{ + "tags": "vfw_int_private2_ip_0", + "name": "vfw_int_private2_ip_0", + "property": { + "description": "vfw_int_private2_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_int_private2_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_int_private2_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_name_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_name_0.json index 96a975859..6f774bf65 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_name_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_name_0.json @@ -1,15 +1,38 @@ { - "name" : "vfw_name_0", - "tags" : "vfw_name_0", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vfw_name_0", - "type" : "string" - }, - "sources" : { - "input" : { - "type" : "source-input", - "properties" : { } - } - } + "tags": "vfw_name_0", + "name": "vfw_name_0", + "property": { + "description": "vfw_name_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_name_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_name_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } }
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vfw_onap_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_onap_private_ip_0.json new file mode 100644 index 000000000..da65a00eb --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vfw_onap_private_ip_0.json @@ -0,0 +1,38 @@ +{ + "tags": "vfw_onap_private_ip_0", + "name": "vfw_onap_private_ip_0", + "property": { + "description": "vfw_onap_private_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vfw_onap_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vfw_onap_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vip.json b/components/model-catalog/resource-dictionary/starter-dictionary/vip.json index 289ab1994..5c649dfc7 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vip.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vip.json @@ -1,37 +1,38 @@ { - "tags": "vip", - "name": "vip", - "property": { - "description": "vip", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vip", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vip": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vip", + "name": "vip", + "property": { + "description": "vip", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vip", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vip": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_0_int_pktgen_private_port_0_mac.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_0_int_pktgen_private_port_0_mac.json index 7640aa21f..0ab9a5319 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_0_int_pktgen_private_port_0_mac.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_0_int_pktgen_private_port_0_mac.json @@ -1,37 +1,38 @@ { - "tags": "vlb_0_int_pktgen_private_port_0_mac", - "name": "vlb_0_int_pktgen_private_port_0_mac", - "property": { - "description": "vlb_0_int_pktgen_private_port_0_mac", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_0_int_pktgen_private_port_0_mac", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_0_int_pktgen_private_port_0_mac": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vlb_0_int_pktgen_private_port_0_mac", + "name": "vlb_0_int_pktgen_private_port_0_mac", + "property": { + "description": "vlb_0_int_pktgen_private_port_0_mac", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_0_int_pktgen_private_port_0_mac", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_0_int_pktgen_private_port_0_mac": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_flavor_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_flavor_name.json index 3ba34ee37..157170837 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_flavor_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_flavor_name.json @@ -1,37 +1,38 @@ { - "tags": "vlb_flavor_name", - "name": "vlb_flavor_name", - "property": { - "description": "vlb_flavor_name", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_flavor_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_flavor_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vlb_flavor_name", + "name": "vlb_flavor_name", + "property": { + "description": "vlb_flavor_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_flavor_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_flavor_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_image_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_image_name.json index 0db006b55..76c7e67af 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_image_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_image_name.json @@ -1,37 +1,38 @@ { - "tags": "vlb_image_name", - "name": "vlb_image_name", - "property": { - "description": "vlb_image_name", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_image_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_image_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vlb_image_name", + "name": "vlb_image_name", + "property": { + "description": "vlb_image_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_image_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_image_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_pktgen_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_pktgen_private_ip_0.json index 04604eb2b..af55cd741 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_pktgen_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_pktgen_private_ip_0.json @@ -1,37 +1,38 @@ - { - "tags": "vlb_int_pktgen_private_ip_0", - "name": "vlb_int_pktgen_private_ip_0", - "property": { - "description": "vlb_int_pktgen_private_ip_0", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_int_pktgen_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_int_pktgen_private_ip_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - } +{ + "tags": "vlb_int_pktgen_private_ip_0", + "name": "vlb_int_pktgen_private_ip_0", + "property": { + "description": "vlb_int_pktgen_private_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_int_pktgen_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_int_pktgen_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_private_ip_0.json index 4ca8e70cb..1ac5e1950 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_int_private_ip_0.json @@ -1,38 +1,38 @@ - { - "tags": "vlb_int_private_ip_0", - "name": "vlb_int_private_ip_0", - "property": { - "description": "vlb_int_private_ip_0", - "type": "string" - }, - "updated-by": "Singal, Kapil <ks220y@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_int_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_int_private_ip_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } - - } +{ + "tags": "vlb_int_private_ip_0", + "name": "vlb_int_private_ip_0", + "property": { + "description": "vlb_int_private_ip_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_int_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_int_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_name_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_name_0.json index f8e7f31de..acf34949d 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_name_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_name_0.json @@ -1,37 +1,38 @@ { - "tags": "vlb_name_0", - "name": "vlb_name_0", - "property": { - "description": "vlb_name_0", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_name_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_name_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vlb_name_0", + "name": "vlb_name_0", + "property": { + "description": "vlb_name_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_name_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_name_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_onap_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_onap_private_ip_0.json index b78cc9fca..6279e446f 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_onap_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_onap_private_ip_0.json @@ -1,37 +1,38 @@ { - "tags": "vlb_onap_private_ip_0", - "name": "vlb_onap_private_ip_0", - "property": { - "description": "vlb_onap_private_ip_0", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_onap_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "private2-prefix-id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vlb_onap_private_ip_0", + "name": "vlb_onap_private_ip_0", + "property": { + "description": "vlb_onap_private_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_onap_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "private2-prefix-id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_cidr.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_cidr.json index 419ef2255..cf782cc9d 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_cidr.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_cidr.json @@ -1,49 +1,50 @@ { - "tags": "vlb_private_net_cidr", - "name": "vlb_private_net_cidr", - "property": { - "description": "vlb_private_net_cidr", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_private_net_cidr", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_private_net_cidr": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private1\"", - "input-key-mapping": {}, - "output-key-mapping": { - "vlb_private_net_cidr": "prefix" - } - } - } - } -} + "tags": "vlb_private_net_cidr", + "name": "vlb_private_net_cidr", + "property": { + "description": "vlb_private_net_cidr", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private1\"", + "input-key-mapping": {}, + "output-key-mapping": { + "vlb_private_net_cidr": "prefix" + } + } + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_private_net_cidr", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_private_net_cidr": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_id.json b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_id.json index 38f33a263..5e832206e 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vlb_private_net_id.json @@ -1,37 +1,38 @@ { - "tags": "vlb_private_net_id", - "name": "vlb_private_net_id", - "property": { - "description": "vlb_private_net_id", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_private_net_id", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vlb_private_net_id": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vlb_private_net_id", + "name": "vlb_private_net_id", + "property": { + "description": "vlb_private_net_id", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vlb_private_net_id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vlb_private_net_id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vm-type.json b/components/model-catalog/resource-dictionary/starter-dictionary/vm-type.json index d24478d96..a514592b5 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vm-type.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vm-type.json @@ -1,35 +1,35 @@ { - "tags": "vm-type", - "name": "vm-type", - "property": { - "description": "vm-type", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select VFC_MODEL.vm_type as vm_type from VFC_MODEL where customization_uuid=:vfccustomizationuuid", - "input-key-mapping": { - "vfccustomizationuuid": "vfccustomizationuuid" - }, - "output-key-mapping": { - "vm-type": "vm_type" - }, - "key-dependencies": [ - "vfccustomizationuuid" - ] - } - } - } -} + "tags": "vm-type", + "name": "vm-type", + "property": { + "description": "vm-type", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select VFC_MODEL.vm_type as vm_type from VFC_MODEL where customization_uuid=:vfccustomizationuuid", + "output-key-mapping": { + "vm-type": "vm_type" + }, + + "input-key-mapping": { + "vfccustomizationuuid": "vfccustomizationuuid" + }, + "key-dependencies": [ + "vfccustomizationuuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json index a71bef975..7b170a622 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json @@ -13,6 +13,26 @@ "default": { "type": "source-default", "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-id", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vnf-id": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } } } } + diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-model-customization-uuid.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-model-customization-uuid.json index 2aa08c40f..e598f6a4d 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-model-customization-uuid.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-model-customization-uuid.json @@ -1,15 +1,15 @@ { - "name" : "vnf-model-customization-uuid", - "tags" : "vnf-model-customization-uuid", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vnf-model-customization-uuid", - "type" : "string" - }, - "sources" : { - "input" : { - "type" : "source-input", - "properties" : { } - } - } + "tags": "vnf-model-customization-uuid", + "name": "vnf-model-customization-uuid", + "property": { + "description": "vnf-model-customization-uuid", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input", + "properties": {} + } + } }
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json index 7d6511935..7d6511935 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnf_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnf_name.json index b8649bfbe..1794b6a83 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vnf_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnf_name.json @@ -1,37 +1,37 @@ -{ - "name" : "vnf_name", - "tags" : "vnf_name", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vnf_name", - "type" : "string" - }, - "sources" : { - "default": { - "type": "source-default", - "properties": { - } - }, - "input": { - "type": "source-input", - "properties": { - } - }, - "sdnc" : { - "type" : "source-rest", - "properties" : { - "type" : "JSON", - "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name", - "path" : "/param/0/value", - "input-key-mapping" : { - "service-instance-id" : "service-instance-id", - "vnf-id" : "vnf-id" - }, - "output-key-mapping" : { - "vnf_name" : "value" - }, - "key-dependencies" : [ "service-instance-id", "vnf-id" ] - } - } - } -} +{
+ "tags": "vnf_name",
+ "name": "vnf_name",
+ "property": {
+ "description": "vnf_name",
+ "type": "string"
+ },
+ "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>",
+ "sources": {
+ "input": {
+ "type": "source-input"
+ },
+ "default": {
+ "type": "source-default",
+ "properties": {}
+ },
+ "sdnc": {
+ "type": "source-rest",
+ "properties": {
+ "verb": "GET", "type": "JSON",
+ "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name",
+ "path": "/param/0/value",
+ "input-key-mapping": {
+ "service-instance-id": "service-instance-id",
+ "vnf-id": "vnf-id"
+ },
+ "output-key-mapping": {
+ "vnf_name": "value"
+ },
+ "key-dependencies": [
+ "service-instance-id",
+ "vnf-id"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-invariant-uuid.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-invariant-uuid.json index 2150b5009..d78ee0d29 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-invariant-uuid.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-invariant-uuid.json @@ -1,35 +1,35 @@ { - "tags": "vnfc-model-invariant-uuid", - "name": "vnfc-model-invariant-uuid", - "property": { - "description": "vnfc-model-invariant-uuid", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select VFC_MODEL.invariant_uuid as vfc_invariant_uuid from VFC_MODEL where customization_uuid=:vfccustomizationuuid", - "input-key-mapping": { - "vfccustomizationuuid": "vfccustomizationuuid" - }, - "output-key-mapping": { - "vnfc-model-invariant-uuid": "vfc_invariant_uuid" - }, - "key-dependencies": [ - "vfccustomizationuuid" - ] - } - } - } -} + "tags": "vnfc-model-invariant-uuid", + "name": "vnfc-model-invariant-uuid", + "property": { + "description": "vnfc-model-invariant-uuid", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + "type": "SQL", + "query": "select VFC_MODEL.invariant_uuid as vfc_invariant_uuid from VFC_MODEL where customization_uuid=:vfccustomizationuuid", + "output-key-mapping": { + "vnfc-model-invariant-uuid": "vfc_invariant_uuid" + }, + + "input-key-mapping": { + "vfccustomizationuuid": "vfccustomizationuuid" + }, + "key-dependencies": [ + "vfccustomizationuuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-version.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-version.json index 4673a61e2..cc9eb62ce 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-version.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnfc-model-version.json @@ -1,35 +1,35 @@ { - "tags": "vnfc-model-version", - "name": "vnfc-model-version", - "property": { - "description": "vnfc-model-version", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "processor-db": { - "type": "source-db", - "properties": { - "endpoint-selector": "dynamic-db-source", - "type": "SQL", - "query": "select VFC_MODEL.version as vnfc_model_version from VFC_MODEL where customization_uuid=:vfccustomizationuuid", - "input-key-mapping": { - "vfccustomizationuuid": "vfccustomizationuuid" - }, - "output-key-mapping": { - "vnfc-model-version": "vnfc_model_version" - }, - "key-dependencies": [ - "vfccustomizationuuid" - ] - } - } - } -} + "tags": "vnfc-model-version", + "name": "vnfc-model-version", + "property": { + "description": "vnfc-model-version", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "processor-db": { + "type": "source-db", + "properties": { + + "type": "SQL", + "query": "select VFC_MODEL.version as vnfc_model_version from VFC_MODEL where customization_uuid=:vfccustomizationuuid", + "input-key-mapping": { + "vfccustomizationuuid": "vfccustomizationuuid" + }, + "output-key-mapping": { + "vnfc-model-version": "vnfc_model_version" + }, + "key-dependencies": [ + "vfccustomizationuuid" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_flavor_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_flavor_name.json index ae2152849..faeccf79b 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_flavor_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_flavor_name.json @@ -1,37 +1,38 @@ { - "tags": "vpg_flavor_name", - "name": "vpg_flavor_name", - "property": { - "description": "vpg_flavor_name", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_flavor_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vpg_flavor_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vpg_flavor_name", + "name": "vpg_flavor_name", + "property": { + "description": "vpg_flavor_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_flavor_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vpg_flavor_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_image_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_image_name.json index 3fd99a693..1bee33cb3 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_image_name.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_image_name.json @@ -1,37 +1,38 @@ { - "tags": "vpg_image_name", - "name": "vpg_image_name", - "property": { - "description": "vpg_image_name", - "type": "string" - }, - "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_image_name", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vpg_image_name": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vpg_image_name", + "name": "vpg_image_name", + "property": { + "description": "vpg_image_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_image_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vpg_image_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_pktgen_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_pktgen_private_ip_0.json index 88e9720dc..42aeed601 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_pktgen_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_pktgen_private_ip_0.json @@ -1,37 +1,38 @@ { - "tags": "vpg_int_pktgen_private_ip_0", - "name": "vpg_int_pktgen_private_ip_0", - "property": { - "description": "vpg_int_pktgen_private_ip_0", - "type": "string" - }, - "updated-by": "Singal, Kapil <ks220y@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_int_pktgen_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vpg_int_pktgen_private_ip_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vpg_int_pktgen_private_ip_0", + "name": "vpg_int_pktgen_private_ip_0", + "property": { + "description": "vpg_int_pktgen_private_ip_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_int_pktgen_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vpg_int_pktgen_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_private1_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_private1_ip_0.json new file mode 100644 index 000000000..c54ab2023 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_int_private1_ip_0.json @@ -0,0 +1,38 @@ +{ + "tags": "vpg_int_private1_ip_0", + "name": "vpg_int_private1_ip_0", + "property": { + "description": "vpg_int_private1_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_int_private1_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vpg_int_private1_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_name_0 .json b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_name_0 .json new file mode 100644 index 000000000..65f54f677 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_name_0 .json @@ -0,0 +1,38 @@ +{ + "tags": "vpg_name_0", + "name": "vpg_name_0", + "property": { + "description": "vlb_name_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_name_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vpg_name_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_onap_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_onap_private_ip_0.json index cfdf8b928..bfb12b8b4 100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vpg_onap_private_ip_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vpg_onap_private_ip_0.json @@ -1,37 +1,38 @@ { - "tags": "vpg_onap_private_ip_0", - "name": "vpg_onap_private_ip_0", - "property": { - "description": "vpg_onap_private_ip_0", - "type": "string" - }, - "updated-by": "Singal, Kapil <ks220y@att.com>", - "sources": { - "input": { - "type": "source-input" - }, - "default": { - "type": "source-default", - "properties": {} - }, - "sdnc": { - "type": "source-rest", - "properties": { - "type": "JSON", - "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_onap_private_ip_0", - "path": "/param/0/value", - "input-key-mapping": { - "service-instance-id": "service-instance-id", - "vnf-id": "vnf-id" - }, - "output-key-mapping": { - "vpg_onap_private_ip_0": "value" - }, - "key-dependencies": [ - "service-instance-id", - "vnf-id" - ] - } - } - } -} + "tags": "vpg_onap_private_ip_0", + "name": "vpg_onap_private_ip_0", + "property": { + "description": "vpg_onap_private_ip_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vpg_onap_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vpg_onap_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vsn_flavor_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_flavor_name.json new file mode 100644 index 000000000..89bd9c4ec --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_flavor_name.json @@ -0,0 +1,38 @@ +{ + "tags": "vsn_flavor_name", + "name": "vsn_flavor_name", + "property": { + "description": "vsn_flavor_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_flavor_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vsn_flavor_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vsn_image_name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_image_name.json new file mode 100644 index 000000000..8edeb565d --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_image_name.json @@ -0,0 +1,38 @@ +{ + "tags": "vsn_image_name", + "name": "vsn_image_name", + "property": { + "description": "vsn_image_name", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_image_name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vsn_image_name": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vsn_int_private2_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_int_private2_ip_0.json new file mode 100644 index 000000000..c0015a682 --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_int_private2_ip_0.json @@ -0,0 +1,38 @@ +{ + "tags": "vsn_int_private2_ip_0", + "name": "vsn_int_private2_ip_0", + "property": { + "description": "vsn_int_private2_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_int_private2_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vsn_int_private2_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vsn_name_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_name_0.json index 7b7ba4574..1ad25b3f9 100755..100644 --- a/components/model-catalog/resource-dictionary/starter-dictionary/vsn_name_0.json +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_name_0.json @@ -1,15 +1,38 @@ { - "name" : "vsn_name_0", - "tags" : "vsn_name_0", - "updated-by" : "Singal, Kapil <ks220y@att.com>", - "property" : { - "description" : "vsn_name_0", - "type" : "string" - }, - "sources" : { - "input" : { - "type" : "source-input", - "properties" : { } - } - } + "tags": "vsn_name_0", + "name": "vsn_name_0", + "property": { + "description": "vsn_name_0", + "type": "string" + }, + "updated-by": "Singal, Kapil <ks220y@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_name_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vsn_name_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } }
\ No newline at end of file diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vsn_onap_private_ip_0.json b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_onap_private_ip_0.json new file mode 100644 index 000000000..b769bc6ee --- /dev/null +++ b/components/model-catalog/resource-dictionary/starter-dictionary/vsn_onap_private_ip_0.json @@ -0,0 +1,38 @@ +{ + "tags": "vsn_onap_private_ip_0", + "name": "vsn_onap_private_ip_0", + "property": { + "description": "vsn_onap_private_ip_0", + "type": "string" + }, + "updated-by": "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources": { + "input": { + "type": "source-input" + }, + "default": { + "type": "source-default", + "properties": {} + }, + "sdnc": { + "type": "source-rest", + "properties": { + "verb": "GET", + "type": "JSON", + "url-path": "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vsn_onap_private_ip_0", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vsn_onap_private_ip_0": "value" + }, + "key-dependencies": [ + "service-instance-id", + "vnf-id" + ] + } + } + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml index ed1b67dfd..0ee6ac339 100755 --- a/ms/blueprintsprocessor/application/pom.xml +++ b/ms/blueprintsprocessor/application/pom.xml @@ -24,7 +24,7 @@ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>parent</artifactId> <version>0.7.0-SNAPSHOT</version> - <relativePath>../parent</relativePath> + <relativePath>..</relativePath> </parent> <artifactId>application</artifactId> @@ -38,7 +38,6 @@ <name.space>org.onap.ccsdk.cds</name.space> <serviceArtifactName>blueprintsprocessor</serviceArtifactName> <image.name>onap/ccsdk-blueprintsprocessor</image.name> - <docker.buildArg.https_proxy>${https_proxy}</docker.buildArg.https_proxy> <docker.push.phase>deploy</docker.push.phase> <docker.verbose>true</docker.verbose> <ccsdk.project.version>${project.version}</ccsdk.project.version> @@ -141,23 +140,42 @@ <artifactId>reactor-test</artifactId> <scope>test</scope> </dependency> + <!-- BEGIN UAT --> + <dependency> + <groupId>org.skyscreamer</groupId> + <artifactId>jsonassert</artifactId> + </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> + <version>2.2.0</version> </dependency> <dependency> <groupId>com.schibsted.spt.data</groupId> <artifactId>jslt</artifactId> <version>0.1.8</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>${apache.httpcomponents.client.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpmime</artifactId> + <version>${apache.httpcomponents.client.version}</version> + </dependency> + <dependency> + <groupId>com.github.tomakehurst</groupId> + <artifactId>wiremock-jre8</artifactId> + <version>2.25.0</version> <scope>test</scope> </dependency> + <!-- END UAT --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> diff --git a/ms/blueprintsprocessor/application/src/main/dc/docker-compose.yaml b/ms/blueprintsprocessor/application/src/main/dc/docker-compose.yaml index e4bb00773..27f72b59b 100755 --- a/ms/blueprintsprocessor/application/src/main/dc/docker-compose.yaml +++ b/ms/blueprintsprocessor/application/src/main/dc/docker-compose.yaml @@ -58,7 +58,11 @@ services: STICKYSELECTORKEY: ENVCONTEXT: dev APP_PORT: 50052 - BASIC_AUTH: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== + #AUTH_TYPE: basic-auth + #AUTH_TOKEN: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== + AUTH_TYPE: tls-auth + AUTH_CERT_CHAIN: /opt/app/onap/python/py-executor-chain.pem + AUTH_PRIVATE_KEY: /opt/app/onap/python/py-executor-key.pem LOG_FILE: /opt/app/onap/logs/application.log volumes: diff --git a/ms/blueprintsprocessor/application/src/main/docker/Dockerfile b/ms/blueprintsprocessor/application/src/main/docker/Dockerfile index dab0a4c01..207cec5cb 100755 --- a/ms/blueprintsprocessor/application/src/main/docker/Dockerfile +++ b/ms/blueprintsprocessor/application/src/main/docker/Dockerfile @@ -1,8 +1,5 @@ FROM omahoco1/alpine-java-python -ENV HTTP_PROXY ${HTTP_PROXY} -ENV HTTPS_PROXY ${HTTPS_PROXY} - # add entrypoint COPY run.source /etc/run.source COPY startService.sh /startService.sh @@ -15,4 +12,4 @@ RUN tar -xzf /source.tar.gz -C /tmp \ && rm -rf /source.tar.gz \ && rm -rf /tmp/@project.build.finalName@ -ENTRYPOINT /startService.sh
\ No newline at end of file +ENTRYPOINT /startService.sh diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintGRPCServer.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintGRPCServer.kt index 160a1b1b4..2d39eaa1f 100644 --- a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintGRPCServer.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintGRPCServer.kt @@ -18,6 +18,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor import io.grpc.ServerBuilder import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.BluePrintManagementGRPCHandler +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcServerLoggingInterceptor import org.onap.ccsdk.cds.blueprintsprocessor.security.BasicAuthServerInterceptor import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.BluePrintProcessingGRPCHandler import org.onap.ccsdk.cds.controllerblueprints.core.logger @@ -44,6 +45,7 @@ open class BlueprintGRPCServer(private val bluePrintProcessingGRPCHandler: BlueP log.info("Starting Blueprint Processor GRPC Starting..") val server = ServerBuilder .forPort(grpcPort!!) + .intercept(GrpcServerLoggingInterceptor()) .intercept(authInterceptor) .addService(bluePrintProcessingGRPCHandler) .addService(bluePrintManagementGRPCHandler) diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt index 5ed5ff450..68fbf256c 100644 --- a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt @@ -16,7 +16,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor -import org.onap.ccsdk.cds.blueprintsprocessor.core.service.LoggingService +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.RestLoggerService import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext import org.springframework.stereotype.Component import org.springframework.web.server.ServerWebExchange @@ -29,7 +29,7 @@ import reactor.util.context.Context open class LoggingWebFilter : WebFilter { override fun filter(serverWebExchange: ServerWebExchange, webFilterChain: WebFilterChain): Mono<Void> { - val loggingService = LoggingService() + val loggingService = RestLoggerService() loggingService.entering(serverWebExchange.request) val filterChain = webFilterChain.filter(serverWebExchange).subscriberContext( Context.of(MDCContext, MDCContext())) diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/JsonNormalizer.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/JsonNormalizer.kt index 69673f931..1a625c279 100644 --- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/JsonNormalizer.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/JsonNormalizer.kt @@ -17,21 +17,20 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ContainerNode -import com.fasterxml.jackson.databind.node.MissingNode import com.fasterxml.jackson.databind.node.ObjectNode import com.schibsted.spt.data.jslt.Parser -class JsonNormalizer { +internal class JsonNormalizer { companion object { - fun getNormalizer(mapper: ObjectMapper, jsltSpec: JsonNode): (String) -> String { - if (jsltSpec is MissingNode) { + fun getNormalizer(mapper: ObjectMapper, jsltSpec: JsonNode?): (String) -> String { + if (jsltSpec == null) { return { it } } return { s: String -> diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/MoreMatchers.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/MoreMatchers.kt index 71e07ab4c..163544fc9 100644 --- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/MoreMatchers.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/MoreMatchers.kt @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat import com.google.common.collect.Maps import org.mockito.ArgumentMatcher diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/PathDeserializer.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/PathDeserializer.kt index 1a232f2d3..6b1b0c676 100644 --- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/PathDeserializer.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/PathDeserializer.kt @@ -17,13 +17,13 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationContext import com.fasterxml.jackson.databind.deser.std.StdDeserializer -class PathDeserializer : StdDeserializer<String>(String::class.java) { +internal class PathDeserializer : StdDeserializer<String>(String::class.java) { override fun deserialize(jp: JsonParser, ctxt: DeserializationContext?): String { val path = jp.codec.readValue(jp, Any::class.java) return flatJoin(path) diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatDefinition.kt index abb1dfcd1..3046f1041 100644 --- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatDefinition.kt @@ -17,45 +17,76 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat import com.fasterxml.jackson.annotation.JsonAlias +import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.node.MissingNode +import com.fasterxml.jackson.module.kotlin.convertValue +import org.yaml.snakeyaml.DumperOptions import org.yaml.snakeyaml.Yaml -import java.nio.file.Path +import org.yaml.snakeyaml.nodes.Tag -data class ProcessDefinition(val name: String, val request: JsonNode, val expectedResponse: JsonNode, - val responseNormalizerSpec: JsonNode = MissingNode.getInstance()) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class ProcessDefinition(val name: String, val request: JsonNode, val expectedResponse: JsonNode? = null, + val responseNormalizerSpec: JsonNode? = null) +@JsonInclude(JsonInclude.Include.NON_EMPTY) data class RequestDefinition(val method: String, @JsonDeserialize(using = PathDeserializer::class) val path: String, val headers: Map<String, String> = emptyMap(), - val body: JsonNode = MissingNode.getInstance()) + val body: JsonNode? = null) -data class ResponseDefinition(val status: Int = 200, val body: JsonNode = MissingNode.getInstance()) { +@JsonInclude(JsonInclude.Include.NON_EMPTY) +data class ResponseDefinition(val status: Int = 200, val body: JsonNode? = null) { companion object { val DEFAULT_RESPONSE = ResponseDefinition() } } +@JsonInclude(JsonInclude.Include.NON_EMPTY) data class ExpectationDefinition(val request: RequestDefinition, val response: ResponseDefinition = ResponseDefinition.DEFAULT_RESPONSE) +@JsonInclude(JsonInclude.Include.NON_EMPTY) data class ServiceDefinition(val selector: String, val expectations: List<ExpectationDefinition>) +@JsonInclude(JsonInclude.Include.NON_EMPTY) data class UatDefinition(val processes: List<ProcessDefinition>, @JsonAlias("external-services") val externalServices: List<ServiceDefinition> = emptyList()) { - companion object { - fun load(mapper: ObjectMapper, path: Path): UatDefinition { - return path.toFile().reader().use { reader -> - mapper.convertValue(Yaml().load(reader), UatDefinition::class.java) + fun dump(mapper: ObjectMapper, excludedProperties: List<String> = emptyList()): String { + val uatAsMap: Map<String, Any> = mapper.convertValue(this) + if (excludedProperties.isNotEmpty()) { + pruneTree(uatAsMap, excludedProperties) + } + return Yaml().dumpAs(uatAsMap, Tag.MAP, DumperOptions.FlowStyle.BLOCK) + } + + fun toBare(): UatDefinition { + val newProcesses = processes.map { p -> + ProcessDefinition(p.name, p.request, null, p.responseNormalizerSpec) + } + return UatDefinition(newProcesses) + } + + private fun pruneTree(node: Any?, excludedProperties: List<String>) { + when (node) { + is MutableMap<*, *> -> { + excludedProperties.forEach { key -> node.remove(key) } + node.forEach { (_, value) -> pruneTree(value, excludedProperties) } } + is List<*> -> node.forEach { value -> pruneTree(value, excludedProperties) } } } + + companion object { + fun load(mapper: ObjectMapper, spec: String): UatDefinition = + mapper.convertValue(Yaml().load(spec), UatDefinition::class.java) + + } } diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatExecutor.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatExecutor.kt new file mode 100644 index 000000000..6678075bd --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatExecutor.kt @@ -0,0 +1,324 @@ +/*- + * ============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.uat + +import com.fasterxml.jackson.databind.JsonNode +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.apache.http.HttpHeaders +import org.apache.http.HttpStatus +import org.apache.http.client.HttpClient +import org.apache.http.client.methods.HttpPost +import org.apache.http.entity.ContentType +import org.apache.http.entity.StringEntity +import org.apache.http.entity.mime.HttpMultipartMode +import org.apache.http.entity.mime.MultipartEntityBuilder +import org.apache.http.impl.client.HttpClientBuilder +import org.apache.http.message.BasicHeader +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.CoreMatchers.notNullValue +import org.hamcrest.MatcherAssert.assertThat +import org.mockito.Answers +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.blueprintsprocessor.uat.logging.LogColor.COLOR_MOCKITO +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.markerOf +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.MockInvocationLogger +import org.skyscreamer.jsonassert.JSONAssert +import org.skyscreamer.jsonassert.JSONCompareMode +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.core.env.ConfigurableEnvironment +import org.springframework.http.MediaType +import org.springframework.stereotype.Component +import org.springframework.util.Base64Utils +import java.util.concurrent.ConcurrentHashMap + +/** + * Assumptions: + * + * - Application HTTP service is bound to loopback interface; + * - Password is either defined in plain (with "{noop}" prefix), or it's the same of username. + * + * @author Eliezio Oliveira + */ +@Component +class UatExecutor( + private val environment: ConfigurableEnvironment, + private val restClientFactory: BluePrintRestLibPropertyService, + private val mapper: ObjectMapper +) { + + companion object { + private const val NOOP_PASSWORD_PREFIX = "{noop}" + + private val log: Logger = LoggerFactory.getLogger(UatExecutor::class.java) + private val mockLoggingListener = MockInvocationLogger(markerOf(COLOR_MOCKITO)) + } + + // use lazy evaluation to postpone until localServerPort is injected by Spring + private val baseUrl: String by lazy { + "http://127.0.0.1:${localServerPort()}" + } + + @Throws(AssertionError::class) + fun execute(uatSpec: String, cbaBytes: ByteArray) { + val uat = UatDefinition.load(mapper, uatSpec) + execute(uat, cbaBytes) + } + + /** + * + * The UAT can range from minimum to completely defined. + * + * @return an updated UAT with all NB and SB messages. + */ + @Throws(AssertionError::class) + fun execute(uat: UatDefinition, cbaBytes: ByteArray): UatDefinition { + val defaultHeaders = listOf(BasicHeader(HttpHeaders.AUTHORIZATION, clientAuthToken())) + val httpClient = HttpClientBuilder.create() + .setDefaultHeaders(defaultHeaders) + .build() + // Only if externalServices are defined + val mockInterceptor = MockPreInterceptor() + // Always defined and used, whatever the case + val spyInterceptor = SpyPostInterceptor(mapper) + restClientFactory.setInterceptors(mockInterceptor, spyInterceptor) + try { + // Configure mocked external services and save their expected requests for further validation + val requestsPerClient = uat.externalServices.associateBy( + { service -> + createRestClientMock(service.expectations).also { restClient -> + // side-effect: register restClient to override real instance + mockInterceptor.registerMock(service.selector, restClient) + } + }, + { service -> service.expectations.map { it.request } } + ) + + val newProcesses = httpClient.use { client -> + uploadBlueprint(client, cbaBytes) + + // Run processes + uat.processes.map { process -> + log.info("Executing process '${process.name}'") + val responseNormalizer = JsonNormalizer.getNormalizer(mapper, process.responseNormalizerSpec) + val actualResponse = processBlueprint(client, process.request, + process.expectedResponse, responseNormalizer) + ProcessDefinition(process.name, process.request, actualResponse, process.responseNormalizerSpec) + } + } + + // Validate requests to external services + for ((mockClient, requests) in requestsPerClient) { + requests.forEach { request -> + verify(mockClient, atLeastOnce()).exchangeResource( + eq(request.method), + eq(request.path), + argThat { assertJsonEquals(request.body, this) }, + argThat(RequiredMapEntriesMatcher(request.headers))) + } + // Don't mind the invocations to the overloaded exchangeResource(String, String, String) + verify(mockClient, atLeast(0)).exchangeResource(any(), any(), any()) + verifyNoMoreInteractions(mockClient) + } + + val newExternalServices = spyInterceptor.getSpies() + .map(SpyService::asServiceDefinition) + + return UatDefinition(newProcesses, newExternalServices) + } finally { + restClientFactory.clearInterceptors() + } + } + + private fun createRestClientMock(restExpectations: List<ExpectationDefinition>) + : BlueprintWebClientService { + val restClient = mock<BlueprintWebClientService>( + defaultAnswer = Answers.RETURNS_SMART_NULLS, + // our custom verboseLogging handler + invocationListeners = arrayOf(mockLoggingListener) + ) + + // 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.request.method), + eq(expectation.request.path), + any(), + any())) + .thenReturn(WebClientResponse(expectation.response.status, expectation.response.body.toString())) + } + return restClient + } + + @Throws(AssertionError::class) + private fun uploadBlueprint(client: HttpClient, cbaBytes: ByteArray) { + val multipartEntity = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("file", cbaBytes, ContentType.DEFAULT_BINARY, "cba.zip") + .build() + val request = HttpPost("$baseUrl/api/v1/blueprint-model/publish").apply { + entity = multipartEntity + } + client.execute(request) { response -> + val statusLine = response.statusLine + assertThat(statusLine.statusCode, equalTo(HttpStatus.SC_OK)) + } + } + + @Throws(AssertionError::class) + private fun processBlueprint(client: HttpClient, requestBody: JsonNode, + expectedResponse: JsonNode?, responseNormalizer: (String) -> String): JsonNode { + val stringEntity = StringEntity(mapper.writeValueAsString(requestBody), ContentType.APPLICATION_JSON) + val request = HttpPost("$baseUrl/api/v1/execution-service/process").apply { + entity = stringEntity + } + val response = client.execute(request) { response -> + val statusLine = response.statusLine + assertThat(statusLine.statusCode, equalTo(HttpStatus.SC_OK)) + val entity = response.entity + assertThat("Response contains no content", entity, notNullValue()) + entity.content.bufferedReader().use { it.readText() } + } + val actualResponse = responseNormalizer(response) + if (expectedResponse != null) { + assertJsonEquals(expectedResponse, actualResponse) + } + return mapper.readTree(actualResponse)!! + } + + @Throws(AssertionError::class) + private fun assertJsonEquals(expected: JsonNode?, actual: String): Boolean { + // special case + if ((expected == null) && actual.isBlank()) { + return true + } + // general case + JSONAssert.assertEquals(expected?.toString(), actual, JSONCompareMode.LENIENT) + // assertEquals throws an exception whenever match fails + return true + } + + private fun localServerPort(): Int = + (environment.getProperty("local.server.port") + ?: environment.getRequiredProperty("blueprint.httpPort")).toInt() + + private fun clientAuthToken(): String { + val username = environment.getRequiredProperty("security.user.name") + val password = environment.getRequiredProperty("security.user.password") + val plainPassword = when { + password.startsWith(NOOP_PASSWORD_PREFIX) -> password.substring(NOOP_PASSWORD_PREFIX.length) + else -> username + } + return "Basic " + Base64Utils.encodeToString("$username:$plainPassword".toByteArray()) + } + + private class MockPreInterceptor : BluePrintRestLibPropertyService.PreInterceptor { + private val mocks = ConcurrentHashMap<String, BlueprintWebClientService>() + + override fun getInstance(jsonNode: JsonNode): BlueprintWebClientService? { + TODO("jsonNode-keyed services not yet supported") + } + + override fun getInstance(selector: String): BlueprintWebClientService? = + mocks[selector] + + fun registerMock(selector: String, client: BlueprintWebClientService) { + mocks[selector] = client + } + } + + private class SpyPostInterceptor(private val mapper: ObjectMapper) : BluePrintRestLibPropertyService.PostInterceptor { + + private val spies = ConcurrentHashMap<String, SpyService>() + + override fun getInstance(jsonNode: JsonNode, service: BlueprintWebClientService): BlueprintWebClientService { + TODO("jsonNode-keyed services not yet supported") + } + + override fun getInstance(selector: String, service: BlueprintWebClientService): BlueprintWebClientService { + val spiedService = SpyService(mapper, selector, service) + spies[selector] = spiedService + return spiedService + } + + fun getSpies(): List<SpyService> = + spies.values.toList() + } + + private class SpyService(private val mapper: ObjectMapper, + val selector: String, + private val realService: BlueprintWebClientService) : + BlueprintWebClientService by realService { + + private val expectations: MutableList<ExpectationDefinition> = mutableListOf() + + override fun exchangeResource(methodType: String, path: String, request: String): WebClientResponse<String> = + exchangeResource(methodType, path, request, DEFAULT_HEADERS) + + override fun exchangeResource(methodType: String, path: String, request: String, + headers: Map<String, String>): WebClientResponse<String> { + val requestDefinition = RequestDefinition(methodType, path, headers, toJson(request)) + val realAnswer = realService.exchangeResource(methodType, path, request, headers) + val responseBody = when { + // TODO: confirm if we need to normalize the response here + realAnswer.status == HttpStatus.SC_OK -> toJson(realAnswer.body) + else -> null + } + val responseDefinition = ResponseDefinition(realAnswer.status, responseBody) + expectations.add(ExpectationDefinition(requestDefinition, responseDefinition)) + return realAnswer + } + + fun asServiceDefinition() = + ServiceDefinition(selector, expectations) + + private fun toJson(str: String): JsonNode? { + return when { + str.isNotBlank() -> mapper.readTree(str) + else -> null + } + } + + companion object { + private val DEFAULT_HEADERS = mapOf( + HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE + ) + } + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatServices.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatServices.kt new file mode 100644 index 000000000..f133fd7c7 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatServices.kt @@ -0,0 +1,121 @@ +/*- + * ============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.uat + +import com.fasterxml.jackson.databind.ObjectMapper +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.COLOR_SERVICES +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.resetContextColor +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.setContextColor +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.UAT_SPECIFICATION_FILE +import org.springframework.context.annotation.Profile +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.http.codec.multipart.FilePart +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestPart +import org.springframework.web.bind.annotation.RestController +import org.springframework.web.server.ResponseStatusException +import java.io.File +import java.util.zip.ZipFile + +/** + * Supporting services to help creating UAT specifications. + * + * @author Eliezio Oliveira + */ +@RestController +@RequestMapping("/api/v1/uat") +@Profile("uat") +open class UatServices(private val uatExecutor: UatExecutor, private val mapper: ObjectMapper) { + + @PostMapping("/verify", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) + @PreAuthorize("hasRole('USER')") + @Suppress("BlockingMethodInNonBlockingContext") + open fun verify(@RequestPart("cba") cbaFile: FilePart) = runBlocking { + setContextColor(COLOR_SERVICES) + val tempFile = createTempFile() + try { + cbaFile.transferTo(tempFile) + val uatSpec = readZipEntryAsText(tempFile, UAT_SPECIFICATION_FILE) + val cbaBytes = tempFile.readBytes() + uatExecutor.execute(uatSpec, cbaBytes) + } catch (e: AssertionError) { + throw ResponseStatusException(HttpStatus.BAD_REQUEST, e.message) + } catch (t: Throwable) { + throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, t.message, t) + } finally { + tempFile.delete() + resetContextColor() + } + } + + @PostMapping("/spy", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE], produces = ["text/vnd.yaml"]) + @PreAuthorize("hasRole('USER')") + @Suppress("BlockingMethodInNonBlockingContext") + open fun spy(@RequestPart("cba") cbaFile: FilePart, + @RequestPart("uat", required = false) uatFile: FilePart?): String = runBlocking { + val tempFile = createTempFile() + setContextColor(COLOR_SERVICES) + try { + cbaFile.transferTo(tempFile) + val uatSpec = when { + uatFile != null -> uatFile.readText() + else -> readZipEntryAsText(tempFile, UAT_SPECIFICATION_FILE) + } + val uat = UatDefinition.load(mapper, uatSpec) + val cbaBytes = tempFile.readBytes() + val updatedUat = uatExecutor.execute(uat, cbaBytes) + return@runBlocking updatedUat.dump(mapper, FIELDS_TO_EXCLUDE) + } catch (t: Throwable) { + throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, t.message, t) + } finally { + tempFile.delete() + resetContextColor() + } + } + + private fun FilePart.readText(): String { + val tempFile = createTempFile() + try { + transferTo(tempFile).block() + return tempFile.readText() + } finally { + tempFile.delete() + } + } + + @Suppress("SameParameterValue") + private fun readZipEntryAsText(file: File, entryName: String): String { + return ZipFile(file).use { zipFile -> zipFile.readEntryAsText(entryName) } + } + + private fun ZipFile.readEntryAsText(entryName: String): String { + val zipEntry = getEntry(entryName) + return getInputStream(zipEntry).readBytes().toString(Charsets.UTF_8) + } + + companion object { + // Fields that can be safely ignored from BPP response, and can be omitted on the UAT specification. + private val FIELDS_TO_EXCLUDE = listOf("timestamp") + } +}
\ 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/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/ColorMarker.kt index 63d64cae4..10139c839 100644 --- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/CollectionUtils2.kt +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/ColorMarker.kt @@ -17,15 +17,8 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat.logging -import org.springframework.util.CollectionUtils -import org.springframework.util.MultiValueMap +import org.slf4j.Marker - -/** - * 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())) -} +class ColorMarker internal constructor(private val dlg: Marker) : Marker by dlg
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/LogColor.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/LogColor.kt new file mode 100644 index 000000000..dce516933 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/LogColor.kt @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.ccsdk.cds.blueprintsprocessor.uat.logging + +import org.slf4j.MDC +import org.slf4j.MarkerFactory + +object LogColor { + + const val COLOR_SERVICES = "green" + const val COLOR_TEST_CLIENT = "yellow" + const val COLOR_MOCKITO = "cyan" + const val COLOR_WIREMOCK = "blue" + + // The Slf4j MDC key that will hold the global color + const val MDC_COLOR_KEY = "color" + + fun setContextColor(color: String) { + MDC.put(MDC_COLOR_KEY, color) + } + + fun resetContextColor() { + MDC.remove(MDC_COLOR_KEY) + } + + fun markerOf(color: String): ColorMarker = + ColorMarker(MarkerFactory.getMarker(color)) +} diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/MockInvocationLogger.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/MockInvocationLogger.kt new file mode 100644 index 000000000..f8e6bd486 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/MockInvocationLogger.kt @@ -0,0 +1,65 @@ +/*- + * ============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.uat.logging + +import org.mockito.listeners.InvocationListener +import org.mockito.listeners.MethodInvocationReport +import org.slf4j.LoggerFactory +import org.slf4j.Marker +import java.util.concurrent.atomic.AtomicInteger + +/** + * Logs all Mockito's mock/spy invocations. + * + * Used for debugging interactions with a mock. + */ +class MockInvocationLogger(private val marker: Marker) : InvocationListener { + + private val mockInvocationsCounter = AtomicInteger() + + override fun reportInvocation(report: MethodInvocationReport) { + val sb = StringBuilder() + sb.appendln("Method invocation #${mockInvocationsCounter.incrementAndGet()} on mock/spy") + report.locationOfStubbing?.let { location -> + sb.append(INDENT).append("stubbed ").appendln(location) + } + sb.appendln(report.invocation) + sb.append(INDENT).append("invoked ").appendln(report.invocation.location) + if (report.threwException()) { + sb.append(INDENT).append("has thrown -> ").append(report.throwable.javaClass.name) + report.throwable.message?.let { message -> + sb.append(" with message ").append(message) + } + sb.appendln() + } else { + sb.append(INDENT).append("has returned -> \"").append(report.returnedValue).append('"') + report.returnedValue?.let { value -> + sb.append(" (").append(value.javaClass.name).append(')') + } + sb.appendln() + } + log.info(marker, sb.toString()) + } + + companion object { + private const val INDENT = " " + private val log = LoggerFactory.getLogger(MockInvocationLogger::class.java) + } +} diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/SmartColorDiscriminator.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/SmartColorDiscriminator.kt new file mode 100644 index 000000000..d7b38d3fa --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/SmartColorDiscriminator.kt @@ -0,0 +1,41 @@ +/*- + * ============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.uat.logging + +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.sift.AbstractDiscriminator +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.MDC_COLOR_KEY + +class SmartColorDiscriminator : AbstractDiscriminator<ILoggingEvent>() { + var defaultValue: String = "white" + + override fun getKey(): String { + return MDC_COLOR_KEY + } + + fun setKey() { + throw UnsupportedOperationException("Key not settable. Using $MDC_COLOR_KEY") + } + + override fun getDiscriminatingValue(e: ILoggingEvent): String = + (e.marker as? ColorMarker)?.name + ?: e.mdcPropertyMap?.get(MDC_COLOR_KEY) + ?: defaultValue +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-local.yml b/ms/blueprintsprocessor/application/src/main/resources/application-local.yml new file mode 100644 index 000000000..de2cf4e52 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/resources/application-local.yml @@ -0,0 +1,65 @@ +appName: ControllerBluePrints +appVersion: 1.0.0 +blueprints: + processor: + functions: + python: + executor: + executionPath: ./components/scripts/python/ccsdk_blueprints + modulePaths: ./components/scripts/python/ccsdk_blueprints,./components/scripts/python/ccsdk_netconf,./components/scripts/python/ccsdk_restconf +blueprintsprocessor: + blueprintArchivePath: /tmp/cds/archive + blueprintDeployPath: /tmp/cds/deploy + blueprintWorkingPath: /tmp/cds/work + db: + primary: + driverClassName: org.mariadb.jdbc.Driver + hibernateDDLAuto: none + hibernateDialect: org.hibernate.dialect.MySQL5InnoDBDialect + hibernateHbm2ddlAuto: update + hibernateNamingStrategy: org.hibernate.cfg.ImprovedNamingStrategy + password: sdnctl + url: jdbc:mysql://localhost:3306/sdnctl + username: sdnctl + grpcEnable: false + grpcPort: 9111 + httpPort: 8080 + loadModelType: false + loadResourceDictionary: false + messageclient: + self-service-api: + bootstrapServers: 127.0.0.1:9092 + clientId: default-client-id + consumerTopic: receiver.t + groupId: receiver-id + kafkaEnable: false + topic: producer.t + type: kafka-basic-auth + remoteScriptCommand: + enabled: true + restclient: + sdncodl: + password: Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U + type: basic-auth + url: http://localhost:8282/ + username: admin + restconfEnabled: true +controllerblueprints: + loadInitialData: true +logging: + level: + org: + springframework: + boot: + context: + config: debug +ms_name: org.onap.ccsdk.apps.controllerblueprints +spring: + datasource: + password: sdnctl + url: jdbc:mysql://localhost:3306/sdnctl + username: sdnctl + security: + user: + name: ccsdkapps + password: '{bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu' diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-uat.yml b/ms/blueprintsprocessor/application/src/main/resources/application-uat.yml new file mode 100644 index 000000000..f00d62b0f --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/resources/application-uat.yml @@ -0,0 +1,4 @@ +server: + error: + include-exception: true + include-stacktrace: always diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt deleted file mode 100644 index ce7434f8e..000000000 --- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt +++ /dev/null @@ -1,242 +0,0 @@ -/*- - * ============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.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.MissingNode -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.mockito.Answers -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.EntityExchangeResult -import org.springframework.test.web.reactive.server.WebTestClient -import reactor.core.publisher.Mono -import java.io.File -import java.nio.charset.StandardCharsets -import java.nio.file.Paths -import kotlin.test.BeforeTest -import kotlin.test.Test - -// Only one runner can be configured with jUnit 4. We had to replace the SpringRunner by equivalent jUnit rules. -// See more on https://docs.spring.io/autorepo/docs/spring-framework/current/spring-framework-reference/testing.html#testcontext-junit4-rules -@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"]) -class BlueprintsAcceptanceTest(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(BlueprintsAcceptanceTest::class.java) - - /** - * Generates the parameters to create a test instance for every blueprint found under UAT_BLUEPRINTS_BASE_DIR - * that contains the proper UAT definition file. - */ - @Parameterized.Parameters(name = "{index} {0}") - @JvmStatic - fun testParameters(): 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, answer = Answers.RETURNS_SMART_NULLS) - 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 uat = UatDefinition.load(mapper, Paths.get(filename, EMBEDDED_UAT_FILE)) - - uploadBlueprint(blueprintName) - - // Configure mocked external services and save their expected requests for further validation - val requestsPerClient = uat.externalServices.associateBy( - { service -> createRestClientMock(service.selector, service.expectations) }, - { service -> service.expectations.map { it.request } } - ) - - // Run processes - for (process in uat.processes) { - log.info("Executing process '${process.name}'") - processBlueprint(process.request, process.expectedResponse, - JsonNormalizer.getNormalizer(mapper, process.responseNormalizerSpec)) - } - - // Validate requests to external services - for ((mockClient, requests) in requestsPerClient) { - requests.forEach { request -> - verify(mockClient, atLeastOnce()).exchangeResource( - eq(request.method), - eq(request.path), - argThat { assertJsonEqual(request.body, this) }, - argThat(RequiredMapEntriesMatcher(request.headers))) - } - // 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<ExpectationDefinition>) - : BlueprintWebClientService { - val restClient = mock<BlueprintWebClientService>(verboseLogging = true, - defaultAnswer = Answers.RETURNS_SMART_NULLS) - - // 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.request.method), - eq(expectation.request.path), - any(), - any())) - .thenReturn(WebClientResponse(expectation.response.status, expectation.response.body.toString())) - } - - whenever(restClientFactory.blueprintWebClientService(selector)) - .thenReturn(restClient) - return restClient - } - - private fun uploadBlueprint(blueprintName: String) { - val body = toMultiValueMap("file", getBlueprintAsResource(blueprintName)) - webTestClient - .post() - .uri("/api/v1/blueprint-model/publish") - .header("Authorization", TestSecuritySettings.clientAuthToken()) - .syncBody(body) - .exchange() - .expectStatus().isOk - } - - private fun processBlueprint(request: JsonNode, expectedResponse: JsonNode, - responseNormalizer: (String) -> String) { - webTestClient - .post() - .uri("/api/v1/execution-service/process") - .header("Authorization", TestSecuritySettings.clientAuthToken()) - .contentType(MediaType.APPLICATION_JSON_UTF8) - .body(Mono.just(request.toString()), String::class.java) - .exchange() - .expectStatus().isOk - .expectBody() - .consumeWith { response -> - assertJsonEqual(expectedResponse, responseNormalizer(getBodyAsString(response))) - } - } - - 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 assertJsonEqual(expected: JsonNode, actual: String): Boolean { - if ((actual == "") && (expected is MissingNode)) { - return true - } - JSONAssert.assertEquals(expected.toString(), actual, JSONCompareMode.LENIENT) - // assertEquals throws an exception whenever match fails - return true - } - - private fun getBodyAsString(result: EntityExchangeResult<ByteArray>): String { - val body = result.responseBody - if ((body == null) || body.isEmpty()) { - return "" - } - val charset = result.responseHeaders.contentType?.charset ?: StandardCharsets.UTF_8 - return String(body, charset) - } -}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/BaseUatTest.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/BaseUatTest.kt new file mode 100644 index 000000000..ec338f274 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/BaseUatTest.kt @@ -0,0 +1,56 @@ +/*- + * ============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.uat + +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.COLOR_TEST_CLIENT +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.resetContextColor +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.setContextColor +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.junit4.SpringRunner +import kotlin.test.AfterTest +import kotlin.test.BeforeTest + +@RunWith(SpringRunner::class) +// Also set blueprintsprocessor.httpPort=0 +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(initializers = [ + WorkingFoldersInitializer::class, + TestSecuritySettings.ServerContextInitializer::class +]) +@TestPropertySource(locations = ["classpath:application-test.properties"]) +abstract class BaseUatTest { + + @BeforeTest + fun setScope() { + setContextColor(COLOR_TEST_CLIENT) + } + + @AfterTest + fun clearScope() { + resetContextColor() + } + + companion object { + const val UAT_BLUEPRINTS_BASE_DIR = "../../../components/model-catalog/blueprint-model/uat-blueprints" + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/BlueprintsAcceptanceTest.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/BlueprintsAcceptanceTest.kt new file mode 100644 index 000000000..4fed0ce67 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/BlueprintsAcceptanceTest.kt @@ -0,0 +1,91 @@ +/*- + * ============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.uat + +import org.junit.ClassRule +import org.junit.Rule +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.UAT_SPECIFICATION_FILE +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintArchiveUtils.Companion.compressToBytes +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.context.junit4.rules.SpringClassRule +import org.springframework.test.context.junit4.rules.SpringMethodRule +import java.io.File +import java.nio.file.FileSystem +import java.nio.file.FileSystems +import kotlin.test.BeforeTest +import kotlin.test.Test + +// Only one runner can be configured with jUnit 4. We had to replace the SpringRunner by equivalent jUnit rules. +// See more on https://docs.spring.io/autorepo/docs/spring-framework/current/spring-framework-reference/testing.html#testcontext-junit4-rules +@RunWith(Parameterized::class) +class BlueprintsAcceptanceTest(@Suppress("unused") private val blueprintName: String, // readable test description + private val rootFs: FileSystem): BaseUatTest() { + + companion object { + + @ClassRule + @JvmField + val springClassRule = SpringClassRule() + + /** + * Generates the parameters to create a test instance for every blueprint found under UAT_BLUEPRINTS_BASE_DIR + * that contains the proper UAT definition file. + */ + @Parameterized.Parameters(name = "{index} {0}") + @JvmStatic + fun scanUatEmpoweredBlueprints(): List<Array<Any>> { + return (File(UAT_BLUEPRINTS_BASE_DIR) + .listFiles { file -> file.isDirectory && File(file, UAT_SPECIFICATION_FILE).isFile } + ?: throw RuntimeException("Failed to scan $UAT_BLUEPRINTS_BASE_DIR")) + .map { file -> + arrayOf( + file.nameWithoutExtension, + FileSystems.newFileSystem(file.canonicalFile.toPath(), null) + ) + } + } + } + + @Rule + @JvmField + val springMethodRule = SpringMethodRule() + + @Autowired + // Bean is created programmatically by {@link WorkingFoldersInitializer#initialize(String)} + @Suppress("SpringJavaInjectionPointsAutowiringInspection") + lateinit var tempFolder: ExtendedTemporaryFolder + + @Autowired + lateinit var uatExecutor: UatExecutor + + @BeforeTest + fun cleanupTemporaryFolder() { + tempFolder.deleteAllFiles() + } + + @Test + fun runUat() { + val uatSpec = rootFs.getPath(UAT_SPECIFICATION_FILE).toFile().readText() + val cbaBytes = compressToBytes(rootFs.getPath("/")) + uatExecutor.execute(uatSpec, cbaBytes) + } +}
\ No newline at end of file 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/uat/ExtendedTemporaryFolder.kt index 57b4573ef..1c0067c36 100644 --- 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/uat/ExtendedTemporaryFolder.kt @@ -17,9 +17,8 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat -import org.junit.rules.TemporaryFolder import java.io.File import java.io.IOException import java.nio.file.* @@ -27,25 +26,27 @@ import java.nio.file.attribute.* import javax.annotation.PreDestroy class ExtendedTemporaryFolder { - private val tempFolder = TemporaryFolder() - - init { - tempFolder.create() - } + private val tempFolder = createTempDir("uat") @PreDestroy - fun delete() = tempFolder.delete() + fun delete() = tempFolder.deleteRecursively() /** * A delegate to org.junit.rules.TemporaryFolder.TemporaryFolder.newFolder(String). */ - fun newFolder(folder: String): File = tempFolder.newFolder(folder) + fun newFolder(folderName: String): File { + val dir = File(tempFolder, folderName) + if (!dir.mkdir()) { + throw IOException("Unable to create temporary directory $dir.") + } + return dir + } /** * Delete all files under the root temporary folder recursively. The folders are preserved. */ fun deleteAllFiles() { - Files.walkFileTree(tempFolder.root.toPath(), object : SimpleFileVisitor<Path>() { + Files.walkFileTree(tempFolder.toPath(), object : SimpleFileVisitor<Path>() { @Throws(IOException::class) override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult { file?.toFile()?.delete() diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/MarkedSlf4jNotifier.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/MarkedSlf4jNotifier.kt new file mode 100644 index 000000000..13ebd9e4b --- /dev/null +++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/MarkedSlf4jNotifier.kt @@ -0,0 +1,43 @@ +/*- + * ============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.uat + +import com.github.tomakehurst.wiremock.common.Notifier +import org.slf4j.LoggerFactory +import org.slf4j.Marker + +class MarkedSlf4jNotifier(private val marker: Marker) : Notifier { + + override fun info(message: String) { + log.info(marker, message) + } + + override fun error(message: String) { + log.error(marker, message) + } + + override fun error(message: String, t: Throwable) { + log.error(marker, message, t) + } + + companion object { + private val log = LoggerFactory.getLogger("uat.WireMock") + } +} 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/uat/TestSecuritySettings.kt index f7ab2554c..216df9aef 100644 --- 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/uat/TestSecuritySettings.kt @@ -17,13 +17,12 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat 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 { @@ -31,7 +30,7 @@ class TestSecuritySettings { private const val authPassword = "Heisenberg" fun clientAuthToken() = - "Basic " + Base64Utils.encodeToString("$authUsername:$authPassword".toByteArray(StandardCharsets.UTF_8)) + "Basic " + Base64Utils.encodeToString("$authUsername:$authPassword".toByteArray()) } class ServerContextInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> { diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatServicesTest.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatServicesTest.kt new file mode 100644 index 000000000..78dc7099c --- /dev/null +++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/UatServicesTest.kt @@ -0,0 +1,260 @@ +/*- + * ============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.uat + +import com.fasterxml.jackson.databind.ObjectMapper +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.MappingBuilder +import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder +import com.github.tomakehurst.wiremock.client.VerificationException +import com.github.tomakehurst.wiremock.client.WireMock.aResponse +import com.github.tomakehurst.wiremock.client.WireMock.equalTo +import com.github.tomakehurst.wiremock.client.WireMock.equalToJson +import com.github.tomakehurst.wiremock.client.WireMock.request +import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo +import com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig +import org.apache.http.HttpStatus +import org.apache.http.client.methods.HttpPost +import org.apache.http.entity.ContentType +import org.apache.http.entity.mime.HttpMultipartMode +import org.apache.http.entity.mime.MultipartEntityBuilder +import org.apache.http.impl.client.CloseableHttpClient +import org.apache.http.impl.client.HttpClientBuilder +import org.apache.http.message.BasicHeader +import org.hamcrest.CoreMatchers +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalToIgnoringCase +import org.jetbrains.kotlin.konan.util.prefixIfNot +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.COLOR_WIREMOCK +import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.markerOf +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.UAT_SPECIFICATION_FILE +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintArchiveUtils.Companion.compressToBytes +import org.skyscreamer.jsonassert.JSONAssert +import org.skyscreamer.jsonassert.JSONCompareMode +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.web.server.LocalServerPort +import org.springframework.core.env.ConfigurableEnvironment +import org.springframework.core.env.MapPropertySource +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.support.TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME +import org.yaml.snakeyaml.Yaml +import java.nio.file.Paths +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertNotNull + +@ActiveProfiles("uat") +@Suppress("MemberVisibilityCanBePrivate") +class UatServicesTest : BaseUatTest() { + + companion object { + private const val BLUEPRINT_NAME = "pnf_config" + private val BLUEPRINT_BASE_DIR = Paths.get(UAT_BLUEPRINTS_BASE_DIR, BLUEPRINT_NAME) + private val UAT_PATH = BLUEPRINT_BASE_DIR.resolve(UAT_SPECIFICATION_FILE) + private val wireMockMarker = markerOf(COLOR_WIREMOCK) + } + + @Autowired + lateinit var mapper: ObjectMapper + + @Autowired + lateinit var environment: ConfigurableEnvironment + + private val ephemeralProperties = mutableSetOf<String>() + private val startedMockServers = mutableListOf<WireMockServer>() + + private fun setProperties(properties: Map<String, String>) { + inlinedPropertySource().putAll(properties) + ephemeralProperties += properties.keys + } + + @AfterTest + fun resetProperties() { + val source = inlinedPropertySource() + ephemeralProperties.forEach { key -> source.remove(key) } + ephemeralProperties.clear() + } + + @AfterTest + fun stopMockServers() { + startedMockServers.forEach { mockServer -> + try { + mockServer.checkForUnmatchedRequests() + } finally { + mockServer.stop() + } + } + startedMockServers.clear() + } + + private fun inlinedPropertySource(): MutableMap<String, Any> = + (environment.propertySources[INLINED_PROPERTIES_PROPERTY_SOURCE_NAME] as MapPropertySource).source + + @LocalServerPort + var localServerPort: Int = 0 + + // use lazy evaluation to postpone until localServerPort is injected by Spring + val baseUrl: String by lazy { + "http://127.0.0.1:$localServerPort" + } + + lateinit var httpClient: CloseableHttpClient + + @BeforeTest + fun setupHttpClient() { + val defaultHeaders = listOf(BasicHeader(org.apache.http.HttpHeaders.AUTHORIZATION, + TestSecuritySettings.clientAuthToken())) + httpClient = HttpClientBuilder.create() + .setDefaultHeaders(defaultHeaders) + .build() + } + + @Test + fun `verify service validates candidate UAT`() { + // GIVEN + val cbaBytes = compressToBytes(BLUEPRINT_BASE_DIR) + val multipartEntity = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("cba", cbaBytes, ContentType.DEFAULT_BINARY, "cba.zip") + .build() + val request = HttpPost("$baseUrl/api/v1/uat/verify").apply { + entity = multipartEntity + } + + // WHEN + httpClient.execute(request) { response -> + + // THEN + val statusLine = response.statusLine + assertThat(statusLine.statusCode, CoreMatchers.equalTo(HttpStatus.SC_OK)) + } + } + + @Test + fun `spy service generates complete UAT from bare UAT`() { + // GIVEN + val uatSpec = UAT_PATH.toFile().readText() + val fullUat = UatDefinition.load(mapper, uatSpec) + val expectedJson = mapper.writeValueAsString(fullUat) + + val bareUatBytes = fullUat.toBare().dump(mapper).toByteArray() + + fullUat.externalServices.forEach { service -> + val mockServer = createMockServer(service) + mockServer.start() + startedMockServers += mockServer + setPropertiesForMockServer(service, mockServer) + } + + val cbaBytes = compressToBytes(BLUEPRINT_BASE_DIR) + val multipartEntity = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("cba", cbaBytes, ContentType.DEFAULT_BINARY, "cba.zip") + .addBinaryBody("uat", bareUatBytes, ContentType.DEFAULT_BINARY, "uat.yaml") + .build() + val request = HttpPost("$baseUrl/api/v1/uat/spy").apply { + entity = multipartEntity + } + + // WHEN + httpClient.execute(request) { response -> + + // THEN + val statusLine = response.statusLine + assertThat(statusLine.statusCode, CoreMatchers.equalTo(HttpStatus.SC_OK)) + val entity = response.entity + assertNotNull(entity) + val contentType = ContentType.get(entity) + assertThat(contentType.mimeType, equalToIgnoringCase("text/vnd.yaml")) + val yamlResponse = entity.content.bufferedReader().readText() + val jsonResponse = yamlToJson(yamlResponse) + JSONAssert.assertEquals(expectedJson, jsonResponse, JSONCompareMode.LENIENT) + } + } + + private fun createMockServer(service: ServiceDefinition): WireMockServer { + val mockServer = WireMockServer(wireMockConfig() + .dynamicPort() + .notifier(MarkedSlf4jNotifier(wireMockMarker)) + ) + service.expectations.forEach { expectation -> + + val request = expectation.request + val response = expectation.response + // WebTestClient always use absolute path, prefixing with "/" if necessary + val urlPattern = urlEqualTo(request.path.prefixIfNot("/")) + val mappingBuilder: MappingBuilder = request(request.method, urlPattern) + request.headers.forEach { (key, value) -> + mappingBuilder.withHeader(key, equalTo(value)) + } + if (request.body != null) { + mappingBuilder.withRequestBody(equalToJson(mapper.writeValueAsString(request.body), true, true)) + } + + val responseDefinitionBuilder: ResponseDefinitionBuilder = aResponse() + .withStatus(response.status) + if (response.body != null) { + responseDefinitionBuilder.withBody(mapper.writeValueAsBytes(response.body)) + .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + } + + mappingBuilder.willReturn(responseDefinitionBuilder) + + mockServer.stubFor(mappingBuilder) + } + return mockServer + } + + private fun setPropertiesForMockServer(service: ServiceDefinition, mockServer: WireMockServer) { + val selector = service.selector + val httpPort = mockServer.port() + val properties = mapOf( + "blueprintsprocessor.restclient.$selector.type" to "basic-auth", + "blueprintsprocessor.restclient.$selector.url" to "http://localhost:$httpPort/", + // TODO credentials should be validated + "blueprintsprocessor.restclient.$selector.username" to "admin", + "blueprintsprocessor.restclient.$selector.password" to "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U" + ) + setProperties(properties) + } + + /** + * Borrowed from com.github.tomakehurst.wiremock.junit.WireMockRule.checkForUnmatchedRequests + */ + private fun WireMockServer.checkForUnmatchedRequests() { + val unmatchedRequests = findAllUnmatchedRequests() + if (unmatchedRequests.isNotEmpty()) { + val nearMisses = findNearMissesForAllUnmatchedRequests() + if (nearMisses.isEmpty()) { + throw VerificationException.forUnmatchedRequests(unmatchedRequests) + } else { + throw VerificationException.forUnmatchedNearMisses(nearMisses) + } + } + } + + private fun yamlToJson(yaml: String): String { + val map: Map<String, Any> = Yaml().load(yaml) + return mapper.writeValueAsString(map) + } +}
\ No newline at end of file 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/uat/WorkingFoldersInitializer.kt index 37615cb1a..ab9ae31a0 100644 --- 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/uat/WorkingFoldersInitializer.kt @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.cds.blueprintsprocessor +package org.onap.ccsdk.cds.blueprintsprocessor.uat import org.springframework.beans.factory.support.BeanDefinitionBuilder import org.springframework.beans.factory.support.BeanDefinitionRegistry diff --git a/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml index 70d94f5a7..f635e7925 100644 --- a/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml +++ b/ms/blueprintsprocessor/application/src/test/resources/logback-test.xml @@ -16,10 +16,17 @@ --> <configuration> - <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>%d{HH:mm:ss.SSS} %-5level %-40.40logger{39} : %msg%n</pattern> - </encoder> + <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"> + <discriminator class="org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.SmartColorDiscriminator"> + <defaultValue>white</defaultValue> + </discriminator> + <sift> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%${color}(%d{HH:mm:ss.SSS} %-5level %-40.40logger{39} : %msg%n)</pattern> + </encoder> + </appender> + </sift> </appender> <logger name="org.springframework.web.HttpLogging" level="trace"/> @@ -34,8 +41,11 @@ <logger name="org.hibernate.SQL" level="debug"/> <logger name="org.hibernate.type.descriptor.sql" level="trace"/> + <logger name="org.apache.http" level="debug"/> + <logger name="org.apache.http.wire" level="error"/> + <root level="info"> - <appender-ref ref="STDOUT"/> + <appender-ref ref="SIFT"/> </root> </configuration> diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt index 2a227ebe1..6b1f186c9 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt @@ -46,6 +46,7 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic const val INPUT_PACKAGES = "packages" const val DEFAULT_SELECTOR = "remote-python" + const val ATTRIBUTE_EXEC_CMD_STATUS = "status" const val ATTRIBUTE_PREPARE_ENV_LOG = "prepare-environment-logs" const val ATTRIBUTE_EXEC_CMD_LOG = "execute-command-logs" const val ATTRIBUTE_RESPONSE_DATA = "response-data" @@ -53,7 +54,7 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic override suspend fun processNB(executionRequest: ExecutionServiceInput) { - log.info("Processing : $operationInputs") + log.debug("Processing : $operationInputs") val bluePrintContext = bluePrintRuntimeService.bluePrintContext() val blueprintName = bluePrintContext.name() @@ -109,12 +110,17 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic ) val prepareEnvOutput = remoteScriptExecutionService.prepareEnv(prepareEnvInput) log.info("$ATTRIBUTE_PREPARE_ENV_LOG - ${prepareEnvOutput.response}") - setAttribute(ATTRIBUTE_PREPARE_ENV_LOG, JacksonUtils.jsonNodeFromObject(prepareEnvOutput.response)) + val logs = JacksonUtils.jsonNodeFromObject(prepareEnvOutput.response) + setAttribute(ATTRIBUTE_PREPARE_ENV_LOG, logs) setAttribute(ATTRIBUTE_EXEC_CMD_LOG, "N/A".asJsonPrimitive()) - check(prepareEnvOutput.status == StatusType.SUCCESS) { - "failed to get prepare remote env response status for requestId(${prepareEnvInput.requestId})" + + if (prepareEnvOutput.status != StatusType.SUCCESS) { + setNodeOutputErrors(prepareEnvOutput.status.name, logs) + } else { + setNodeOutputProperties(prepareEnvOutput.status.name.asJsonPrimitive(), logs, "".asJsonPrimitive()) } } + // Populate command execution properties and pass it to the remote server val properties = dynamicProperties?.returnNullIfMissing()?.rootFieldsToMap() ?: hashMapOf() @@ -124,10 +130,13 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic command = scriptCommand, properties = properties) val remoteExecutionOutput = remoteScriptExecutionService.executeCommand(remoteExecutionInput) - log.info("$ATTRIBUTE_EXEC_CMD_LOG - ${remoteExecutionOutput.response}") - setAttribute(ATTRIBUTE_EXEC_CMD_LOG, JacksonUtils.jsonNodeFromObject(remoteExecutionOutput.response)) - check(remoteExecutionOutput.status == StatusType.SUCCESS) { - "failed to get prepare remote command response status for requestId(${remoteExecutionOutput.requestId})" + + val logs = JacksonUtils.jsonNodeFromObject(remoteExecutionOutput.response) + if (remoteExecutionOutput.status != StatusType.SUCCESS) { + setNodeOutputErrors(remoteExecutionOutput.status.name,logs, remoteExecutionOutput.payload) + } else { + setNodeOutputProperties(remoteExecutionOutput.status.name.asJsonPrimitive(), logs, + remoteExecutionOutput.payload) } } catch (e: Exception) { @@ -139,7 +148,7 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { bluePrintRuntimeService.getBluePrintError() - .addError("Failed in ComponentJythonExecutor : ${runtimeException.message}") + .addError("Failed in ComponentRemotePythonExecutor : ${runtimeException.message}") } private fun formatNestedJsonNode(node: JsonNode): String { @@ -151,4 +160,27 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic } return sb.toString() } + + /** + * Utility function to set the output properties of the executor node + */ + private fun setNodeOutputProperties(status: JsonNode, message: JsonNode, artifacts: JsonNode) { + setAttribute(ATTRIBUTE_EXEC_CMD_STATUS, status) + log.info("Executor status : $status") + setAttribute(ATTRIBUTE_RESPONSE_DATA, artifacts) + log.info("Executor artifacts: $artifacts") + setAttribute(ATTRIBUTE_EXEC_CMD_LOG, message) + log.info("Executor message : $message") + } + + /** + * Utility function to set the output properties and errors of the executor node, in cas of errors + */ + private fun setNodeOutputErrors(status: String, message: JsonNode, artifacts: JsonNode = "".asJsonPrimitive() ) { + setAttribute(ATTRIBUTE_EXEC_CMD_STATUS, status.asJsonPrimitive()) + setAttribute(ATTRIBUTE_EXEC_CMD_LOG, message) + setAttribute(ATTRIBUTE_RESPONSE_DATA, artifacts) + + addError(status, ATTRIBUTE_EXEC_CMD_LOG, message.asText()) + } } diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt index d103bbf08..89af42579 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt @@ -194,6 +194,7 @@ class MockRemoteScriptExecutionService : RemoteScriptExecutionService { assertNotNull(prepareEnvInput.packages, "failed to get packages") val remoteScriptExecutionOutput = mockk<RemoteScriptExecutionOutput>() + every { remoteScriptExecutionOutput.payload } returns "payload".asJsonPrimitive() every { remoteScriptExecutionOutput.response } returns listOf("prepared successfully") every { remoteScriptExecutionOutput.status } returns StatusType.SUCCESS return remoteScriptExecutionOutput @@ -203,6 +204,7 @@ class MockRemoteScriptExecutionService : RemoteScriptExecutionService { assertEquals(remoteExecutionInput.requestId, "123456-1000", "failed to match request id") val remoteScriptExecutionOutput = mockk<RemoteScriptExecutionOutput>() + every { remoteScriptExecutionOutput.payload } returns "payload".asJsonPrimitive() every { remoteScriptExecutionOutput.response } returns listOf("processed successfully") every { remoteScriptExecutionOutput.status } returns StatusType.SUCCESS return remoteScriptExecutionOutput diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml index 5945e29fd..15cabb260 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ~ Copyright © 2019 IBM. + ~ Modifications Copyright © 2018-2019 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. @@ -42,5 +43,9 @@ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>processor-core</artifactId> </dependency> + <dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-testing</artifactId> + </dependency> </dependencies> </project> diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcExtensions.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcExtensions.kt new file mode 100644 index 000000000..55cf0941d --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcExtensions.kt @@ -0,0 +1,27 @@ +/* + * Copyright © 2018-2019 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.grpc + +import io.grpc.Metadata + +fun Metadata.getStringKey(key: String): String? { + return this.get(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER)) +} + +fun Metadata.putStringKeyValue(key: String, value: String) { + this.put(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER), value) +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt index 1bef3a0f2..0ec049a3c 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -16,6 +17,10 @@ package org.onap.ccsdk.cds.blueprintsprocessor.grpc +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcClientService +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcLibPropertyService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration @@ -23,10 +28,25 @@ import org.springframework.context.annotation.Configuration @ComponentScan open class BluePrintGrpcLibConfiguration +/** + * Exposed Dependency Service by this GRPC Lib Module + */ +fun BluePrintDependencyService.grpcLibPropertyService(): BluePrintGrpcLibPropertyService = + instance(GRPCLibConstants.SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY) + +fun BluePrintDependencyService.grpcClientService(selector: String): BluePrintGrpcClientService { + return grpcLibPropertyService().blueprintGrpcClientService(selector) +} + +fun BluePrintDependencyService.grpcClientService(jsonNode: JsonNode): BluePrintGrpcClientService { + return grpcLibPropertyService().blueprintGrpcClientService(jsonNode) +} + class GRPCLibConstants { companion object { const val SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY = "blueprint-grpc-lib-property-service" const val TYPE_TOKEN_AUTH = "token-auth" const val TYPE_BASIC_AUTH = "basic-auth" + const val TYPE_TLS_AUTH = "tls-auth" } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt index 76e60bd0d..47d16fbc7 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -16,6 +17,24 @@ package org.onap.ccsdk.cds.blueprintsprocessor.grpc +/** GRPC Server Properties */ +open class GrpcServerProperties { + lateinit var type: String + var port: Int = -1 +} + +open class TokenAuthGrpcServerProperties : GrpcServerProperties() { + lateinit var token: String +} + +open class TLSAuthGrpcServerProperties : GrpcServerProperties() { + lateinit var certChain: String + lateinit var privateKey: String + /** Below Used only for Mutual TLS */ + var trustCertCollection: String? = null +} + +/** GRPC Client Properties */ open class GrpcClientProperties { lateinit var type: String lateinit var host: String @@ -26,6 +45,13 @@ open class TokenAuthGrpcClientProperties : GrpcClientProperties() { lateinit var token: String } +open class TLSAuthGrpcClientProperties : GrpcClientProperties() { + var trustCertCollection: String? = null + /** Below Used only for Mutual TLS */ + var clientCertChain: String? = null + var clientPrivateKey: String? = null +} + open class BasicAuthGrpcClientProperties : GrpcClientProperties() { lateinit var username: String lateinit var password: String diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/interceptor/GrpcClientLoggingInterceptor.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/interceptor/GrpcClientLoggingInterceptor.kt new file mode 100644 index 000000000..f3b14b59f --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/interceptor/GrpcClientLoggingInterceptor.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2018-2019 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.grpc.interceptor + +import io.grpc.* +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.GrpcLoggerService +import org.onap.ccsdk.cds.controllerblueprints.core.logger + + +class GrpcClientLoggingInterceptor : ClientInterceptor { + val log = logger(GrpcClientLoggingInterceptor::class) + + val loggingService = GrpcLoggerService() + + override fun <ReqT, RespT> interceptCall(method: MethodDescriptor<ReqT, RespT>, + callOptions: CallOptions, channel: Channel): ClientCall<ReqT, RespT> { + + return object : ForwardingClientCall + .SimpleForwardingClientCall<ReqT, RespT>(channel.newCall(method, callOptions)) { + + override fun start(responseListener: Listener<RespT>, headers: Metadata) { + val listener = object : ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) { + override fun onMessage(message: RespT) { + loggingService.grpcInvoking(headers) + super.onMessage(message) + } + } + super.start(listener, headers) + } + } + + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/interceptor/GrpcServerLoggingInterceptor.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/interceptor/GrpcServerLoggingInterceptor.kt new file mode 100644 index 000000000..e21d5d3ce --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/interceptor/GrpcServerLoggingInterceptor.kt @@ -0,0 +1,92 @@ +/* + * Copyright © 2018-2019 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.grpc.interceptor + +import io.grpc.* +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.GrpcLoggerService +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintDownloadInput +import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintRemoveInput +import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput +import org.slf4j.MDC + +class GrpcServerLoggingInterceptor : ServerInterceptor { + val log = logger(GrpcServerLoggingInterceptor::class) + val loggingService = GrpcLoggerService() + + override fun <ReqT : Any, RespT : Any> interceptCall(call: ServerCall<ReqT, RespT>, + requestHeaders: Metadata, next: ServerCallHandler<ReqT, RespT>) + : ServerCall.Listener<ReqT> { + + val forwardingServerCall = object : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) { + override fun sendHeaders(responseHeaders: Metadata) { + loggingService.grpResponding(requestHeaders, responseHeaders) + super.sendHeaders(responseHeaders) + } + } + + return object + : ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>( + next.startCall(forwardingServerCall, requestHeaders)) { + + override fun onMessage(message: ReqT) { + /** Get the requestId, SubRequestId and Originator Id and set in MDS context + * If you are using other GRPC services, Implement own Logging Interceptors to get tracing. + * */ + when (message) { + is ExecutionServiceInput -> { + val commonHeader = message.commonHeader + ?: throw BluePrintProcessorException("missing common header in request") + loggingService.grpcRequesting(call, commonHeader, next) + } + is BluePrintUploadInput -> { + val commonHeader = message.commonHeader + ?: throw BluePrintProcessorException("missing common header in request") + loggingService.grpcRequesting(call, commonHeader, next) + } + is BluePrintDownloadInput -> { + val commonHeader = message.commonHeader + ?: throw BluePrintProcessorException("missing common header in request") + loggingService.grpcRequesting(call, commonHeader, next) + } + is BluePrintRemoveInput -> { + val commonHeader = message.commonHeader + ?: throw BluePrintProcessorException("missing common header in request") + loggingService.grpcRequesting(call, commonHeader, next) + } + else -> { + loggingService.grpcRequesting(call, requestHeaders, next) + } + } + super.onMessage(message) + } + + override fun onComplete() { + MDC.clear() + super.onComplete() + } + + override fun onCancel() { + MDC.clear() + super.onCancel() + } + + } + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt index a1d2188ab..f4933a3ad 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -18,17 +19,56 @@ package org.onap.ccsdk.cds.blueprintsprocessor.grpc.service import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BasicAuthGrpcClientProperties -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GrpcClientProperties -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.* import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.returnNullIfMissing import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.springframework.stereotype.Service @Service(GRPCLibConstants.SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY) open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: BluePrintProperties) { + /** GRPC Server Lib Property Service */ + fun grpcServerProperties(jsonNode: JsonNode): GrpcServerProperties { + return when (val type = jsonNode.get("type").textValue()) { + GRPCLibConstants.TYPE_TOKEN_AUTH -> { + JacksonUtils.readValue(jsonNode, TokenAuthGrpcServerProperties::class.java)!! + } + GRPCLibConstants.TYPE_TLS_AUTH -> { + JacksonUtils.readValue(jsonNode, TLSAuthGrpcServerProperties::class.java)!! + } + else -> { + throw BluePrintProcessorException("Grpc type($type) not supported") + } + } + } + + fun grpcServerProperties(prefix: String): GrpcServerProperties { + val type = bluePrintProperties.propertyBeanType( + "$prefix.type", String::class.java) + return when (type) { + GRPCLibConstants.TYPE_TOKEN_AUTH -> { + tokenAuthGrpcServerProperties(prefix) + } + GRPCLibConstants.TYPE_TLS_AUTH -> { + tlsAuthGrpcServerProperties(prefix) + } + else -> { + throw BluePrintProcessorException("Grpc type($type) not supported") + } + } + } + + private fun tokenAuthGrpcServerProperties(prefix: String): TokenAuthGrpcServerProperties { + return bluePrintProperties.propertyBeanType(prefix, TokenAuthGrpcServerProperties::class.java) + } + + private fun tlsAuthGrpcServerProperties(prefix: String): TLSAuthGrpcServerProperties { + return bluePrintProperties.propertyBeanType(prefix, TLSAuthGrpcServerProperties::class.java) + } + + /** GRPC Client Lib Property Service */ + fun blueprintGrpcClientService(jsonNode: JsonNode): BluePrintGrpcClientService { val restClientProperties = grpcClientProperties(jsonNode) return blueprintGrpcClientService(restClientProperties) @@ -42,11 +82,15 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue fun grpcClientProperties(jsonNode: JsonNode): GrpcClientProperties { - val type = jsonNode.get("type").textValue() + val type = jsonNode.get("type").returnNullIfMissing()?.textValue() + ?: BluePrintProcessorException("missing type property") return when (type) { GRPCLibConstants.TYPE_TOKEN_AUTH -> { JacksonUtils.readValue(jsonNode, TokenAuthGrpcClientProperties::class.java)!! } + GRPCLibConstants.TYPE_TLS_AUTH -> { + JacksonUtils.readValue(jsonNode, TLSAuthGrpcClientProperties::class.java)!! + } GRPCLibConstants.TYPE_BASIC_AUTH -> { JacksonUtils.readValue(jsonNode, BasicAuthGrpcClientProperties::class.java)!! } @@ -63,6 +107,9 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue GRPCLibConstants.TYPE_TOKEN_AUTH -> { tokenAuthGrpcClientProperties(prefix) } + GRPCLibConstants.TYPE_TLS_AUTH -> { + tlsAuthGrpcClientProperties(prefix) + } GRPCLibConstants.TYPE_BASIC_AUTH -> { basicAuthGrpcClientProperties(prefix) } @@ -75,12 +122,15 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue fun blueprintGrpcClientService(grpcClientProperties: GrpcClientProperties): BluePrintGrpcClientService { - when (grpcClientProperties) { + return when (grpcClientProperties) { is TokenAuthGrpcClientProperties -> { - return TokenAuthGrpcClientService(grpcClientProperties) + TokenAuthGrpcClientService(grpcClientProperties) + } + is TLSAuthGrpcClientProperties -> { + TLSAuthGrpcClientService(grpcClientProperties) } is BasicAuthGrpcClientProperties -> { - return BasicAuthGrpcClientService(grpcClientProperties) + BasicAuthGrpcClientService(grpcClientProperties) } else -> { throw BluePrintProcessorException("couldn't get grpc service for type(${grpcClientProperties.type})") @@ -92,6 +142,10 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue return bluePrintProperties.propertyBeanType(prefix, TokenAuthGrpcClientProperties::class.java) } + private fun tlsAuthGrpcClientProperties(prefix: String): TLSAuthGrpcClientProperties { + return bluePrintProperties.propertyBeanType(prefix, TLSAuthGrpcClientProperties::class.java) + } + private fun basicAuthGrpcClientProperties(prefix: String): BasicAuthGrpcClientProperties { return bluePrintProperties.propertyBeanType(prefix, BasicAuthGrpcClientProperties::class.java) } diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcService.kt index 016c05035..0d9291615 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcService.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -17,6 +18,11 @@ package org.onap.ccsdk.cds.blueprintsprocessor.grpc.service import io.grpc.ManagedChannel +import io.grpc.netty.NettyServerBuilder + +interface BluePrintGrpcServerService { + fun serverBuilder(): NettyServerBuilder +} interface BluePrintGrpcClientService { suspend fun channel(): ManagedChannel diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/GrpcLoggerService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/GrpcLoggerService.kt new file mode 100644 index 000000000..6d2ba43cc --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/GrpcLoggerService.kt @@ -0,0 +1,101 @@ +/* + * Copyright © 2018-2019 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.grpc.service + +import io.grpc.Grpc +import io.grpc.Metadata +import io.grpc.ServerCall +import io.grpc.ServerCallHandler +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.getStringKey +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.putStringKeyValue +import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_INVOCATION_ID +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_PARTNER_NAME +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_REQUEST_ID +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToUUID +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.slf4j.MDC +import java.net.InetAddress +import java.net.InetSocketAddress +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.util.* + +class GrpcLoggerService { + + private val log = logger(GrpcLoggerService::class) + + /** Used when server receives request */ + fun <ReqT : Any, RespT : Any> grpcRequesting(call: ServerCall<ReqT, RespT>, + headers: Metadata, next: ServerCallHandler<ReqT, RespT>) { + val requestID = headers.getStringKey(ONAP_REQUEST_ID).defaultToUUID() + val invocationID = headers.getStringKey(ONAP_INVOCATION_ID).defaultToUUID() + val partnerName = headers.getStringKey(ONAP_PARTNER_NAME) ?: "UNKNOWN" + grpcRequesting(requestID, invocationID, partnerName, call) + } + + fun <ReqT : Any, RespT : Any> grpcRequesting(call: ServerCall<ReqT, RespT>, + headers: CommonHeader, next: ServerCallHandler<ReqT, RespT>) { + val requestID = headers.requestId.defaultToUUID() + val invocationID = headers.subRequestId.defaultToUUID() + val partnerName = headers.originatorId ?: "UNKNOWN" + grpcRequesting(requestID, invocationID, partnerName, call) + } + + fun <ReqT : Any, RespT : Any> grpcRequesting(requestID: String, invocationID: String, partnerName: String, + call: ServerCall<ReqT, RespT>) { + val localhost = InetAddress.getLocalHost() + + val clientSocketAddress = call.attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR) as? InetSocketAddress + ?: throw BluePrintProcessorException("failed to get client address") + val serviceName = call.methodDescriptor.fullMethodName + + MDC.put("InvokeTimestamp", ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT)) + MDC.put("RequestID", requestID) + MDC.put("InvocationID", invocationID) + MDC.put("PartnerName", partnerName) + MDC.put("ClientIPAddress", clientSocketAddress.address.defaultToEmpty()) + MDC.put("ServerFQDN", localhost.hostName.defaultToEmpty()) + MDC.put("ServiceName", serviceName) + log.trace("MDC Properties : ${MDC.getCopyOfContextMap()}") + } + + + /** Used before invoking any GRPC outbound request, Inbound Invocation ID is used as request Id + * for outbound Request, If invocation Id is missing then default Request Id will be generated. + */ + fun grpcInvoking(requestHeader: Metadata) { + requestHeader.putStringKeyValue(ONAP_REQUEST_ID, MDC.get("InvocationID").defaultToUUID()) + requestHeader.putStringKeyValue(ONAP_INVOCATION_ID, UUID.randomUUID().toString()) + val partnerName = System.getProperty("APPNAME") ?: "BlueprintsProcessor" + requestHeader.putStringKeyValue(ONAP_PARTNER_NAME, partnerName) + } + + /** Used when server returns response */ + fun grpResponding(requestHeaders: Metadata, responseHeaders: Metadata) { + try { + responseHeaders.putStringKeyValue(ONAP_REQUEST_ID, MDC.get("RequestID").defaultToEmpty()) + responseHeaders.putStringKeyValue(ONAP_INVOCATION_ID, MDC.get("InvocationID").defaultToEmpty()) + responseHeaders.putStringKeyValue(ONAP_PARTNER_NAME, MDC.get("PartnerName").defaultToEmpty()) + } catch (e: Exception) { + log.warn("couldn't set grpc response headers", e) + } + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcClientService.kt new file mode 100644 index 000000000..a70cbbce0 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcClientService.kt @@ -0,0 +1,54 @@ +/* + * Copyright © 2018-2019 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.grpc.service + +import io.grpc.ManagedChannel +import io.grpc.internal.DnsNameResolverProvider +import io.grpc.internal.PickFirstLoadBalancerProvider +import io.grpc.netty.GrpcSslContexts +import io.grpc.netty.NettyChannelBuilder +import io.netty.handler.ssl.SslContext +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcClientLoggingInterceptor +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile + +class TLSAuthGrpcClientService(private val tlsAuthGrpcClientProperties: TLSAuthGrpcClientProperties) + : BluePrintGrpcClientService { + + override suspend fun channel(): ManagedChannel { + return NettyChannelBuilder + .forAddress(tlsAuthGrpcClientProperties.host, tlsAuthGrpcClientProperties.port) + .nameResolverFactory(DnsNameResolverProvider()) + .loadBalancerFactory(PickFirstLoadBalancerProvider()) + .intercept(GrpcClientLoggingInterceptor()) + .sslContext(sslContext()) + .build() + } + + fun sslContext(): SslContext { + val builder = GrpcSslContexts.forClient() + if (tlsAuthGrpcClientProperties.trustCertCollection != null) { + builder.trustManager(normalizedFile(tlsAuthGrpcClientProperties.trustCertCollection!!)) + } + if (tlsAuthGrpcClientProperties.clientCertChain != null + && tlsAuthGrpcClientProperties.clientPrivateKey != null) { + builder.keyManager(normalizedFile(tlsAuthGrpcClientProperties.clientCertChain!!), + normalizedFile(tlsAuthGrpcClientProperties.clientPrivateKey!!)) + } + return builder.build() + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcServerService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcServerService.kt new file mode 100644 index 000000000..fc73d43f9 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TLSAuthGrpcServerService.kt @@ -0,0 +1,49 @@ +/* + * Copyright © 2018-2019 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.grpc.service + +import io.grpc.netty.GrpcSslContexts +import io.grpc.netty.NettyServerBuilder +import io.netty.handler.ssl.ClientAuth +import io.netty.handler.ssl.SslContext +import io.netty.handler.ssl.SslContextBuilder +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcServerProperties +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile + + +class TLSAuthGrpcServerService(private val tlsAuthGrpcServerProperties: TLSAuthGrpcServerProperties) + : BluePrintGrpcServerService { + + override fun serverBuilder(): NettyServerBuilder { + return NettyServerBuilder + .forPort(tlsAuthGrpcServerProperties.port) + .sslContext(sslContext()) + } + + fun sslContext(): SslContext { + val sslClientContextBuilder = SslContextBuilder + .forServer(normalizedFile(tlsAuthGrpcServerProperties.certChain), + normalizedFile(tlsAuthGrpcServerProperties.privateKey)) + + tlsAuthGrpcServerProperties.trustCertCollection?.let { trustCertFile -> + sslClientContextBuilder.trustManager(normalizedFile(trustCertFile)) + sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE) + } + return GrpcSslContexts.configure(sslClientContextBuilder).build() + } + +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt index dbff84211..601dc0e33 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt @@ -21,6 +21,7 @@ import io.grpc.internal.DnsNameResolverProvider import io.grpc.internal.PickFirstLoadBalancerProvider import io.grpc.netty.NettyChannelBuilder import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcClientLoggingInterceptor class TokenAuthGrpcClientService(private val tokenAuthGrpcClientProperties: TokenAuthGrpcClientProperties) : BluePrintGrpcClientService { @@ -30,6 +31,7 @@ class TokenAuthGrpcClientService(private val tokenAuthGrpcClientProperties: Toke .forAddress(tokenAuthGrpcClientProperties.host, tokenAuthGrpcClientProperties.port) .nameResolverFactory(DnsNameResolverProvider()) .loadBalancerFactory(PickFirstLoadBalancerProvider()) + .intercept(GrpcClientLoggingInterceptor()) .intercept(TokenAuthClientInterceptor(tokenAuthGrpcClientProperties)).usePlaintext().build() return managedChannel } diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyServiceTest.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyServiceTest.kt index 8df218fe9..b7ddc1569 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyServiceTest.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -22,9 +23,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BasicAuthGrpcClientProperties -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BluePrintGrpcLibConfiguration -import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.* +import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource @@ -42,11 +42,25 @@ import kotlin.test.assertTrue "blueprintsprocessor.grpcclient.sample.port=50505", "blueprintsprocessor.grpcclient.sample.username=sampleuser", "blueprintsprocessor.grpcclient.sample.password=sampleuser", + "blueprintsprocessor.grpcclient.token.type=token-auth", "blueprintsprocessor.grpcclient.token.host=127.0.0.1", "blueprintsprocessor.grpcclient.token.port=50505", "blueprintsprocessor.grpcclient.token.username=sampleuser", - "blueprintsprocessor.grpcclient.token.password=sampleuser" + "blueprintsprocessor.grpcclient.token.password=sampleuser", + + "blueprintsprocessor.grpcserver.tls-sample.type=tls-auth", + "blueprintsprocessor.grpcserver.tls-sample.port=50505", + "blueprintsprocessor.grpcserver.tls-sample.certChain=server1.pem", + "blueprintsprocessor.grpcserver.tls-sample.privateKey=server1.key", + "blueprintsprocessor.grpcserver.tls-sample.trustCertCollection=ca.pem", + + "blueprintsprocessor.grpcclient.tls-sample.type=tls-auth", + "blueprintsprocessor.grpcclient.tls-sample.host=127.0.0.1", + "blueprintsprocessor.grpcclient.tls-sample.port=50505", + "blueprintsprocessor.grpcclient.tls-sample.trustCertCollection=ca.pem", + "blueprintsprocessor.grpcclient.tls-sample.clientCertChain=client.pem", + "blueprintsprocessor.grpcclient.tls-sample.clientPrivateKey=client.key" ]) class BluePrintGrpcLibPropertyServiceTest { @@ -129,4 +143,52 @@ class BluePrintGrpcLibPropertyServiceTest { .blueprintGrpcClientService(actualObj) assertTrue(svc is BasicAuthGrpcClientService) } + + @Test + fun testGrpcClientTLSProperties() { + val properties = bluePrintGrpcLibPropertyService + .grpcClientProperties("blueprintsprocessor.grpcclient.tls-sample") as TLSAuthGrpcClientProperties + assertNotNull(properties, "failed to create property bean") + assertNotNull(properties.host, "failed to get host property in property bean") + assertNotNull(properties.port, "failed to get host property in property bean") + assertNotNull(properties.trustCertCollection, "failed to get trustCertCollection property in property bean") + assertNotNull(properties.clientCertChain, "failed to get clientCertChain property in property bean") + assertNotNull(properties.clientPrivateKey, "failed to get clientPrivateKey property in property bean") + + val configDsl = """{ + "type" : "tls-auth", + "host" : "localhost", + "port" : "50505", + "trustCertCollection" : "server1.pem", + "clientCertChain" : "server1.key", + "clientPrivateKey" : "ca.pem" + } + """.trimIndent() + val jsonProperties = bluePrintGrpcLibPropertyService + .grpcClientProperties(configDsl.jsonAsJsonType()) as TLSAuthGrpcClientProperties + assertNotNull(jsonProperties, "failed to create property bean from json") + } + + @Test + fun testGrpcServerTLSProperties() { + val properties = bluePrintGrpcLibPropertyService + .grpcServerProperties("blueprintsprocessor.grpcserver.tls-sample") as TLSAuthGrpcServerProperties + assertNotNull(properties, "failed to create property bean") + assertNotNull(properties.port, "failed to get host property in property bean") + assertNotNull(properties.trustCertCollection, "failed to get trustCertCollection property in property bean") + assertNotNull(properties.certChain, "failed to get certChain property in property bean") + assertNotNull(properties.privateKey, "failed to get privateKey property in property bean") + + val configDsl = """{ + "type" : "tls-auth", + "port" : "50505", + "certChain" : "server1.pem", + "privateKey" : "server1.key", + "trustCertCollection" : "ca.pem" + } + """.trimIndent() + val jsonProperties = bluePrintGrpcLibPropertyService + .grpcServerProperties(configDsl.jsonAsJsonType()) as TLSAuthGrpcServerProperties + assertNotNull(jsonProperties, "failed to create property bean from json") + } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcServerTest.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcServerTest.kt new file mode 100644 index 000000000..8154d3747 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcServerTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright © 2018-2019 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.grpc.service + +import com.github.marcoferrer.krotoplus.coroutines.client.clientCallBidiStreaming +import com.google.protobuf.util.JsonFormat +import kotlinx.coroutines.channels.consumeEach +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_SYNC +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcServerProperties +import org.onap.ccsdk.cds.controllerblueprints.common.api.ActionIdentifiers +import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader +import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType +import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput +import java.util.* +import kotlin.test.Test +import kotlin.test.assertNotNull + +class BluePrintGrpcServerTest { + + private val tlsAuthGrpcServerProperties = TLSAuthGrpcServerProperties().apply { + port = 50052 + type = GRPCLibConstants.TYPE_TLS_AUTH + certChain = "src/test/resources/tls-manual/py-executor-chain.pem" + privateKey = "src/test/resources/tls-manual/py-executor-key.pem" + } + + private val tlsAuthGrpcClientProperties = TLSAuthGrpcClientProperties().apply { + host = "localhost" + port = 50052 + type = GRPCLibConstants.TYPE_TLS_AUTH + trustCertCollection = "src/test/resources/tls-manual/py-executor-chain.pem" + } + + @Test + fun testGrpcTLSContext() { + val tlsAuthGrpcServerService = TLSAuthGrpcServerService(tlsAuthGrpcServerProperties) + val sslContext = tlsAuthGrpcServerService.sslContext() + assertNotNull(sslContext, "failed to create grpc server ssl context") + + val tlsAuthGrpcClientService = TLSAuthGrpcClientService(tlsAuthGrpcClientProperties) + val clientSslContext = tlsAuthGrpcClientService.sslContext() + assertNotNull(clientSslContext, "failed to create grpc client ssl context") + } + + /** TLS Client Integration testing, GRPC TLS Junit testing is not supported. */ + //@Test + fun testGrpcTLSServerIntegration() { + runBlocking { + val tlsAuthGrpcClientService = TLSAuthGrpcClientService(tlsAuthGrpcClientProperties) + val grpcChannel = tlsAuthGrpcClientService.channel() + /** Get Send and Receive Channel for bidirectional process method*/ + val (reqChannel, resChannel) = clientCallBidiStreaming(BluePrintProcessingServiceGrpc.getProcessMethod(), + grpcChannel) + launch { + resChannel.consumeEach { + log.info("Received Response") + if (it.status.eventType == EventType.EVENT_COMPONENT_EXECUTED) { + resChannel.cancel() + } + } + } + val request = getRequest("12345") + reqChannel.send(request) + } + } + + private fun getRequest(requestId: String): ExecutionServiceInput { + val commonHeader = CommonHeader.newBuilder() + .setTimestamp("2012-04-23T18:25:43.511Z") + .setOriginatorId("System") + .setRequestId(requestId) + .setSubRequestId("$requestId-" + UUID.randomUUID().toString()).build() + val actionIdentifier = ActionIdentifiers.newBuilder() + .setActionName("SampleScript") + .setBlueprintName("sample-cba") + .setBlueprintVersion("1.0.0") + .setMode(ACTION_MODE_SYNC) + .build() + val jsonContent = """{ "key1" : "value1" }""" + val payloadBuilder = ExecutionServiceInput.newBuilder().payloadBuilder + JsonFormat.parser().merge(jsonContent, payloadBuilder) + + return ExecutionServiceInput.newBuilder() + .setCommonHeader(commonHeader) + .setActionIdentifiers(actionIdentifier) + .setPayload(payloadBuilder.build()) + .build() + } + +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/MockTLSBluePrintProcessingServer.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/MockTLSBluePrintProcessingServer.kt new file mode 100644 index 000000000..d5bc70c48 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/MockTLSBluePrintProcessingServer.kt @@ -0,0 +1,90 @@ +/* + * Copyright © 2018-2019 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.grpc.service + +import io.grpc.stub.StreamObserver +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TLSAuthGrpcServerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcServerLoggingInterceptor +import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType +import org.onap.ccsdk.cds.controllerblueprints.common.api.Status +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput + + +val log = logger(MockTLSBluePrintProcessingServer::class) + +/** For Integration testing stat this server, Set the working path to run this method */ +fun main() { + try { + val tlsAuthGrpcServerProperties = TLSAuthGrpcServerProperties().apply { + port = 50052 + type = GRPCLibConstants.TYPE_TLS_AUTH + certChain = "src/test/resources/tls-manual/py-executor-chain.pem" + privateKey = "src/test/resources/tls-manual/py-executor-key.pem" + } + val server = TLSAuthGrpcServerService(tlsAuthGrpcServerProperties).serverBuilder() + .intercept(GrpcServerLoggingInterceptor()) + .addService(MockTLSBluePrintProcessingServer()) + .build() + server.start() + log.info("GRPC Serve started(${server.isShutdown}) on port(${server.port})...") + server.awaitTermination() + } catch (e: Exception) { + log.error("Failed to start tls grpc integration server", e) + } + +} + +class MockTLSBluePrintProcessingServer : BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase() { + override fun process(responseObserver: StreamObserver<ExecutionServiceOutput>): StreamObserver<ExecutionServiceInput> { + + return object : StreamObserver<ExecutionServiceInput> { + override fun onNext(executionServiceInput: ExecutionServiceInput) { + log.info("Received requestId(${executionServiceInput.commonHeader.requestId}) " + + "subRequestId(${executionServiceInput.commonHeader.subRequestId})") + responseObserver.onNext(buildResponse(executionServiceInput)) + responseObserver.onCompleted() + } + + override fun onError(error: Throwable) { + log.debug("Fail to process message", error) + responseObserver.onError(io.grpc.Status.INTERNAL + .withDescription(error.message) + .asException()) + } + + override fun onCompleted() { + log.info("Completed") + } + } + } + + private fun buildResponse(input: ExecutionServiceInput): ExecutionServiceOutput { + val status = Status.newBuilder().setCode(200) + .setEventType(EventType.EVENT_COMPONENT_EXECUTED) + .build() + return ExecutionServiceOutput.newBuilder() + .setCommonHeader(input.commonHeader) + .setActionIdentifiers(input.actionIdentifiers) + .setStatus(status) + .build() + + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/README b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/README new file mode 100644 index 000000000..c4e91a2fc --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/README @@ -0,0 +1,5 @@ + +Generate Certifactes & Keys +---------------------------- + +openssl req -x509 -newkey rsa:4096 -keyout my-private-key.pem -out my-public-key-cert.pem -days 3650 -nodes -subj '/CN=localhost' diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/py-executor-chain.pem b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/py-executor-chain.pem new file mode 100644 index 000000000..30f09dfea --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/py-executor-chain.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpDCCAowCCQDyhR+GR2RUiTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMTkxMDIzMDAwMTA0WhcNMjkxMDIwMDAwMTA0WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCs +c4d6qfbW+GSMp+XURoLXtSAbbehoBXL2beSzqQNW6e+Q9IVtSPZst8VRjUXelFzM +m7VpS9jhiXOPZ5KKUOD0GVuNQc54VpwtHt7t9L5wS9OvdnLijnMIkc0iUvC6+Rcq +HSfbNC2Tb+a8jLwojmtRCeY/MyCnmqYpD+U3b6Eue89VpMOIfmDuTqSRRBYNVO72 +hq7FI3UD8+zREg7htfzjJjG14Ec5iVMDxJA1FlwtXFnZxDHgbLjEVjTTR/9Wm1eU +aJ4oWRt3gG/vnJNa+GwN4w/My+j/5/n/YpNh6GeQrHxBl/SL/SAFBshlwozr4K4K +av5MqRKyhCACV4SsdhKJUEDtvrtukJvh/ZDW8jdNbFJAljm8UucZGbJrZl6G7XB3 +WteI7rezo0mL0NMBZIT3nQSMEpefKUFZFiE5lYvIk3UuChqIM0xdgV4INwLRHZdc +1TtiGaBJV05y3Klo5gaUgNGbHP26zfub5TydiMrOA5W2mUvMkG2oit9aqnbaZBLD +t17cCKzpzcVF5uNUng3j6sQvpTt3S4L28TvKUMAfpecQqvxMoxG0/9HZuv2z+U+L +LVVsS07yJPIGMLcq1LMM++8LwD1MupcoShjNOq/lUOL6hIMfLOIfxt8Kv8WykVzv +6yjKEIurjkwMipq4kvr9J7FFi54kGr7uvXWQRHDFJwIDAQABMA0GCSqGSIb3DQEB +CwUAA4ICAQB7gJzvaOIP3/S2jrObz67g0jiz1cfb4I9KQwpwb6JUWbYm1QjBcGm4 +IhNbdPMD6dpwBc/A4JctA5E+/fArvl14UtK1jkaaE/GCumL0VUSZeAM6CK/63brt +LplqCunv8ePHmiwjJBnhu+ewe1+mDMVDMw0iot/q+pOM3vqNS1Fipja+xFK1JQZx +JmkjW/Ug3NHk/SSTfO+VNmlI5bBBApMqKmd9picsyDZ7dTBtZvbqV5eQsPZvv14G +oEvWnvvom+D5GojroSO+OMHNDR3bzK6p0Cu8AiTy9Ls6J2e4GXJz3Cg/kuF9tNlR +3X62zDT+CUipuYyTvmjbSyNMGwU7BIZTKFPuTtjh7EwT2g6S8RV9PmT98CQW6kTT +RJbL7nMIOF0WusysAT5wj1HJ0QKBQCXK+L6WTKTTovaEE7JSVrYe7wVF8Q9SyBIM +4CPVZt+GMyQKJ9SRnVgTDEMb7sj9HPaoVeDc6LQTv8Q//wFeTdZIWXQhpVJCQCEG +qkRk9r3isF60ISOXXIYhqE+hx3QXY9M2UyHDtKXPZ7X370vADi2ebBMF8MpIZYl5 +628dME9JhOhLhD5qPJeva2Nq4gLpK+rO6t7ML0Us4edoKyoScowXAh80q1GW3EO3 +IxTK123651C/S0kDqLqZ9rknEdpwSujrT2UW95jUlfo5OKDrPpdOBw== +-----END CERTIFICATE----- diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/py-executor-key.pem b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/py-executor-key.pem new file mode 100644 index 000000000..830a3ae21 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/resources/tls-manual/py-executor-key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCsc4d6qfbW+GSM +p+XURoLXtSAbbehoBXL2beSzqQNW6e+Q9IVtSPZst8VRjUXelFzMm7VpS9jhiXOP +Z5KKUOD0GVuNQc54VpwtHt7t9L5wS9OvdnLijnMIkc0iUvC6+RcqHSfbNC2Tb+a8 +jLwojmtRCeY/MyCnmqYpD+U3b6Eue89VpMOIfmDuTqSRRBYNVO72hq7FI3UD8+zR +Eg7htfzjJjG14Ec5iVMDxJA1FlwtXFnZxDHgbLjEVjTTR/9Wm1eUaJ4oWRt3gG/v +nJNa+GwN4w/My+j/5/n/YpNh6GeQrHxBl/SL/SAFBshlwozr4K4Kav5MqRKyhCAC +V4SsdhKJUEDtvrtukJvh/ZDW8jdNbFJAljm8UucZGbJrZl6G7XB3WteI7rezo0mL +0NMBZIT3nQSMEpefKUFZFiE5lYvIk3UuChqIM0xdgV4INwLRHZdc1TtiGaBJV05y +3Klo5gaUgNGbHP26zfub5TydiMrOA5W2mUvMkG2oit9aqnbaZBLDt17cCKzpzcVF +5uNUng3j6sQvpTt3S4L28TvKUMAfpecQqvxMoxG0/9HZuv2z+U+LLVVsS07yJPIG +MLcq1LMM++8LwD1MupcoShjNOq/lUOL6hIMfLOIfxt8Kv8WykVzv6yjKEIurjkwM +ipq4kvr9J7FFi54kGr7uvXWQRHDFJwIDAQABAoICADepPmRAMbTnDYU8t/jRHXBE +PO29htL0V0vk4nl+pt5JuZJe6iYA89DZa+3LnG6gEmfUJjSrT4BUXiE+O9U7D7CZ +8qvgPqUmx1fk6+2AHmuefd/XanNnqQduD/jxLlQbC/gC2xdsev1ok9/tyNmKRmcs +u81QUkzmpJUCVWiUNkELozswaBBJQj4I0iM1B60b6dlWVVi5/g3dkGVW38jIdaxX +apoansKaaVoA+s63vd7CPRoFsleOoAB3FqvPREIO97CmJ848HJpwsTB0qDcnkbDV +xgbDFhxrIozko09ptOvEUILXag45EDmvG8WEivmjVml0aUoTFD7cWHyJBQCpR4fU +5W9mYd4Rrzbmpb+LGYdNyrp3wo3C7dJ7/ffBMQxmXTdMZkcxorxj4BRG3oACRQ1u +Ff1iUruZzIIDtEkrC9hc5QpLlDf9b1obm8L9sxf1QmTt59o5oFG40GPwPP19GXwE +l2faHwho2jYLM9rhuSsK/5sSmUshPNQYmfMnbWzTtghMPE/g0Cfpt8qbspq+G1bk +z3M97JlFMF83ccRotDElX9E/ttjU7Lehoz+1sOyHiVW1E4oqKer4t+nI2bp6VYZm +W94qptW7kb4o0DsvPCaoTPBxLJ1ag2WBlqoFkVI0YaxZiZ8OTR55Ovi4z5xWBO1q +NkCKgdAUQvQVzVtASVGBAoIBAQDSw2nvPFN4gGZ6OI+8j2gWtPcsrhSHS9ykxBeB +mB/HExYIe8k3EvClf2rnfwzuKgKyVMp7Ev7nH2jS/PGZq37QyXrw0NBGRnvJY0Ez +YB1KTgf9xaHMGMut5efNvv/cPwYriqosgJ0pdt0vvUAIQ6EBv+iDXXqJ1lQUSRYk +wKjFABi6TeJY4t9vC474KoXTDaHlwn9+TwnuRBk85wrZzlhK90J0iVa9/Eqeddsc +Z3CuTlc+NmcP3qvniYODq8nyVc0pKw+28AVYYEd3aJfgm+dpcB21L0oz7CaxH/Rz +FNONuQRaOzJrcuJsde/KG2X+MHs6hVMXXXWciPrJ2l+Cq7dnAoIBAQDRdwZDcgem +tJHLihCRzUl9PKip4ZA5757ZyTy6WMLR3wMS2cNTK8+bTrUa0SSC4WSI28pybFA7 +QdSR08c5Nd7jXcIrtqspgZKhb0E60i8VQHhh6ba/kyQjsEz9c/G1WquPK13j2vZ0 +79bomDwFJPsFzABU+sC0/F42ZVQzy9qXkjngjtmaGfrCc7X+pV28nEGtyxHci3L4 +XXfE2dOb+GBVZPLBVXwcthdRYsFuU9GMy2GH0zVtWPOcGRnlpx53Tqg7NIeR0Nm1 +K35EaK8PH92PsAr0Xza7vQHY4cPRz+RhDzjyGQtnhKf96U6gzzt4ZVbQ/UuzDBcL +PQ2DvUH+sqxBAoIBAEW5kiUsDu0xhTVv2tVll+jTK2ZjnLT5ut/jY2djHTgtrz9V +PEb1BBmsIoC9PljYGxZGCMpYiW2KrZIHTiIpYwXNcdeTLSPik3cXV+2YIXiAghJJ +PHKZzWAVS+97/YcubmsfL5cTYWrjQN9XO4TAYtaCV3iGB1DsT9p6J1I3Tl4F3yhb +NcN0IrjI2R5uauFchC/PfYAaw81ISBUm1iciJYF/dUO6X7DwcvsjQD6QVe3ESwZw +1v2gC7zIeHKp9WAvVHUHIubBVvNavqnZN01+JjtydNGI+IJe4Jn+WU9tF2OuTqtP +JCn50sBQ7+gr0j0aatn8W3XCXHNRua3niWtgRYcCggEAT7OzfWxhPuyMYV9qiKAN +a4ruPp3mjDUCQ6pP4jQuBT+PYtfbe8U63MSpIsgb1XVAFNdVBA70xGd7I/XqY3l9 +ExS08n8yR7vW+Hhl4KTjZ3m9lLwiXmj1omLOGM7KVRBoITUGJ9JEXyB3rM9oXyjA +H2eNZMh5FSTGEHqj/IV/6paoUSrp37os8VqoEHoJ3d+zGhcf98RT/e9KyGt+GmX6 ++eNMf4YwkJg07THfmkRoguNMfCtAtBfZsjbW5MyfShRy7PxC7ZgDju06wXr3yZB9 +dNQuhufH4s27azQUl7w8ETaCm5QuA7i1V2c0FPpljZ052JHZAQsDpbIYd11HREvm +QQKCAQEA0W7xNYoFvnyikdG0t266LLv1EkWDFdgkelGx/eGe/JZ+au3uTM94EssC +ni64XX2P8vK/te+c3jItYO4MRgnDJ7GW+bRnJFu2kBE0W4chx7vga0XApVCP+Ugg +owv5yf9cOAHFulvPefsU0snYStD3gNq77XDg0CwoyUkpeq+GiupoQ8tquMSsrEwp +ve5DtDip3cLHz2oVLB3mR4kKVwVwmOgO5RKq6N/H6Jxtf/Zk1I260dKr+Dv2MnDh +dysO4zH5YEt2ML3oY4zY8lu+I5bHCBR1updSny0B31WrXAJyfZpMx+HOwETFKa3B +v9AGKz0Jc2GOIRKHrCQ/WkZePetaYQ== +-----END PRIVATE KEY----- diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageExtensions.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageExtensions.kt new file mode 100644 index 000000000..a817c0c74 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageExtensions.kt @@ -0,0 +1,32 @@ +/* + * Copyright © 2018-2019 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.message + +import org.apache.kafka.common.header.Headers +import org.apache.kafka.common.header.internals.RecordHeader +import java.nio.charset.Charset + + +fun <T : Headers> T?.toMap(): MutableMap<String, String> { + val map: MutableMap<String, String> = hashMapOf() + this?.forEach { map[it.key()] = String(it.value(), Charset.defaultCharset()) } + return map +} + +fun Headers.addHeader(key: String, value: String) { + this.add(RecordHeader(key, value.toByteArray())) +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt index 1cd8a2af7..184e85b70 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -33,8 +34,10 @@ open class MessageConsumerProperties open class KafkaMessageConsumerProperties : MessageConsumerProperties() { lateinit var bootstrapServers: String lateinit var groupId: String - var clientId: String? = null + lateinit var clientId: String var topic: String? = null + var autoCommit: Boolean = true + var autoOffsetReset: String = "latest" var pollMillSec: Long = 1000 var pollRecords: Int = -1 } diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerService.kt index 25f0bf44d..8bcc7580a 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerService.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -17,16 +18,47 @@ package org.onap.ccsdk.cds.blueprintsprocessor.message.service import kotlinx.coroutines.channels.Channel +import org.apache.kafka.clients.consumer.Consumer +import org.apache.kafka.clients.consumer.ConsumerRecords +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageConsumerProperties +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException + +/** Consumer Function Interfaces */ +interface ConsumerFunction interface BlueprintMessageConsumerService { + suspend fun subscribe(): Channel<String> { + return subscribe(null) + } + /** Subscribe to the Kafka channel with [additionalConfig] */ suspend fun subscribe(additionalConfig: Map<String, Any>?): Channel<String> /** Subscribe to the Kafka channel with [additionalConfig] for dynamic [topics]*/ suspend fun subscribe(topics: List<String>, additionalConfig: Map<String, Any>? = null): Channel<String> + /** Consume and execute dynamic function [consumerFunction] */ + suspend fun consume(consumerFunction: ConsumerFunction) { + consume(null, consumerFunction) + } + + /** Consume with [additionalConfig], so that we can execute dynamic function [consumerFunction] */ + suspend fun consume(additionalConfig: Map<String, Any>?, consumerFunction: ConsumerFunction) { + throw BluePrintProcessorException("Not Implemented") + } + + /** Consume the [topics] with [additionalConfig], so that we can execute dynamic function [consumerFunction] */ + suspend fun consume(topics: List<String>, additionalConfig: Map<String, Any>?, + consumerFunction: ConsumerFunction) { + throw BluePrintProcessorException("Not Implemented") + } + /** close the channel, consumer and other resources */ suspend fun shutDown() - +} +/** Consumer dynamic implementation interface */ +interface KafkaConsumerRecordsFunction : ConsumerFunction { + suspend fun invoke(messageConsumerProperties: MessageConsumerProperties, consumer: Consumer<*, *>, + consumerRecords: ConsumerRecords<*, *>) }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt index e33d41c09..7d8138639 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt @@ -20,15 +20,31 @@ import kotlinx.coroutines.runBlocking interface BlueprintMessageProducerService { - fun sendMessage(message: Any): Boolean = runBlocking { - sendMessageNB(message) + fun sendMessage(message: Any): Boolean { + return sendMessage(message = message, headers = null) } - fun sendMessage(topic: String, message: Any): Boolean = runBlocking { - sendMessageNB(topic, message) + fun sendMessage(topic: String, message: Any): Boolean { + return sendMessage(topic, message, null) } - suspend fun sendMessageNB(message: Any): Boolean + fun sendMessage(message: Any, headers: MutableMap<String, String>?): Boolean = runBlocking { + sendMessageNB(message = message, headers = headers) + } + + fun sendMessage(topic: String, message: Any, headers: MutableMap<String, String>?): Boolean = runBlocking { + sendMessageNB(topic, message, headers) + } + + suspend fun sendMessageNB(message: Any): Boolean { + return sendMessageNB(message = message, headers = null) + } + + suspend fun sendMessageNB(message: Any, headers: MutableMap<String, String>?): Boolean + + suspend fun sendMessageNB(topic: String, message: Any): Boolean { + return sendMessageNB(topic, message, null) + } - suspend fun sendMessageNB(topic: String, message: Any): Boolean + suspend fun sendMessageNB(topic: String, message: Any, headers: MutableMap<String, String>?): Boolean }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt index b5d444a49..757846c81 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -24,33 +25,39 @@ import org.apache.kafka.clients.CommonClientConfigs import org.apache.kafka.clients.consumer.Consumer import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.clients.consumer.KafkaConsumer +import org.apache.kafka.common.serialization.ByteArrayDeserializer import org.apache.kafka.common.serialization.StringDeserializer import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageConsumerProperties import org.onap.ccsdk.cds.controllerblueprints.core.logger +import java.nio.charset.Charset import java.time.Duration import kotlin.concurrent.thread -class KafkaBasicAuthMessageConsumerService( +open class KafkaBasicAuthMessageConsumerService( private val messageConsumerProperties: KafkaBasicAuthMessageConsumerProperties) : BlueprintMessageConsumerService { - private val channel = Channel<String>() - private var kafkaConsumer: Consumer<String, String>? = null val log = logger(KafkaBasicAuthMessageConsumerService::class) + val channel = Channel<String>() + var kafkaConsumer: Consumer<String, ByteArray>? = null @Volatile var keepGoing = true - fun kafkaConsumer(additionalConfig: Map<String, Any>? = null): Consumer<String, String> { + fun kafkaConsumer(additionalConfig: Map<String, Any>? = null): Consumer<String, ByteArray> { val configProperties = hashMapOf<String, Any>() configProperties[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = messageConsumerProperties.bootstrapServers configProperties[ConsumerConfig.GROUP_ID_CONFIG] = messageConsumerProperties.groupId - configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = "latest" + configProperties[ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG] = messageConsumerProperties.autoCommit + /** + * earliest: automatically reset the offset to the earliest offset + * latest: automatically reset the offset to the latest offset + */ + configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = messageConsumerProperties.autoOffsetReset configProperties[ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java - configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java - if (messageConsumerProperties.clientId != null) { - configProperties[ConsumerConfig.CLIENT_ID_CONFIG] = messageConsumerProperties.clientId!! - } + configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = ByteArrayDeserializer::class.java + configProperties[ConsumerConfig.CLIENT_ID_CONFIG] = messageConsumerProperties.clientId + /** To handle Back pressure, Get only configured record for processing */ if (messageConsumerProperties.pollRecords > 0) { configProperties[ConsumerConfig.MAX_POLL_RECORDS_CONFIG] = messageConsumerProperties.pollRecords @@ -70,7 +77,7 @@ class KafkaBasicAuthMessageConsumerService( } - override suspend fun subscribe(consumerTopic: List<String>, additionalConfig: Map<String, Any>?): Channel<String> { + override suspend fun subscribe(topics: List<String>, additionalConfig: Map<String, Any>?): Channel<String> { /** Create Kafka consumer */ kafkaConsumer = kafkaConsumer(additionalConfig) @@ -80,22 +87,22 @@ class KafkaBasicAuthMessageConsumerService( "topics(${messageConsumerProperties.bootstrapServers})" } - kafkaConsumer!!.subscribe(consumerTopic) - log.info("Successfully consumed topic($consumerTopic)") + kafkaConsumer!!.subscribe(topics) + log.info("Successfully consumed topic($topics)") - thread(start = true, name = "KafkaConsumer") { + thread(start = true, name = "KafkaConsumer-${messageConsumerProperties.clientId}") { keepGoing = true kafkaConsumer!!.use { kc -> while (keepGoing) { val consumerRecords = kc.poll(Duration.ofMillis(messageConsumerProperties.pollMillSec)) - log.info("Consumed Records : ${consumerRecords.count()}") + log.trace("Consumed Records : ${consumerRecords.count()}") runBlocking { consumerRecords?.forEach { consumerRecord -> /** execute the command block */ consumerRecord.value()?.let { launch { if (!channel.isClosedForSend) { - channel.send(it) + channel.send(String(it, Charset.defaultCharset())) } else { log.error("Channel is closed to receive message") } @@ -110,6 +117,46 @@ class KafkaBasicAuthMessageConsumerService( return channel } + override suspend fun consume(additionalConfig: Map<String, Any>?, consumerFunction: ConsumerFunction) { + /** get to topic names */ + val consumerTopic = messageConsumerProperties.topic?.split(",")?.map { it.trim() } + check(!consumerTopic.isNullOrEmpty()) { "couldn't get topic information" } + return consume(topics = consumerTopic, additionalConfig = additionalConfig, consumerFunction = consumerFunction) + } + + override suspend fun consume(topics: List<String>, additionalConfig: Map<String, Any>?, + consumerFunction: ConsumerFunction) { + + val kafkaConsumerFunction = consumerFunction as KafkaConsumerRecordsFunction + + /** Create Kafka consumer */ + kafkaConsumer = kafkaConsumer(additionalConfig) + + checkNotNull(kafkaConsumer) { + "failed to create kafka consumer for " + + "server(${messageConsumerProperties.bootstrapServers})'s " + + "topics(${messageConsumerProperties.bootstrapServers})" + } + + kafkaConsumer!!.subscribe(topics) + log.info("Successfully consumed topic($topics)") + + thread(start = true, name = "KafkaConsumer-${messageConsumerProperties.clientId}") { + keepGoing = true + kafkaConsumer!!.use { kc -> + while (keepGoing) { + val consumerRecords = kc.poll(Duration.ofMillis(messageConsumerProperties.pollMillSec)) + log.trace("Consumed Records : ${consumerRecords.count()}") + runBlocking { + /** Execute dynamic consumer Block substitution */ + kafkaConsumerFunction.invoke(messageConsumerProperties, kc, consumerRecords) + } + } + log.info("message listener shutting down.....") + } + } + } + override suspend fun shutDown() { /** stop the polling loop */ keepGoing = false diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt index 1c93bb0fc..42adcd712 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -17,16 +18,18 @@ package org.onap.ccsdk.cds.blueprintsprocessor.message.service import org.apache.commons.lang.builder.ToStringBuilder +import org.apache.kafka.clients.producer.Callback +import org.apache.kafka.clients.producer.KafkaProducer import org.apache.kafka.clients.producer.ProducerConfig.* +import org.apache.kafka.clients.producer.ProducerRecord +import org.apache.kafka.common.header.internals.RecordHeader +import org.apache.kafka.common.serialization.ByteArraySerializer import org.apache.kafka.common.serialization.StringSerializer import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageProducerProperties -import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToUUID import org.slf4j.LoggerFactory -import org.springframework.kafka.core.DefaultKafkaProducerFactory -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.kafka.core.ProducerFactory -import org.springframework.kafka.support.SendResult -import org.springframework.util.concurrent.ListenableFutureCallback +import java.nio.charset.Charset class KafkaBasicAuthMessageProducerService( private val messageProducerProperties: KafkaBasicAuthMessageProducerProperties) @@ -34,42 +37,46 @@ class KafkaBasicAuthMessageProducerService( private val log = LoggerFactory.getLogger(KafkaBasicAuthMessageProducerService::class.java)!! - private var kafkaTemplate: KafkaTemplate<String, Any>? = null + private var kafkaProducer: KafkaProducer<String, ByteArray>? = null + + private val messageLoggerService = MessageLoggerService() override suspend fun sendMessageNB(message: Any): Boolean { checkNotNull(messageProducerProperties.topic) { "default topic is not configured" } - return sendMessage(messageProducerProperties.topic!!, message) + return sendMessageNB(messageProducerProperties.topic!!, message) } - override suspend fun sendMessageNB(topic: String, message: Any): Boolean { - val serializedMessage = when (message) { - is String -> { - message - } - else -> { - message.asJsonType().toString() - } - } - val future = messageTemplate().send(topic, serializedMessage) + override suspend fun sendMessageNB(message: Any, headers: MutableMap<String, String>?): Boolean { + checkNotNull(messageProducerProperties.topic) { "default topic is not configured" } + return sendMessageNB(messageProducerProperties.topic!!, message, headers) + } - future.addCallback(object : ListenableFutureCallback<SendResult<String, Any>> { - override fun onSuccess(result: SendResult<String, Any>) { - log.info("message sent successfully with offset=[${result.recordMetadata.offset()}]") - } + override suspend fun sendMessageNB(topic: String, message: Any, + headers: MutableMap<String, String>?): Boolean { + val byteArrayMessage = when (message) { + is String -> message.toByteArray(Charset.defaultCharset()) + else -> message.asJsonString().toByteArray(Charset.defaultCharset()) + } - override fun onFailure(ex: Throwable) { - log.error("Unable to send message", ex) - } - }) + val record = ProducerRecord<String, ByteArray>(topic, defaultToUUID(), byteArrayMessage) + val recordHeaders = record.headers() + messageLoggerService.messageProducing(recordHeaders) + headers?.let { + headers.forEach { (key, value) -> recordHeaders.add(RecordHeader(key, value.toByteArray())) } + } + val callback = Callback { metadata, exception -> + log.info("message published offset(${metadata.offset()}, headers :$headers )") + } + messageTemplate().send(record, callback).get() return true } - private fun producerFactory(additionalConfig: Map<String, Any>? = null): ProducerFactory<String, Any> { - log.info("Client Properties : ${ToStringBuilder.reflectionToString(messageProducerProperties)}") + fun messageTemplate(additionalConfig: Map<String, ByteArray>? = null): KafkaProducer<String, ByteArray> { + log.trace("Client Properties : ${ToStringBuilder.reflectionToString(messageProducerProperties)}") val configProps = hashMapOf<String, Any>() configProps[BOOTSTRAP_SERVERS_CONFIG] = messageProducerProperties.bootstrapServers configProps[KEY_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java - configProps[VALUE_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java + configProps[VALUE_SERIALIZER_CLASS_CONFIG] = ByteArraySerializer::class.java if (messageProducerProperties.clientId != null) { configProps[CLIENT_ID_CONFIG] = messageProducerProperties.clientId!! } @@ -79,14 +86,11 @@ class KafkaBasicAuthMessageProducerService( if (additionalConfig != null) { configProps.putAll(additionalConfig) } - return DefaultKafkaProducerFactory(configProps) - } - fun messageTemplate(additionalConfig: Map<String, Any>? = null): KafkaTemplate<String, Any> { - if (kafkaTemplate == null) { - kafkaTemplate = KafkaTemplate(producerFactory(additionalConfig)) + if (kafkaProducer == null) { + kafkaProducer = KafkaProducer(configProps) } - return kafkaTemplate!! + return kafkaProducer!! } } diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/MessageLoggerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/MessageLoggerService.kt new file mode 100644 index 000000000..21bf1b76c --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/MessageLoggerService.kt @@ -0,0 +1,88 @@ +/* + * Copyright © 2018-2019 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.message.service + +import org.apache.kafka.clients.consumer.ConsumerRecord +import org.apache.kafka.common.header.Headers +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader +import org.onap.ccsdk.cds.blueprintsprocessor.message.addHeader +import org.onap.ccsdk.cds.blueprintsprocessor.message.toMap +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToUUID +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.slf4j.MDC +import java.net.InetAddress +import java.time.Instant +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.util.* + +class MessageLoggerService { + + private val log = logger(MessageLoggerService::class) + + fun messageConsuming(headers: CommonHeader, consumerRecord: ConsumerRecord<*, *>) { + messageConsuming(headers.requestId, headers.subRequestId, + headers.originatorId, consumerRecord) + } + + fun messageConsuming(consumerRecord: ConsumerRecord<*, *>) { + val headers = consumerRecord.headers().toMap() + val requestID = headers[BluePrintConstants.ONAP_REQUEST_ID].defaultToUUID() + val invocationID = headers[BluePrintConstants.ONAP_INVOCATION_ID].defaultToUUID() + val partnerName = headers[BluePrintConstants.ONAP_PARTNER_NAME] ?: "UNKNOWN" + messageConsuming(requestID, invocationID, partnerName, consumerRecord) + } + + + fun messageConsuming(requestID: String, invocationID: String, partnerName: String, + consumerRecord: ConsumerRecord<*, *>) { + val headers = consumerRecord.headers().toMap() + val localhost = InetAddress.getLocalHost() + MDC.put("InvokeTimestamp", ZonedDateTime + .ofInstant(Instant.ofEpochMilli(consumerRecord.timestamp()), ZoneOffset.UTC) + .format(DateTimeFormatter.ISO_INSTANT)) + MDC.put("RequestID", requestID) + MDC.put("InvocationID", invocationID) + MDC.put("PartnerName", partnerName) + MDC.put("ClientIPAddress", headers["ClientIPAddress"].defaultToEmpty()) + MDC.put("ServerFQDN", localhost.hostName.defaultToEmpty()) + MDC.put("ServiceName", consumerRecord.topic()) + // Custom MDC for Message Consumers + MDC.put("Offset", consumerRecord.offset().toString()) + MDC.put("MessageKey", consumerRecord.key()?.toString().defaultToEmpty()) + log.info("Consuming MDC Properties : ${MDC.getCopyOfContextMap()}") + } + + /** Used before producing message request, Inbound Invocation ID is used as request Id + * for produced message Request, If invocation Id is missing then default Request Id will be generated. + */ + fun messageProducing(requestHeader: Headers) { + val localhost = InetAddress.getLocalHost() + requestHeader.addHeader(BluePrintConstants.ONAP_REQUEST_ID, MDC.get("InvocationID").defaultToUUID()) + requestHeader.addHeader(BluePrintConstants.ONAP_INVOCATION_ID, UUID.randomUUID().toString()) + val partnerName = System.getProperty("APPNAME") ?: "BlueprintsProcessor" + requestHeader.addHeader(BluePrintConstants.ONAP_PARTNER_NAME, partnerName) + requestHeader.addHeader("ClientIPAddress", localhost.hostAddress) + } + + fun messageConsumingExisting() { + MDC.clear() + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt index f4e85a94b..bdceec7d3 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2018-2019 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. @@ -22,15 +23,14 @@ import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import org.apache.kafka.clients.consumer.ConsumerRecord -import org.apache.kafka.clients.consumer.MockConsumer -import org.apache.kafka.clients.consumer.OffsetResetStrategy +import org.apache.kafka.clients.consumer.* import org.apache.kafka.common.TopicPartition import org.junit.Test import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageConsumerProperties import org.onap.ccsdk.cds.controllerblueprints.core.logger import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.annotation.DirtiesContext @@ -87,14 +87,14 @@ open class BlueprintMessageConsumerServiceTest { partitionsEndMap[partition] = records topicsCollection.add(partition.topic()) } - val mockKafkaConsumer = MockConsumer<String, String>(OffsetResetStrategy.EARLIEST) + val mockKafkaConsumer = MockConsumer<String, ByteArray>(OffsetResetStrategy.EARLIEST) mockKafkaConsumer.subscribe(topicsCollection) mockKafkaConsumer.rebalance(partitions) mockKafkaConsumer.updateBeginningOffsets(partitionsBeginningMap) mockKafkaConsumer.updateEndOffsets(partitionsEndMap) for (i in 1..10) { - val record = ConsumerRecord<String, String>(topic, 1, i.toLong(), "key_$i", - "I am message $i") + val record = ConsumerRecord<String, ByteArray>(topic, 1, i.toLong(), "key_$i", + "I am message $i".toByteArray()) mockKafkaConsumer.addRecord(record) } @@ -110,6 +110,54 @@ open class BlueprintMessageConsumerServiceTest { } } + @Test + fun testKafkaBasicAuthConsumerWithDynamicFunction() { + runBlocking { + val blueprintMessageConsumerService = bluePrintMessageLibPropertyService + .blueprintMessageConsumerService("sample") as KafkaBasicAuthMessageConsumerService + assertNotNull(blueprintMessageConsumerService, "failed to get blueprintMessageConsumerService") + + val spyBlueprintMessageConsumerService = spyk(blueprintMessageConsumerService, recordPrivateCalls = true) + + val topic = "default-topic" + val partitions: MutableList<TopicPartition> = arrayListOf() + val topicsCollection: MutableList<String> = arrayListOf() + partitions.add(TopicPartition(topic, 1)) + val partitionsBeginningMap: MutableMap<TopicPartition, Long> = mutableMapOf() + val partitionsEndMap: MutableMap<TopicPartition, Long> = mutableMapOf() + + val records: Long = 10 + partitions.forEach { partition -> + partitionsBeginningMap[partition] = 0L + partitionsEndMap[partition] = records + topicsCollection.add(partition.topic()) + } + val mockKafkaConsumer = MockConsumer<String, ByteArray>(OffsetResetStrategy.EARLIEST) + mockKafkaConsumer.subscribe(topicsCollection) + mockKafkaConsumer.rebalance(partitions) + mockKafkaConsumer.updateBeginningOffsets(partitionsBeginningMap) + mockKafkaConsumer.updateEndOffsets(partitionsEndMap) + for (i in 1..10) { + val record = ConsumerRecord<String, ByteArray>(topic, 1, i.toLong(), "key_$i", + "I am message $i".toByteArray()) + mockKafkaConsumer.addRecord(record) + } + + every { spyBlueprintMessageConsumerService.kafkaConsumer(any()) } returns mockKafkaConsumer + /** Test Consumer Function implementation */ + val consumerFunction = object : KafkaConsumerRecordsFunction { + override suspend fun invoke(messageConsumerProperties: MessageConsumerProperties, + consumer: Consumer<*, *>, consumerRecords: ConsumerRecords<*, *>) { + val count = consumerRecords.count() + log.trace("Received Message count($count)") + } + } + spyBlueprintMessageConsumerService.consume(consumerFunction) + delay(10) + spyBlueprintMessageConsumerService.shutDown() + } + } + /** Integration Kafka Testing, Enable and use this test case only for local desktop testing with real kafka broker */ //@Test fun testKafkaIntegration() { @@ -131,7 +179,10 @@ open class BlueprintMessageConsumerServiceTest { launch { repeat(5) { delay(100) - blueprintMessageProducerService.sendMessage("this is my message($it)") + val headers: MutableMap<String, String> = hashMapOf() + headers["id"] = it.toString() + blueprintMessageProducerService.sendMessageNB(message = "this is my message($it)", + headers = headers) } } delay(5000) diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt index 31bcc1517..f23624f7a 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt @@ -20,18 +20,18 @@ import io.mockk.every import io.mockk.mockk import io.mockk.spyk import kotlinx.coroutines.runBlocking +import org.apache.kafka.clients.producer.KafkaProducer +import org.apache.kafka.clients.producer.RecordMetadata import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration import org.springframework.beans.factory.annotation.Autowired -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.kafka.support.SendResult import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner -import org.springframework.util.concurrent.SettableListenableFuture +import java.util.concurrent.Future import kotlin.test.Test import kotlin.test.assertTrue @@ -57,12 +57,12 @@ open class BlueprintMessageProducerServiceTest { val blueprintMessageProducerService = bluePrintMessageLibPropertyService .blueprintMessageProducerService("sample") as KafkaBasicAuthMessageProducerService - val mockKafkaTemplate = mockk<KafkaTemplate<String, Any>>() + val mockKafkaTemplate = mockk<KafkaProducer<String, ByteArray>>() - val future = SettableListenableFuture<SendResult<String, Any>>() - //future.setException(BluePrintException("failed sending")) + val responseMock = mockk<Future<RecordMetadata>>() + every { responseMock.get() } returns mockk() - every { mockKafkaTemplate.send(any(), any()) } returns future + every { mockKafkaTemplate.send(any(), any()) } returns responseMock val spyBluePrintMessageProducerService = spyk(blueprintMessageProducerService, recordPrivateCalls = true) diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/MessageLoggerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/MessageLoggerServiceTest.kt new file mode 100644 index 000000000..82e40efd1 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/MessageLoggerServiceTest.kt @@ -0,0 +1,61 @@ +/* + * Copyright © 2018-2019 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.message.service + +import io.mockk.every +import io.mockk.mockk +import org.apache.kafka.clients.consumer.ConsumerRecord +import org.apache.kafka.common.header.internals.RecordHeaders +import org.junit.Test +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader +import org.onap.ccsdk.cds.blueprintsprocessor.message.toMap +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.slf4j.MDC +import kotlin.test.assertEquals + +class MessageLoggerServiceTest { + + + @Test + fun testMessagingHeaders() { + val messageLoggerService = MessageLoggerService() + val commonHeader = CommonHeader().apply { + requestId = "1234" + subRequestId = "1234-12" + originatorId = "cds-test" + } + + val consumerRecord = mockk<ConsumerRecord<*, *>>() + every { consumerRecord.headers() } returns null + every { consumerRecord.key() } returns "1234" + every { consumerRecord.offset() } returns 12345 + every { consumerRecord.topic() } returns "sample-topic" + every { consumerRecord.timestamp() } returns System.currentTimeMillis() + messageLoggerService.messageConsuming(commonHeader, consumerRecord) + assertEquals(commonHeader.requestId, MDC.get("RequestID")) + assertEquals(commonHeader.subRequestId, MDC.get("InvocationID")) + + val mockHeaders = RecordHeaders() + messageLoggerService.messageProducing(mockHeaders) + val map = mockHeaders.toMap() + assertEquals("1234-12", map[BluePrintConstants.ONAP_REQUEST_ID]) + + messageLoggerService.messageConsumingExisting() + + } + +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml index 3868440c7..820041f74 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml @@ -1,5 +1,6 @@ <!-- ~ Copyright © 2019 IBM. + ~ Modifications Copyright © 2018-2019 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. @@ -15,11 +16,18 @@ --> <configuration> + + <property name="localPattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/> + <property name="defaultPattern" + value="%date{ISO8601,UTC}|%X{RequestID}|%X{InvocationID}|%thread|%X{ServiceName}|%X{ClientIPAddress}|%logger{50}| %msg%n"/> + <property name="testing" + value="%X{RequestID}|%X{InvocationID}|%logger{50}| %msg%n"/> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> - <pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{50} - %msg%n</pattern> + <pattern>${localPattern}</pattern> </encoder> </appender> diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/LoggerExtensions.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/LoggerExtensions.kt deleted file mode 100644 index cdf6ce195..000000000 --- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/LoggerExtensions.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright © 2018-2019 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.core - -import kotlinx.coroutines.* -import kotlinx.coroutines.reactor.ReactorContext -import kotlinx.coroutines.reactor.asCoroutineContext -import org.onap.ccsdk.cds.blueprintsprocessor.core.service.MonoMDCCoroutine -import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext -import reactor.core.publisher.Mono -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext - -/** Used in Rest controller API methods to populate MDC context to nested coroutines from reactor web filter context. */ -@UseExperimental(InternalCoroutinesApi::class) -fun <T> monoMdc(context: CoroutineContext = EmptyCoroutineContext, - block: suspend CoroutineScope.() -> T?): Mono<T> = Mono.create { sink -> - - val reactorContext = (context[ReactorContext]?.context?.putAll(sink.currentContext()) - ?: sink.currentContext()).asCoroutineContext() - /** Populate MDC context only if present in Reactor Context */ - val newContext = if (!reactorContext.context.isEmpty - && reactorContext.context.hasKey(MDCContext)) { - val mdcContext = reactorContext.context.get<MDCContext>(MDCContext) - GlobalScope.newCoroutineContext(context + reactorContext + mdcContext) - } else GlobalScope.newCoroutineContext(context + reactorContext) - - val coroutine = MonoMDCCoroutine(newContext, sink) - sink.onDispose(coroutine) - coroutine.start(CoroutineStart.DEFAULT, coroutine, block) -}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt index 2f9ea4a25..d63f34ced 100644 --- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt +++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt @@ -39,7 +39,8 @@ data class RemoteScriptExecutionInput(var requestId: String, data class RemoteScriptExecutionOutput(var requestId: String, var response: List<String>, var status: StatusType = StatusType.SUCCESS, - var timestamp: Date = Date()) + var timestamp: Date = Date(), + var payload: JsonNode) data class PrepareRemoteEnvInput(var requestId: String, var correlationId: String? = null, diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt index 9fa13bdaf..384946ae8 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt @@ -29,16 +29,32 @@ import org.springframework.stereotype.Service open class BluePrintRestLibPropertyService(private var bluePrintProperties: BluePrintProperties) { - open fun blueprintWebClientService(jsonNode: JsonNode): - BlueprintWebClientService { - val restClientProperties = restClientProperties(jsonNode) - return blueprintWebClientService(restClientProperties) + private var preInterceptor: PreInterceptor? = null + private var postInterceptor: PostInterceptor? = null + + fun setInterceptors(preInterceptor: PreInterceptor?, postInterceptor: PostInterceptor?) { + this.preInterceptor = preInterceptor + this.postInterceptor = postInterceptor + } + + fun clearInterceptors() { + this.preInterceptor = null + this.postInterceptor = null + } + + open fun blueprintWebClientService(jsonNode: JsonNode): BlueprintWebClientService { + val service = preInterceptor?.getInstance(jsonNode) + ?: blueprintWebClientService(restClientProperties(jsonNode)) + return postInterceptor?.getInstance(jsonNode, service) ?: service } open fun blueprintWebClientService(selector: String): BlueprintWebClientService { - val prefix = "blueprintsprocessor.restclient.$selector" - val restClientProperties = restClientProperties(prefix) - return blueprintWebClientService(restClientProperties) + val service = preInterceptor?.getInstance(selector) ?: run { + val prefix = "blueprintsprocessor.restclient.$selector" + val restClientProperties = restClientProperties(prefix) + blueprintWebClientService(restClientProperties) + } + return postInterceptor?.getInstance(selector, service) ?: service } fun restClientProperties(prefix: String): RestClientProperties { @@ -182,6 +198,18 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: return bluePrintProperties.propertyBeanType( prefix, PolicyManagerRestClientProperties::class.java) } + + interface PreInterceptor { + fun getInstance(jsonNode: JsonNode): BlueprintWebClientService? + + fun getInstance(selector: String): BlueprintWebClientService? + } + + interface PostInterceptor { + fun getInstance(jsonNode: JsonNode, service: BlueprintWebClientService): BlueprintWebClientService + + fun getInstance(selector: String, service: BlueprintWebClientService): BlueprintWebClientService + } } diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/service/BluePrintProcessorLoggingService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestLoggerService.kt index 4da7dcd0e..cec11ae3c 100644 --- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/service/BluePrintProcessorLoggingService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestLoggerService.kt @@ -14,43 +14,47 @@ * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.core.service +package org.onap.ccsdk.cds.blueprintsprocessor.rest.service -import kotlinx.coroutines.AbstractCoroutine -import kotlinx.coroutines.InternalCoroutinesApi -import kotlinx.coroutines.handleCoroutineException +import kotlinx.coroutines.* +import kotlinx.coroutines.reactor.ReactorContext +import kotlinx.coroutines.reactor.asCoroutineContext +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_INVOCATION_ID +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_PARTNER_NAME +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_REQUEST_ID +import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.defaultToUUID import org.onap.ccsdk.cds.controllerblueprints.core.logger import org.slf4j.MDC import org.springframework.http.server.reactive.ServerHttpRequest import org.springframework.http.server.reactive.ServerHttpResponse import reactor.core.Disposable +import reactor.core.publisher.Mono import reactor.core.publisher.MonoSink +import java.net.InetAddress import java.time.ZoneOffset import java.time.ZonedDateTime import java.time.format.DateTimeFormatter -import java.util.* import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext -class LoggingService { - private val log = logger(LoggingService::class) +class RestLoggerService { + private val log = logger(RestLoggerService::class) - companion object { - const val ONAP_REQUEST_ID = "X-ONAP-RequestID" - const val ONAP_INVOCATION_ID = "X-ONAP-InvocationID" - const val ONAP_PARTNER_NAME = "X-ONAP-PartnerName" - } fun entering(request: ServerHttpRequest) { + val localhost = InetAddress.getLocalHost() val headers = request.headers - val requestID = defaultToUUID(headers.getFirst(ONAP_REQUEST_ID)) - val invocationID = defaultToUUID(headers.getFirst(ONAP_INVOCATION_ID)) - val partnerName = defaultToEmpty(headers.getFirst(ONAP_PARTNER_NAME)) + val requestID = headers.getFirst(ONAP_REQUEST_ID).defaultToUUID() + val invocationID = headers.getFirst(ONAP_INVOCATION_ID).defaultToUUID() + val partnerName = headers.getFirst(ONAP_PARTNER_NAME).defaultToEmpty() MDC.put("InvokeTimestamp", ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT)) MDC.put("RequestID", requestID) MDC.put("InvocationID", invocationID) MDC.put("PartnerName", partnerName) - MDC.put("ClientIPAddress", defaultToEmpty(request.remoteAddress?.address?.hostAddress)) - MDC.put("ServerFQDN", defaultToEmpty(request.remoteAddress?.hostString)) + MDC.put("ClientIPAddress", request.remoteAddress?.address?.hostAddress.defaultToEmpty()) + MDC.put("ServerFQDN",localhost.hostName.defaultToEmpty()) if (MDC.get("ServiceName") == null || MDC.get("ServiceName").equals("", ignoreCase = true)) { MDC.put("ServiceName", request.uri.path) } @@ -62,22 +66,35 @@ class LoggingService { val resHeaders = response.headers resHeaders[ONAP_REQUEST_ID] = MDC.get("RequestID") resHeaders[ONAP_INVOCATION_ID] = MDC.get("InvocationID") + val partnerName = System.getProperty("APPNAME") ?: "BlueprintsProcessor" + resHeaders[ONAP_PARTNER_NAME] = partnerName } catch (e: Exception) { log.warn("couldn't set response headers", e) } finally { MDC.clear() } } +} - private fun defaultToEmpty(input: Any?): String { - return input?.toString() ?: "" - } - private fun defaultToUUID(input: String?): String { - return input ?: UUID.randomUUID().toString() - } -} +/** Used in Rest controller API methods to populate MDC context to nested coroutines from reactor web filter context. */ +@UseExperimental(InternalCoroutinesApi::class) +fun <T> monoMdc(context: CoroutineContext = EmptyCoroutineContext, + block: suspend CoroutineScope.() -> T?): Mono<T> = Mono.create { sink -> + + val reactorContext = (context[ReactorContext]?.context?.putAll(sink.currentContext()) + ?: sink.currentContext()).asCoroutineContext() + /** Populate MDC context only if present in Reactor Context */ + val newContext = if (!reactorContext.context.isEmpty + && reactorContext.context.hasKey(MDCContext)) { + val mdcContext = reactorContext.context.get<MDCContext>(MDCContext) + GlobalScope.newCoroutineContext(context + reactorContext + mdcContext) + } else GlobalScope.newCoroutineContext(context + reactorContext) + val coroutine = MonoMDCCoroutine(newContext, sink) + sink.onDispose(coroutine) + coroutine.start(CoroutineStart.DEFAULT, coroutine, block) +} @InternalCoroutinesApi class MonoMDCCoroutine<in T>( diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt index a6bff7051..bf251f6c3 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt @@ -19,9 +19,9 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam -import org.onap.ccsdk.cds.blueprintsprocessor.core.monoMdc import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler.BluePrintModelHandler +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.monoMdc import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.springframework.core.io.Resource import org.springframework.http.MediaType diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt index f14f61e60..345650686 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt @@ -23,7 +23,7 @@ import io.swagger.annotations.ApiParam import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_ASYNC import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput -import org.onap.ccsdk.cds.blueprintsprocessor.core.monoMdc +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.monoMdc import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils.determineHttpStatusCode import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.logger diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt index 20af589a1..ade47cf3f 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt @@ -23,11 +23,13 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.* import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils.toProto +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractServiceFunction import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintWorkflowExecutionService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -70,26 +72,45 @@ class ExecutionServiceHandler(private val bluePrintLoadConfiguration: BluePrintL val blueprintName = actionIdentifiers.blueprintName val blueprintVersion = actionIdentifiers.blueprintVersion try { - val basePath = blueprintsProcessorCatalogService.getFromDatabase(blueprintName, blueprintVersion) - log.info("blueprint base path $basePath") + /** Check Blueprint is needed for this request */ + if (checkServiceFunction(executionServiceInput)) { + return executeServiceFunction(executionServiceInput) + } else { + val basePath = blueprintsProcessorCatalogService.getFromDatabase(blueprintName, blueprintVersion) + log.info("blueprint base path $basePath") - val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(requestId, basePath.toString()) + val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(requestId, basePath.toString()) - val output = bluePrintWorkflowExecutionService.executeBluePrintWorkflow(blueprintRuntimeService, - executionServiceInput, hashMapOf()) + val output = bluePrintWorkflowExecutionService.executeBluePrintWorkflow(blueprintRuntimeService, + executionServiceInput, hashMapOf()) - val errors = blueprintRuntimeService.getBluePrintError().errors - if (errors.isNotEmpty()) { - val errorMessage = errors.stream().map { it.toString() }.collect(Collectors.joining(", ")) - setErrorStatus(errorMessage, output.status) + val errors = blueprintRuntimeService.getBluePrintError().errors + if (errors.isNotEmpty()) { + val errorMessage = errors.stream().map { it.toString() }.collect(Collectors.joining(", ")) + setErrorStatus(errorMessage, output.status) + } + return output } - return output } catch (e: Exception) { log.error("fail processing request id $requestId", e) return response(executionServiceInput, e.localizedMessage ?: e.message ?: e.toString(), true) } } + /** If the blueprint name is default, It means no blueprint is needed for the execution */ + fun checkServiceFunction(executionServiceInput: ExecutionServiceInput): Boolean { + return executionServiceInput.actionIdentifiers.blueprintName == "default" + } + + /** If no blueprint is needed, then get the Service function instance mapping to the action name and execute it */ + suspend fun executeServiceFunction(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput { + val actionName = executionServiceInput.actionIdentifiers.actionName + val instance = BluePrintDependencyService.instance<AbstractServiceFunction>(actionName) + checkNotNull(instance) { "failed to initialize service function($actionName)" } + instance.actionName = actionName + return instance.applyNB(executionServiceInput) + } + private fun setErrorStatus(errorMessage: String, status: Status) { status.errorMessage = errorMessage status.eventType = EventType.EVENT_COMPONENT_FAILURE.name diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt new file mode 100644 index 000000000..293da0da6 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt @@ -0,0 +1,84 @@ +/* + * Copyright © 2018-2019 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.selfservice.api + +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractServiceFunction +import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.ApplicationContext +import org.springframework.stereotype.Service +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.junit4.SpringRunner +import kotlin.test.Test +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +@RunWith(SpringRunner::class) +@ContextConfiguration(classes = [MockServiceAction::class]) +class ExecutionServiceHandlerTest { + + @Autowired + lateinit var applicationContext: ApplicationContext + + @Before + fun init() { + BluePrintDependencyService.inject(applicationContext) + } + + @Test + fun testExecuteServiceFunction() { + val executionServiceInput = ExecutionServiceInput().apply { + commonHeader = CommonHeader().apply { + requestId = "1234" + subRequestId = "1234-12" + originatorId = "cds-test" + } + actionIdentifiers = ActionIdentifiers().apply { + blueprintName = "default" + blueprintVersion = "1.0.0" + actionName = "mock-service-action" + } + } + runBlocking { + val executionServiceHandler = ExecutionServiceHandler(mockk(), mockk(), mockk()) + val isServiceFunction = executionServiceHandler.checkServiceFunction(executionServiceInput) + assertTrue(isServiceFunction, "failed to checkServiceFunction") + val executionServiceOutput = executionServiceHandler.executeServiceFunction(executionServiceInput) + assertNotNull(executionServiceOutput, "failed to get executionServiceOutput") + } + } +} + +@Service("mock-service-action") +class MockServiceAction : AbstractServiceFunction() { + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + val responsePayload = """{"answer" : "correct"}""".jsonAsJsonType() + setResponsePayloadForAction(responsePayload) + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractServiceFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractServiceFunction.kt new file mode 100644 index 000000000..67ab9c4de --- /dev/null +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractServiceFunction.kt @@ -0,0 +1,112 @@ +/* + * Copyright © 2018-2019 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.services.execution + +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.Status +import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode +import org.onap.ccsdk.cds.controllerblueprints.core.jsonPathParse +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils + +/** This implementation is used to build services, which doesn't need blueprints */ +abstract class AbstractServiceFunction : BlueprintFunctionNode<ExecutionServiceInput, ExecutionServiceOutput> { + + @Transient + private val log = logger(AbstractServiceFunction::class) + + lateinit var executionServiceInput: ExecutionServiceInput + var executionServiceOutput = ExecutionServiceOutput() + lateinit var processId: String + lateinit var actionName: String + lateinit var responseActionPayload: JsonNode + + override fun getName(): String { + return actionName + } + + override suspend fun prepareRequestNB(executionRequest: ExecutionServiceInput): ExecutionServiceInput { + + this.executionServiceInput = executionRequest + + actionName = executionRequest.actionIdentifiers.actionName + check(actionName.isNotEmpty()) { "couldn't get action name" } + + processId = executionRequest.commonHeader.requestId + check(processId.isNotEmpty()) { "couldn't get process id for service action($actionName)" } + + return executionRequest + } + + override suspend fun applyNB(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput { + try { + prepareRequestNB(executionServiceInput) + processNB(executionServiceInput) + } catch (runtimeException: RuntimeException) { + log.error("failed in ${getName()} : ${runtimeException.message}", runtimeException) + recoverNB(runtimeException, executionServiceInput) + } + return prepareResponseNB() + } + + override suspend fun prepareResponseNB(): ExecutionServiceOutput { + log.debug("Preparing Response...") + executionServiceOutput.commonHeader = executionServiceInput.commonHeader + executionServiceOutput.actionIdentifiers = executionServiceInput.actionIdentifiers + var status = Status() + try { + // Set the Response Payload + executionServiceOutput.payload = JacksonUtils.objectMapper.createObjectNode() + executionServiceOutput.payload.set("$actionName-response", responseActionPayload) + // Set the Default Step Status + status.eventType = EventType.EVENT_COMPONENT_EXECUTED.name + } catch (e: Exception) { + status.message = BluePrintConstants.STATUS_FAILURE + status.eventType = EventType.EVENT_COMPONENT_FAILURE.name + } + executionServiceOutput.status = status + return this.executionServiceOutput + } + + fun setResponsePayloadForAction(actionPayload: JsonNode) { + this.responseActionPayload = actionPayload + } + + /** + * Get Execution Input Payload data + */ + fun requestPayload(): JsonNode? { + return executionServiceInput.payload + } + + /** + * Get Execution Input payload action property with [expression] + * ex: requestPayloadActionProperty("data") will look for path "payload/<action-name>-request/data" + */ + fun requestPayloadActionProperty(expression: String?): JsonNode? { + val requestExpression = if (expression.isNullOrBlank()) { + "$actionName-request" + } else { + "$actionName-request.$expression" + } + return executionServiceInput.payload.jsonPathParse(".$requestExpression") + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt index b0e3e4701..d6146e111 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt @@ -25,6 +25,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.* import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcClientService import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcLibPropertyService import org.onap.ccsdk.cds.controllerblueprints.command.api.* +import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.slf4j.LoggerFactory import org.springframework.beans.factory.config.ConfigurableBeanFactory @@ -154,7 +155,8 @@ class GrpcRemoteScriptExecutionService(private val bluePrintGrpcLibPropertyServi return RemoteScriptExecutionOutput( requestId = this.requestId, response = this.responseList, - status = StatusType.valueOf(this.status.name) + status = StatusType.valueOf(this.status.name), + payload = payload.jsonAsJsonType() ) } diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/MockBluePrintProcessingServer.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/MockBluePrintProcessingServer.kt index e291aa78e..6bffffdb5 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/MockBluePrintProcessingServer.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/MockBluePrintProcessingServer.kt @@ -18,8 +18,12 @@ package org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts import io.grpc.ServerBuilder import io.grpc.stub.StreamObserver +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.grpc.interceptor.GrpcServerLoggingInterceptor import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType import org.onap.ccsdk.cds.controllerblueprints.common.api.Status +import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext import org.onap.ccsdk.cds.controllerblueprints.core.logger import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput @@ -36,8 +40,13 @@ class MockBluePrintProcessingServer : BluePrintProcessingServiceGrpc.BluePrintPr override fun onNext(executionServiceInput: ExecutionServiceInput) { log.info("Received requestId(${executionServiceInput.commonHeader.requestId}) " + "subRequestId(${executionServiceInput.commonHeader.subRequestId})") - responseObserver.onNext(buildNotification(executionServiceInput)) - responseObserver.onNext(buildResponse(executionServiceInput)) + runBlocking { + launch(MDCContext()) { + responseObserver.onNext(buildNotification(executionServiceInput)) + responseObserver.onNext(buildResponse(executionServiceInput)) + log.info("message has sent successfully...") + } + } responseObserver.onCompleted() } @@ -85,6 +94,7 @@ fun main() { try { val server = ServerBuilder .forPort(50052) + .intercept(GrpcServerLoggingInterceptor()) .addService(MockBluePrintProcessingServer()) .build() server.start() diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt index 29d24c6ad..9a5be0151 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt @@ -16,6 +16,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.services.execution +import com.google.protobuf.util.JsonFormat import io.grpc.inprocess.InProcessChannelBuilder import io.grpc.inprocess.InProcessServerBuilder import io.grpc.testing.GrpcCleanupRule @@ -26,6 +27,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.flow.collect import org.junit.Rule import org.junit.Test +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_SYNC import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcLibPropertyService @@ -132,12 +134,17 @@ class StreamingRemoteExecutionServiceTest { .setActionName("SampleScript") .setBlueprintName("sample-cba") .setBlueprintVersion("1.0.0") + .setMode(ACTION_MODE_SYNC) .build() + val jsonContent = """{ "key1" : "value1" }""" + val payloadBuilder = ExecutionServiceInput.newBuilder().payloadBuilder + JsonFormat.parser().merge(jsonContent, payloadBuilder) + return ExecutionServiceInput.newBuilder() .setCommonHeader(commonHeader) .setActionIdentifiers(actionIdentifier) - //.setPayload(payloadBuilder.build()) + .setPayload(payloadBuilder.build()) .build() } diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml index afe10b39d..8951e1a71 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml @@ -15,11 +15,18 @@ --> <configuration> + + <property name="localPattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/> + <property name="defaultPattern" + value="%date{ISO8601,UTC}|%X{RequestID}|%X{InvocationID}|%thread|%X{ServiceName}|%X{ClientIPAddress}|%logger{50}| %msg%n"/> + <property name="testing" + value="%X{RequestID}|%X{InvocationID}|%logger{50}| %msg%n"/> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> - <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> + <pattern>${testing}</pattern> </encoder> </appender> diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index 37a071280..a77122fe8 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -48,6 +48,7 @@ <json.unit.version>2.8.0</json.unit.version> <xmlunit.version>2.6.3</xmlunit.version> + <netty-ssl>2.0.26.Final</netty-ssl> <sshd.version>2.2.0</sshd.version> <jsch.version>0.1.55</jsch.version> <jython.version>2.7.1</jython.version> @@ -269,6 +270,11 @@ <artifactId>protobuf-java-util</artifactId> <version>${protobuff.java.utils.version}</version> </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-tcnative-boringssl-static</artifactId> + <version>${netty-ssl}</version> + </dependency> <!-- Adaptors --> <dependency> @@ -665,6 +671,10 @@ <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java-util</artifactId> </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-tcnative-boringssl-static</artifactId> + </dependency> </dependencies> <repositories> diff --git a/ms/command-executor/src/main/docker/Dockerfile b/ms/command-executor/src/main/docker/Dockerfile index c0458bdf6..b28e580fb 100644 --- a/ms/command-executor/src/main/docker/Dockerfile +++ b/ms/command-executor/src/main/docker/Dockerfile @@ -1,8 +1,5 @@ FROM python:3.6-slim -ENV HTTP_PROXY ${HTTP_PROXY} -ENV HTTPS_PROXY ${HTTPS_PROXY} - ENV GRPC_PYTHON_VERSION 1.20.0 RUN python -m pip install --upgrade pip RUN pip install grpcio==${GRPC_PYTHON_VERSION} grpcio-tools==${GRPC_PYTHON_VERSION} @@ -21,4 +18,4 @@ RUN tar -xzf /source.tar.gz -C /tmp \ VOLUME /opt/app/onap/blueprints/deploy/ -ENTRYPOINT /opt/app/onap/start.sh
\ No newline at end of file +ENTRYPOINT /opt/app/onap/start.sh diff --git a/ms/command-executor/src/main/python/cds_utils/__init__.py b/ms/command-executor/src/main/python/cds_utils/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ms/command-executor/src/main/python/cds_utils/__init__.py diff --git a/ms/command-executor/src/main/python/cds_utils/payload_coder.py b/ms/command-executor/src/main/python/cds_utils/payload_coder.py new file mode 100644 index 000000000..951262172 --- /dev/null +++ b/ms/command-executor/src/main/python/cds_utils/payload_coder.py @@ -0,0 +1,13 @@ +import json
+from email.mime import multipart
+from email.mime import text
+import email.parser
+
+def send_response_data_payload(json_payload):
+ m = multipart.MIMEMultipart("form-data")
+ data = text.MIMEText("response_payload", "json", "utf8")
+ data.set_payload(json.JSONEncoder().encode(json_payload))
+ m.attach(data)
+ print("BEGIN_EXTRA_PAYLOAD")
+ print(m.as_string())
+ print("END_EXTRA_PAYLOAD")
\ No newline at end of file diff --git a/ms/command-executor/src/main/python/command_executor_handler.py b/ms/command-executor/src/main/python/command_executor_handler.py index 972dad627..c920dda89 100644 --- a/ms/command-executor/src/main/python/command_executor_handler.py +++ b/ms/command-executor/src/main/python/command_executor_handler.py @@ -25,6 +25,8 @@ import virtualenv import venv import utils import proto.CommandExecutor_pb2 as CommandExecutor_pb2 +import email.parser +import json REQUIREMENTS_TXT = "requirements.txt" @@ -75,6 +77,10 @@ class CommandExecutorHandler(): else: cmd = cmd + "; " + request.command + " " + re.escape(MessageToJson(request.properties)) + payload_result = {} + payload_section = [] + is_payload_section = False + try: with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, bufsize=1, universal_newlines=True) as newProcess: @@ -82,19 +88,36 @@ class CommandExecutorHandler(): output = newProcess.stdout.readline() if output == '' and newProcess.poll() is not None: break - if output: + if output.startswith('BEGIN_EXTRA_PAYLOAD'): + is_payload_section = True + output = newProcess.stdout.readline() + if output.startswith('END_EXTRA_PAYLOAD'): + is_payload_section = False + output = '' + payload = '\n'.join(payload_section) + msg = email.parser.Parser().parsestr(payload) + for part in msg.get_payload(): + payload_result = json.loads(part.get_payload()) + if output and not is_payload_section: self.logger.info(output.strip()) results.append(output.strip()) - rc = newProcess.poll() + else: + payload_section.append(output.strip()) + rc = newProcess.poll() except Exception as e: self.logger.info("{} - Failed to execute command. Error: {}".format(self.blueprint_id, e)) results.append(e) - return False + payload_result["cds_return_code"] = False + return payload_result # deactivate_venv(blueprint_id) - return True + + payload_result["cds_return_code"] = rc + return payload_result def install_packages(self, request, type, f, results): + success = self.install_python_packages('UTILITY', results) + for package in request.packages: if package.type == type: f.write("Installed %s packages:\r\n" % CommandExecutor_pb2.PackageType.Name(type)) @@ -116,6 +139,8 @@ class CommandExecutorHandler(): if REQUIREMENTS_TXT == package: command = ["pip", "install", "-r", self.venv_home + "/Environments/" + REQUIREMENTS_TXT] + elif package == 'UTILITY': + command = ["cp", "-r", "./cds_utils", self.venv_home + "/lib/python3.6/site-packages/"] else: command = ["pip", "install", package] diff --git a/ms/command-executor/src/main/python/command_executor_server.py b/ms/command-executor/src/main/python/command_executor_server.py index 6266141d9..577c8a0ca 100644 --- a/ms/command-executor/src/main/python/command_executor_server.py +++ b/ms/command-executor/src/main/python/command_executor_server.py @@ -16,7 +16,7 @@ # limitations under the License. # import logging - +import os, sys import proto.CommandExecutor_pb2_grpc as CommandExecutor_pb2_grpc from command_executor_handler import CommandExecutorHandler @@ -39,19 +39,26 @@ class CommandExecutorServer(CommandExecutor_pb2_grpc.CommandExecutorServiceServi handler = CommandExecutorHandler(request) if not handler.prepare_env(request, results): self.logger.info("{} - Failed to prepare python environment. {}".format(blueprint_id, results)) - return utils.build_response(request, results, False) + return utils.build_response(request, results, {}, False) self.logger.info("{} - Package installation logs {}".format(blueprint_id, results)) - return utils.build_response(request, results) + return utils.build_response(request, results, {}, True) def executeCommand(self, request, context): blueprint_id = utils.get_blueprint_id(request) self.logger.info("{} - Received executeCommand request".format(blueprint_id)) - self.logger.info(request) + if os.environ.get('CE_DEBUG','false') == "true": + self.logger.info(request) - results = [] + log_results = [] + payload_result = {} handler = CommandExecutorHandler(request) - if not handler.execute_command(request, results): - self.logger.info("{} - Failed to executeCommand. {}".format(blueprint_id, results)) - return utils.build_response(request, results, False) - self.logger.info("{} - Execution finished successfully.".format(blueprint_id)) - return utils.build_response(request, results) + payload_result = handler.execute_command(request, log_results) + if not payload_result["cds_return_code"]: + self.logger.info("{} - Failed to executeCommand. {}".format(blueprint_id, log_results)) + else: + self.logger.info("{} - Execution finished successfully.".format(blueprint_id)) + + ret = utils.build_response(request, log_results, payload_result, payload_result["cds_return_code"]) + self.logger.info("Payload returned %s" % payload_result) + + return ret
\ No newline at end of file diff --git a/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py index 478e00959..4edfc6cd5 100644 --- a/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py +++ b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py @@ -23,7 +23,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='org.onap.ccsdk.cds.controllerblueprints.command.api', syntax='proto3', serialized_options=_b('P\001'), - serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd0\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12O\n\x08packages\x18\x04 \x03(\x0b\x32=.org.onap.ccsdk.cds.controllerblueprints.command.api.Packages\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xba\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x03(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x08Packages\x12N\n\x04type\x18\x01 \x01(\x0e\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.PackageType\x12\x0f\n\x07package\x18\x02 \x03(\t**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01**\n\x0bPackageType\x12\x07\n\x03pip\x10\x00\x12\x12\n\x0e\x61nsible_galaxy\x10\x01\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3') + serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd0\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12O\n\x08packages\x18\x04 \x03(\x0b\x32=.org.onap.ccsdk.cds.controllerblueprints.command.api.Packages\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xcb\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x03(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07payload\x18\x05 \x01(\t\"k\n\x08Packages\x12N\n\x04type\x18\x01 \x01(\x0e\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.PackageType\x12\x0f\n\x07package\x18\x02 \x03(\t**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01*9\n\x0bPackageType\x12\x07\n\x03pip\x10\x00\x12\x12\n\x0e\x61nsible_galaxy\x10\x01\x12\r\n\tutilities\x10\x02\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3') , dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,]) @@ -44,8 +44,8 @@ _RESPONSESTATUS = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=1116, - serialized_end=1158, + serialized_start=1133, + serialized_end=1175, ) _sym_db.RegisterEnumDescriptor(_RESPONSESTATUS) @@ -64,11 +64,15 @@ _PACKAGETYPE = _descriptor.EnumDescriptor( name='ansible_galaxy', index=1, number=1, serialized_options=None, type=None), + _descriptor.EnumValueDescriptor( + name='utilities', index=2, number=2, + serialized_options=None, + type=None), ], containing_type=None, serialized_options=None, - serialized_start=1160, - serialized_end=1202, + serialized_start=1177, + serialized_end=1234, ) _sym_db.RegisterEnumDescriptor(_PACKAGETYPE) @@ -77,6 +81,7 @@ SUCCESS = 0 FAILURE = 1 pip = 0 ansible_galaxy = 1 +utilities = 2 @@ -299,6 +304,13 @@ _EXECUTIONOUTPUT = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='payload', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput.payload', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -312,7 +324,7 @@ _EXECUTIONOUTPUT = _descriptor.Descriptor( oneofs=[ ], serialized_start=819, - serialized_end=1005, + serialized_end=1022, ) @@ -349,8 +361,8 @@ _PACKAGES = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1007, - serialized_end=1114, + serialized_start=1024, + serialized_end=1131, ) _EXECUTIONINPUT.fields_by_name['identifiers'].message_type = _IDENTIFIERS @@ -372,39 +384,39 @@ DESCRIPTOR.enum_types_by_name['ResponseStatus'] = _RESPONSESTATUS DESCRIPTOR.enum_types_by_name['PackageType'] = _PACKAGETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) -ExecutionInput = _reflection.GeneratedProtocolMessageType('ExecutionInput', (_message.Message,), dict( - DESCRIPTOR = _EXECUTIONINPUT, - __module__ = 'CommandExecutor_pb2' +ExecutionInput = _reflection.GeneratedProtocolMessageType('ExecutionInput', (_message.Message,), { + 'DESCRIPTOR' : _EXECUTIONINPUT, + '__module__' : 'CommandExecutor_pb2' # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput) - )) + }) _sym_db.RegisterMessage(ExecutionInput) -PrepareEnvInput = _reflection.GeneratedProtocolMessageType('PrepareEnvInput', (_message.Message,), dict( - DESCRIPTOR = _PREPAREENVINPUT, - __module__ = 'CommandExecutor_pb2' +PrepareEnvInput = _reflection.GeneratedProtocolMessageType('PrepareEnvInput', (_message.Message,), { + 'DESCRIPTOR' : _PREPAREENVINPUT, + '__module__' : 'CommandExecutor_pb2' # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput) - )) + }) _sym_db.RegisterMessage(PrepareEnvInput) -Identifiers = _reflection.GeneratedProtocolMessageType('Identifiers', (_message.Message,), dict( - DESCRIPTOR = _IDENTIFIERS, - __module__ = 'CommandExecutor_pb2' +Identifiers = _reflection.GeneratedProtocolMessageType('Identifiers', (_message.Message,), { + 'DESCRIPTOR' : _IDENTIFIERS, + '__module__' : 'CommandExecutor_pb2' # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers) - )) + }) _sym_db.RegisterMessage(Identifiers) -ExecutionOutput = _reflection.GeneratedProtocolMessageType('ExecutionOutput', (_message.Message,), dict( - DESCRIPTOR = _EXECUTIONOUTPUT, - __module__ = 'CommandExecutor_pb2' +ExecutionOutput = _reflection.GeneratedProtocolMessageType('ExecutionOutput', (_message.Message,), { + 'DESCRIPTOR' : _EXECUTIONOUTPUT, + '__module__' : 'CommandExecutor_pb2' # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput) - )) + }) _sym_db.RegisterMessage(ExecutionOutput) -Packages = _reflection.GeneratedProtocolMessageType('Packages', (_message.Message,), dict( - DESCRIPTOR = _PACKAGES, - __module__ = 'CommandExecutor_pb2' +Packages = _reflection.GeneratedProtocolMessageType('Packages', (_message.Message,), { + 'DESCRIPTOR' : _PACKAGES, + '__module__' : 'CommandExecutor_pb2' # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.Packages) - )) + }) _sym_db.RegisterMessage(Packages) @@ -416,8 +428,8 @@ _COMMANDEXECUTORSERVICE = _descriptor.ServiceDescriptor( file=DESCRIPTOR, index=0, serialized_options=None, - serialized_start=1205, - serialized_end=1542, + serialized_start=1237, + serialized_end=1574, methods=[ _descriptor.MethodDescriptor( name='prepareEnv', diff --git a/ms/command-executor/src/main/python/server.py b/ms/command-executor/src/main/python/server.py index 453d751b2..c136bd8cc 100644 --- a/ms/command-executor/src/main/python/server.py +++ b/ms/command-executor/src/main/python/server.py @@ -43,7 +43,7 @@ def serve(): 'Access denied!') server = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), + futures.ThreadPoolExecutor(max_workers=15), interceptors=(header_validator,)) CommandExecutor_pb2_grpc.add_CommandExecutorServiceServicer_to_server( diff --git a/ms/command-executor/src/main/python/utils.py b/ms/command-executor/src/main/python/utils.py index 4314b287d..a3748eb17 100644 --- a/ms/command-executor/src/main/python/utils.py +++ b/ms/command-executor/src/main/python/utils.py @@ -16,7 +16,7 @@ from google.protobuf.timestamp_pb2 import Timestamp import proto.CommandExecutor_pb2 as CommandExecutor_pb2 - +import json def get_blueprint_id(request): blueprint_name = request.identifiers.blueprintName @@ -24,7 +24,7 @@ def get_blueprint_id(request): return blueprint_name + '/' + blueprint_version -def build_response(request, results, is_success=True): +def build_response(request, log_results, payload_return, is_success=False): if is_success: status = CommandExecutor_pb2.SUCCESS else: @@ -32,5 +32,9 @@ def build_response(request, results, is_success=True): timestamp = Timestamp() timestamp.GetCurrentTime() - return CommandExecutor_pb2.ExecutionOutput(requestId=request.requestId, response=results, status=status, - timestamp=timestamp) + + if 'cds_return_code' in payload_return: + payload_return.pop('cds_return_code') + payload_str = json.dumps(payload_return) + return CommandExecutor_pb2.ExecutionOutput(requestId=request.requestId, response=log_results, status=status, + payload=payload_str, timestamp=timestamp) diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt index ba5815bb6..509b8ca3a 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt @@ -24,11 +24,14 @@ package org.onap.ccsdk.cds.controllerblueprints.core */ object BluePrintConstants { - const val RESPONSE_HEADER_TRANSACTION_ID: String = "X-ONAP-RequestID" const val RESPONSE_HEADER_MINOR_VERSION: String = "X-MinorVersion" const val RESPONSE_HEADER_PATCH_VERSION: String = "X-PatchVersion" const val RESPONSE_HEADER_LATEST_VERSION: String = "X-LatestVersion" + const val ONAP_REQUEST_ID = "X-ONAP-RequestID" + const val ONAP_INVOCATION_ID = "X-ONAP-InvocationID" + const val ONAP_PARTNER_NAME = "X-ONAP-PartnerName" + const val STATUS_SUCCESS: String = "success" const val STATUS_PROCESSING: String = "processing" const val STATUS_FAILURE: String = "failure" @@ -161,6 +164,8 @@ object BluePrintConstants { const val TOSCA_SCRIPTS_KOTLIN_DIR: String = "$TOSCA_SCRIPTS_DIR/kotlin" const val TOSCA_SCRIPTS_JYTHON_DIR: String = "$TOSCA_SCRIPTS_DIR/python" + const val UAT_SPECIFICATION_FILE = "Tests/uat.yaml" + const val GRAPH_START_NODE_NAME = "START" const val GRAPH_END_NODE_NAME = "END" diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt index 1aaf9d8a4..7aa2fc86c 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt @@ -24,6 +24,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JsonParserUtils import org.slf4j.LoggerFactory import org.slf4j.helpers.MessageFormatter +import java.util.* import kotlin.reflect.KClass /** @@ -36,6 +37,13 @@ fun <T : Any> logger(clazz: T) = LoggerFactory.getLogger(clazz.javaClass)!! fun <T : KClass<*>> logger(clazz: T) = LoggerFactory.getLogger(clazz.java)!! +fun <T : Any> T?.defaultToEmpty(): String { + return this?.toString() ?: "" +} + +fun <T : Any> T?.defaultToUUID(): String { + return this?.toString() ?: UUID.randomUUID().toString() +} fun <T : Any> T.bpClone(): T { return ObjectUtils.clone(this) @@ -175,7 +183,7 @@ fun ArrayNode.asListOfString(): List<String> { fun <T> JsonNode.asType(clazzType: Class<T>): T { return JacksonUtils.readValue(this, clazzType) - ?: throw BluePrintException("couldn't convert JsonNode of type $clazzType") + ?: throw BluePrintException("couldn't convert JsonNode of type $clazzType") } fun JsonNode.asListOfString(): List<String> { @@ -186,8 +194,7 @@ fun JsonNode.asListOfString(): List<String> { fun <T : JsonNode> T?.returnNullIfMissing(): JsonNode? { return if (this == null || this is NullNode || this is MissingNode) { null - } - else this + } else this } fun <T : JsonNode> T?.isNullOrMissing(): Boolean { diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt index 2ddb4503d..6c92d1815 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt @@ -39,13 +39,13 @@ class MDCContextTest { @Test fun testContextCanBePassedBetweenCoroutines() { - MDC.put(BluePrintConstants.RESPONSE_HEADER_TRANSACTION_ID, "12345") + MDC.put(BluePrintConstants.ONAP_REQUEST_ID, "12345") runBlocking { GlobalScope.launch { - assertEquals(null, MDC.get(BluePrintConstants.RESPONSE_HEADER_TRANSACTION_ID)) + assertEquals(null, MDC.get(BluePrintConstants.ONAP_REQUEST_ID)) } launch(MDCContext()) { - assertEquals("12345", MDC.get(BluePrintConstants.RESPONSE_HEADER_TRANSACTION_ID), + assertEquals("12345", MDC.get(BluePrintConstants.ONAP_REQUEST_ID), "couldn't get request id") MDC.put("client_id", "client-1") diff --git a/ms/py-executor/README b/ms/py-executor/README new file mode 100644 index 000000000..919795a3c --- /dev/null +++ b/ms/py-executor/README @@ -0,0 +1,5 @@ + +Generate Server Certificates +------------------------------ + +openssl req -x509 -newkey rsa:4096 -keyout py-executor-key.pem -out py-executor-chain.pem -days 3650 -nodes -subj '/CN=localhost'
\ No newline at end of file diff --git a/ms/py-executor/client.py b/ms/py-executor/client.py new file mode 100644 index 000000000..c5bdc43c8 --- /dev/null +++ b/ms/py-executor/client.py @@ -0,0 +1,67 @@ +# Copyright © 2018-2019 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. +# +# 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. + +import grpc +from blueprints_grpc.proto.BluePrintProcessing_pb2_grpc import BluePrintProcessingServiceStub +from blueprints_grpc.proto.BluePrintProcessing_pb2 import ExecutionServiceInput +from blueprints_grpc.proto.BluePrintCommon_pb2 import CommonHeader, ActionIdentifiers + + +def generate_messages(): + commonHeader = CommonHeader() + commonHeader.requestId = "1234" + commonHeader.subRequestId = "1234-1" + commonHeader.originatorId = "CDS" + + actionIdentifiers = ActionIdentifiers() + actionIdentifiers.blueprintName = "sample-cba" + actionIdentifiers.blueprintVersion = "1.0.0" + actionIdentifiers.actionName = "SampleScript" + + input = ExecutionServiceInput(commonHeader=commonHeader, actionIdentifiers=actionIdentifiers) + + commonHeader2 = CommonHeader() + commonHeader2.requestId = "1235" + commonHeader2.subRequestId = "1234-2" + commonHeader2.originatorId = "CDS" + input2 = ExecutionServiceInput(commonHeader=commonHeader2, actionIdentifiers=actionIdentifiers) + + inputs = [input, input2] + for input in inputs: + print(input) + yield input + + +if __name__ == '__main__': + with open('py-executor-chain.pem', 'rb') as f: + creds = grpc.ssl_channel_credentials(f.read()) + channel = grpc.secure_channel('localhost:50052', creds) + stub = BluePrintProcessingServiceStub(channel) + + messages = generate_messages() + responses = stub.process(messages) + for response in responses: + print(response) diff --git a/ms/py-executor/configuration.ini b/ms/py-executor/configuration.ini index 8c36dd04f..5688f39bd 100644 --- a/ms/py-executor/configuration.ini +++ b/ms/py-executor/configuration.ini @@ -1,6 +1,11 @@ [scriptExecutor] port=%(APP_PORT)s -auth=%(BASIC_AUTH)s +authType=%(AUTH_TYPE)s +# For Token Auth +token=%(AUTH_TOKEN)s +# For TLS Auth +certChain=%(AUTH_CERT_CHAIN)s +privateKey=%(AUTH_PRIVATE_KEY)s logFile=%(LOG_FILE)s maxWorkers=20 diff --git a/ms/py-executor/dc/docker-compose.yaml b/ms/py-executor/dc/docker-compose.yaml index 76009411b..30298e3c0 100755 --- a/ms/py-executor/dc/docker-compose.yaml +++ b/ms/py-executor/dc/docker-compose.yaml @@ -16,7 +16,11 @@ services: STICKYSELECTORKEY: ENVCONTEXT: dev APP_PORT: 50052 - BASIC_AUTH: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== + #AUTH_TYPE: basic-auth + #AUTH_TOKEN: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== + AUTH_TYPE: tls-auth + AUTH_CERT_CHAIN: /opt/app/onap/python/py-executor-chain.pem + AUTH_PRIVATE_KEY: /opt/app/onap/python/py-executor-key.pem LOG_FILE: /opt/app/onap/logs/application.log volumes: diff --git a/ms/py-executor/docker/Dockerfile b/ms/py-executor/docker/Dockerfile index b49daf68f..9e86cc87e 100644 --- a/ms/py-executor/docker/Dockerfile +++ b/ms/py-executor/docker/Dockerfile @@ -1,8 +1,5 @@ FROM python:3.7-slim -ENV HTTP_PROXY ${HTTP_PROXY} -ENV HTTPS_PROXY ${HTTPS_PROXY} - RUN mkdir -p /opt/app/onap/logs/ && touch /opt/app/onap/logs/application.log COPY @project.build.finalName@-@assembly.id@.tar.gz /source.tar.gz @@ -15,4 +12,4 @@ RUN pip install --no-cache-dir -r /opt/app/onap/python/requirements.txt VOLUME /opt/app/onap/blueprints/deploy/ -ENTRYPOINT /opt/app/onap/python/start.sh
\ No newline at end of file +ENTRYPOINT /opt/app/onap/python/start.sh diff --git a/ms/py-executor/docker/distribution.xml b/ms/py-executor/docker/distribution.xml index 6235a7b8a..bb7a8d20a 100755 --- a/ms/py-executor/docker/distribution.xml +++ b/ms/py-executor/docker/distribution.xml @@ -38,6 +38,9 @@ <includes> <include>requirements.txt</include> <include>configuration.ini</include> + <include>*.crt</include> + <include>*.key</include> + <include>*.pem</include> </includes> <useDefaultExcludes>true</useDefaultExcludes> <fileMode>0666</fileMode> diff --git a/ms/py-executor/py-executor-chain.pem b/ms/py-executor/py-executor-chain.pem new file mode 100644 index 000000000..30f09dfea --- /dev/null +++ b/ms/py-executor/py-executor-chain.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpDCCAowCCQDyhR+GR2RUiTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMTkxMDIzMDAwMTA0WhcNMjkxMDIwMDAwMTA0WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCs +c4d6qfbW+GSMp+XURoLXtSAbbehoBXL2beSzqQNW6e+Q9IVtSPZst8VRjUXelFzM +m7VpS9jhiXOPZ5KKUOD0GVuNQc54VpwtHt7t9L5wS9OvdnLijnMIkc0iUvC6+Rcq +HSfbNC2Tb+a8jLwojmtRCeY/MyCnmqYpD+U3b6Eue89VpMOIfmDuTqSRRBYNVO72 +hq7FI3UD8+zREg7htfzjJjG14Ec5iVMDxJA1FlwtXFnZxDHgbLjEVjTTR/9Wm1eU +aJ4oWRt3gG/vnJNa+GwN4w/My+j/5/n/YpNh6GeQrHxBl/SL/SAFBshlwozr4K4K +av5MqRKyhCACV4SsdhKJUEDtvrtukJvh/ZDW8jdNbFJAljm8UucZGbJrZl6G7XB3 +WteI7rezo0mL0NMBZIT3nQSMEpefKUFZFiE5lYvIk3UuChqIM0xdgV4INwLRHZdc +1TtiGaBJV05y3Klo5gaUgNGbHP26zfub5TydiMrOA5W2mUvMkG2oit9aqnbaZBLD +t17cCKzpzcVF5uNUng3j6sQvpTt3S4L28TvKUMAfpecQqvxMoxG0/9HZuv2z+U+L +LVVsS07yJPIGMLcq1LMM++8LwD1MupcoShjNOq/lUOL6hIMfLOIfxt8Kv8WykVzv +6yjKEIurjkwMipq4kvr9J7FFi54kGr7uvXWQRHDFJwIDAQABMA0GCSqGSIb3DQEB +CwUAA4ICAQB7gJzvaOIP3/S2jrObz67g0jiz1cfb4I9KQwpwb6JUWbYm1QjBcGm4 +IhNbdPMD6dpwBc/A4JctA5E+/fArvl14UtK1jkaaE/GCumL0VUSZeAM6CK/63brt +LplqCunv8ePHmiwjJBnhu+ewe1+mDMVDMw0iot/q+pOM3vqNS1Fipja+xFK1JQZx +JmkjW/Ug3NHk/SSTfO+VNmlI5bBBApMqKmd9picsyDZ7dTBtZvbqV5eQsPZvv14G +oEvWnvvom+D5GojroSO+OMHNDR3bzK6p0Cu8AiTy9Ls6J2e4GXJz3Cg/kuF9tNlR +3X62zDT+CUipuYyTvmjbSyNMGwU7BIZTKFPuTtjh7EwT2g6S8RV9PmT98CQW6kTT +RJbL7nMIOF0WusysAT5wj1HJ0QKBQCXK+L6WTKTTovaEE7JSVrYe7wVF8Q9SyBIM +4CPVZt+GMyQKJ9SRnVgTDEMb7sj9HPaoVeDc6LQTv8Q//wFeTdZIWXQhpVJCQCEG +qkRk9r3isF60ISOXXIYhqE+hx3QXY9M2UyHDtKXPZ7X370vADi2ebBMF8MpIZYl5 +628dME9JhOhLhD5qPJeva2Nq4gLpK+rO6t7ML0Us4edoKyoScowXAh80q1GW3EO3 +IxTK123651C/S0kDqLqZ9rknEdpwSujrT2UW95jUlfo5OKDrPpdOBw== +-----END CERTIFICATE----- diff --git a/ms/py-executor/py-executor-key.pem b/ms/py-executor/py-executor-key.pem new file mode 100644 index 000000000..830a3ae21 --- /dev/null +++ b/ms/py-executor/py-executor-key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCsc4d6qfbW+GSM +p+XURoLXtSAbbehoBXL2beSzqQNW6e+Q9IVtSPZst8VRjUXelFzMm7VpS9jhiXOP +Z5KKUOD0GVuNQc54VpwtHt7t9L5wS9OvdnLijnMIkc0iUvC6+RcqHSfbNC2Tb+a8 +jLwojmtRCeY/MyCnmqYpD+U3b6Eue89VpMOIfmDuTqSRRBYNVO72hq7FI3UD8+zR +Eg7htfzjJjG14Ec5iVMDxJA1FlwtXFnZxDHgbLjEVjTTR/9Wm1eUaJ4oWRt3gG/v +nJNa+GwN4w/My+j/5/n/YpNh6GeQrHxBl/SL/SAFBshlwozr4K4Kav5MqRKyhCAC +V4SsdhKJUEDtvrtukJvh/ZDW8jdNbFJAljm8UucZGbJrZl6G7XB3WteI7rezo0mL +0NMBZIT3nQSMEpefKUFZFiE5lYvIk3UuChqIM0xdgV4INwLRHZdc1TtiGaBJV05y +3Klo5gaUgNGbHP26zfub5TydiMrOA5W2mUvMkG2oit9aqnbaZBLDt17cCKzpzcVF +5uNUng3j6sQvpTt3S4L28TvKUMAfpecQqvxMoxG0/9HZuv2z+U+LLVVsS07yJPIG +MLcq1LMM++8LwD1MupcoShjNOq/lUOL6hIMfLOIfxt8Kv8WykVzv6yjKEIurjkwM +ipq4kvr9J7FFi54kGr7uvXWQRHDFJwIDAQABAoICADepPmRAMbTnDYU8t/jRHXBE +PO29htL0V0vk4nl+pt5JuZJe6iYA89DZa+3LnG6gEmfUJjSrT4BUXiE+O9U7D7CZ +8qvgPqUmx1fk6+2AHmuefd/XanNnqQduD/jxLlQbC/gC2xdsev1ok9/tyNmKRmcs +u81QUkzmpJUCVWiUNkELozswaBBJQj4I0iM1B60b6dlWVVi5/g3dkGVW38jIdaxX +apoansKaaVoA+s63vd7CPRoFsleOoAB3FqvPREIO97CmJ848HJpwsTB0qDcnkbDV +xgbDFhxrIozko09ptOvEUILXag45EDmvG8WEivmjVml0aUoTFD7cWHyJBQCpR4fU +5W9mYd4Rrzbmpb+LGYdNyrp3wo3C7dJ7/ffBMQxmXTdMZkcxorxj4BRG3oACRQ1u +Ff1iUruZzIIDtEkrC9hc5QpLlDf9b1obm8L9sxf1QmTt59o5oFG40GPwPP19GXwE +l2faHwho2jYLM9rhuSsK/5sSmUshPNQYmfMnbWzTtghMPE/g0Cfpt8qbspq+G1bk +z3M97JlFMF83ccRotDElX9E/ttjU7Lehoz+1sOyHiVW1E4oqKer4t+nI2bp6VYZm +W94qptW7kb4o0DsvPCaoTPBxLJ1ag2WBlqoFkVI0YaxZiZ8OTR55Ovi4z5xWBO1q +NkCKgdAUQvQVzVtASVGBAoIBAQDSw2nvPFN4gGZ6OI+8j2gWtPcsrhSHS9ykxBeB +mB/HExYIe8k3EvClf2rnfwzuKgKyVMp7Ev7nH2jS/PGZq37QyXrw0NBGRnvJY0Ez +YB1KTgf9xaHMGMut5efNvv/cPwYriqosgJ0pdt0vvUAIQ6EBv+iDXXqJ1lQUSRYk +wKjFABi6TeJY4t9vC474KoXTDaHlwn9+TwnuRBk85wrZzlhK90J0iVa9/Eqeddsc +Z3CuTlc+NmcP3qvniYODq8nyVc0pKw+28AVYYEd3aJfgm+dpcB21L0oz7CaxH/Rz +FNONuQRaOzJrcuJsde/KG2X+MHs6hVMXXXWciPrJ2l+Cq7dnAoIBAQDRdwZDcgem +tJHLihCRzUl9PKip4ZA5757ZyTy6WMLR3wMS2cNTK8+bTrUa0SSC4WSI28pybFA7 +QdSR08c5Nd7jXcIrtqspgZKhb0E60i8VQHhh6ba/kyQjsEz9c/G1WquPK13j2vZ0 +79bomDwFJPsFzABU+sC0/F42ZVQzy9qXkjngjtmaGfrCc7X+pV28nEGtyxHci3L4 +XXfE2dOb+GBVZPLBVXwcthdRYsFuU9GMy2GH0zVtWPOcGRnlpx53Tqg7NIeR0Nm1 +K35EaK8PH92PsAr0Xza7vQHY4cPRz+RhDzjyGQtnhKf96U6gzzt4ZVbQ/UuzDBcL +PQ2DvUH+sqxBAoIBAEW5kiUsDu0xhTVv2tVll+jTK2ZjnLT5ut/jY2djHTgtrz9V +PEb1BBmsIoC9PljYGxZGCMpYiW2KrZIHTiIpYwXNcdeTLSPik3cXV+2YIXiAghJJ +PHKZzWAVS+97/YcubmsfL5cTYWrjQN9XO4TAYtaCV3iGB1DsT9p6J1I3Tl4F3yhb +NcN0IrjI2R5uauFchC/PfYAaw81ISBUm1iciJYF/dUO6X7DwcvsjQD6QVe3ESwZw +1v2gC7zIeHKp9WAvVHUHIubBVvNavqnZN01+JjtydNGI+IJe4Jn+WU9tF2OuTqtP +JCn50sBQ7+gr0j0aatn8W3XCXHNRua3niWtgRYcCggEAT7OzfWxhPuyMYV9qiKAN +a4ruPp3mjDUCQ6pP4jQuBT+PYtfbe8U63MSpIsgb1XVAFNdVBA70xGd7I/XqY3l9 +ExS08n8yR7vW+Hhl4KTjZ3m9lLwiXmj1omLOGM7KVRBoITUGJ9JEXyB3rM9oXyjA +H2eNZMh5FSTGEHqj/IV/6paoUSrp37os8VqoEHoJ3d+zGhcf98RT/e9KyGt+GmX6 ++eNMf4YwkJg07THfmkRoguNMfCtAtBfZsjbW5MyfShRy7PxC7ZgDju06wXr3yZB9 +dNQuhufH4s27azQUl7w8ETaCm5QuA7i1V2c0FPpljZ052JHZAQsDpbIYd11HREvm +QQKCAQEA0W7xNYoFvnyikdG0t266LLv1EkWDFdgkelGx/eGe/JZ+au3uTM94EssC +ni64XX2P8vK/te+c3jItYO4MRgnDJ7GW+bRnJFu2kBE0W4chx7vga0XApVCP+Ugg +owv5yf9cOAHFulvPefsU0snYStD3gNq77XDg0CwoyUkpeq+GiupoQ8tquMSsrEwp +ve5DtDip3cLHz2oVLB3mR4kKVwVwmOgO5RKq6N/H6Jxtf/Zk1I260dKr+Dv2MnDh +dysO4zH5YEt2ML3oY4zY8lu+I5bHCBR1updSny0B31WrXAJyfZpMx+HOwETFKa3B +v9AGKz0Jc2GOIRKHrCQ/WkZePetaYQ== +-----END PRIVATE KEY----- diff --git a/ms/py-executor/server.py b/ms/py-executor/server.py index 5c149d96b..f506e9446 100644 --- a/ms/py-executor/server.py +++ b/ms/py-executor/server.py @@ -33,21 +33,45 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 def serve(configuration: ScriptExecutorConfiguration): port = configuration.script_executor_property('port') - basic_auth = configuration.script_executor_property('auth') + authType = configuration.script_executor_property('authType') maxWorkers = configuration.script_executor_property('maxWorkers') - header_validator = RequestHeaderValidatorInterceptor( - 'authorization', basic_auth, grpc.StatusCode.UNAUTHENTICATED, - 'Access denied!') + if authType == 'tls-auth': + cert_chain_file = configuration.script_executor_property('certChain') + private_key_file = configuration.script_executor_property('privateKey') + logger.info("Setting GRPC server TLS authentication, cert file(%s) private key file(%s)", cert_chain_file, + private_key_file) + # read in key and certificate + with open(cert_chain_file, 'rb') as f: + certificate_chain = f.read() + with open(private_key_file, 'rb') as f: + private_key = f.read() - server = grpc.server(futures.ThreadPoolExecutor(max_workers=int(maxWorkers)), - interceptors=(header_validator,)) + # create server credentials + server_credentials = grpc.ssl_server_credentials(((private_key, certificate_chain),)) - BluePrintProcessing_pb2_grpc.add_BluePrintProcessingServiceServicer_to_server( - BluePrintProcessingServer(configuration), server) + # create server + server = grpc.server(futures.ThreadPoolExecutor(max_workers=int(maxWorkers))) + BluePrintProcessing_pb2_grpc.add_BluePrintProcessingServiceServicer_to_server( + BluePrintProcessingServer(configuration), server) - server.add_insecure_port('[::]:' + port) - server.start() + # add secure port using credentials + server.add_secure_port('[::]:' + port, server_credentials) + server.start() + else: + logger.info("Setting GRPC server base authentication") + basic_auth = configuration.script_executor_property('token') + header_validator = RequestHeaderValidatorInterceptor( + 'authorization', basic_auth, grpc.StatusCode.UNAUTHENTICATED, + 'Access denied!') + # create server with token authentication interceptors + server = grpc.server(futures.ThreadPoolExecutor(max_workers=int(maxWorkers)), + interceptors=(header_validator,)) + BluePrintProcessing_pb2_grpc.add_BluePrintProcessingServiceServicer_to_server( + BluePrintProcessingServer(configuration), server) + + server.add_insecure_port('[::]:' + port) + server.start() logger.info("Command Executor Server started on %s" % port) diff --git a/ms/sdclistener/distribution/src/main/docker/Dockerfile b/ms/sdclistener/distribution/src/main/docker/Dockerfile index e945188a8..34f6443bf 100755 --- a/ms/sdclistener/distribution/src/main/docker/Dockerfile +++ b/ms/sdclistener/distribution/src/main/docker/Dockerfile @@ -1,8 +1,5 @@ FROM openjdk:8-jdk-alpine -ENV HTTP_PROXY ${HTTP_PROXY} -ENV HTTPS_PROXY ${HTTPS_PROXY} - # add entrypoint COPY startService.sh /startService.sh RUN chmod 751 /startService.sh |