diff options
65 files changed, 1442 insertions, 238 deletions
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 f8cfc888e..ef6880d37 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 @@ -37,7 +37,18 @@ limitations under the License. <mat-sidenav #drawer mode="side" [(opened)]="opened" (opened)="events.push('open!')" (closed)="events.push('close!')"> <mat-toolbar color="" primary>Menu</mat-toolbar> <mat-nav-list> - <a mat-list-item [routerLink]="['/blueprint']">Controller Blueprint</a> + <!-- <a mat-list-item [routerLink]="['/blueprint']">Controller Blueprint</a> --> + <nav class="ng-tns-c12-2 ng-star-inserted"> + <!-- <button class="docs-nav-content-btn" cdkaccordionitem="" expanded="true" + aria-label="Form Controls, section toggle" aria-controls="panel-forms" aria-expanded="false">--> + <label>Controller Blueprint</label> + <!-- <mat-icon class="mat-icon notranslate material-icons mat-icon-no-color" role="img" aria-hidden="true"> + keyboard_arrow_down</mat-icon></button> --> + <ul> + <a mat-list-item [routerLink]="['/blueprint']">Create Blueprint</a> + <a mat-list-item [routerLink]="['/']">Search Blueprint</a> + </ul> + </nav> <a mat-list-item [routerLink]="['/resource-definition']">Resource Definition</a> </mat-nav-list> </mat-sidenav> diff --git a/cds-ui/client/src/app/common/shared/components/home/home.component.scss b/cds-ui/client/src/app/common/shared/components/home/home.component.scss index df9a48de5..be21b750c 100644 --- a/cds-ui/client/src/app/common/shared/components/home/home.component.scss +++ b/cds-ui/client/src/app/common/shared/components/home/home.component.scss @@ -26,22 +26,41 @@ limitations under the License. // left: 0; // right: 0; // } - // .example-events { // width: 300px; // height: 200px; // overflow: auto; // border: 1px solid #555; // } -.mat-sidenav-container{ +.mat-sidenav-container { height: 652px; } -.mat-button.mat-primary, .mat-icon-button.mat-primary, .mat-stroked-button.mat-primary { + +.mat-button.mat-primary, +.mat-icon-button.mat-primary, +.mat-stroked-button.mat-primary { color: white !important; } -.menuBar{ + +.menuBar { cursor: pointer; } -.title{ + +.title { margin: 1em; +} + +.docs-component-viewer-nav .docs-component-viewer-nav-content button { + padding: 10px 15px; + font-weight: 700; + line-height: 16px; + margin: 0; + font-size: 13px; + cursor: pointer; + position: relative; + display: block; + width: 100%; + text-align: left; + background: 0 0; + border: none; }
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/blueprint/blueprint.module.ts b/cds-ui/client/src/app/feature-modules/blueprint/blueprint.module.ts index 3a25e92f0..ae4df4ccf 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/blueprint.module.ts +++ b/cds-ui/client/src/app/feature-modules/blueprint/blueprint.module.ts @@ -30,7 +30,7 @@ import { SelectTemplateModule } from './select-template/select-template.module'; import { ModifyTemplateModule } from './modify-template/modify-template.module'; import { DeployTemplateModule } from './deploy-template/deploy-template.module'; import { TestTemplateModule } from './test-template/test-template.module'; - +import { SearchEditCBAComponent } from './search-edit-cba/search-edit-cba.component'; import { AppMaterialModule } from '../../../app/common/modules/app-material.module'; @NgModule({ @@ -45,7 +45,8 @@ import { AppMaterialModule } from '../../../app/common/modules/app-material.modu SelectTemplateModule, ModifyTemplateModule, DeployTemplateModule, - TestTemplateModule + TestTemplateModule, + SearchEditCBAComponent ] }) export class BlueprintModule { } diff --git a/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.html b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.html new file mode 100644 index 000000000..7371d2105 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.html @@ -0,0 +1,16 @@ +/* ============LICENSE_START========================================== =================================================================== Copyright (C) 2018 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============================================ */ + +<form class="search-form" [formGroup]="myControl"> + <mat-form-field class="search-full-width"> + <input #resourceSelect type="text" [(ngModel)]="searchText" placeholder="Search Resources" matInput [matAutocomplete]="auto" formControlName="search_input"> + <button matSuffix mat-icon-button (click)="fetchResourceByName()"><mat-icon>search</mat-icon></button> + <!-- <mat-autocomplete #auto="matAutocomplete"> + <mat-option (click)="selected(option)" *ngFor="let option of options | search : searchText" [value]="option.tags"> + {{option.tags}} + </mat-option> + </mat-autocomplete> --> + </mat-form-field> +</form>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.scss b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.scss diff --git a/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.spec.ts b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.spec.ts new file mode 100644 index 000000000..78210cf12 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchEditCBAComponent } from './search-edit-cba.component'; + +describe('SearchEditCBAComponent', () => { + let component: SearchEditCBAComponent; + let fixture: ComponentFixture<SearchEditCBAComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchEditCBAComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchEditCBAComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.ts new file mode 100644 index 000000000..14a79e0f1 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint/search-edit-cba/search-edit-cba.component.ts @@ -0,0 +1,67 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright 2019 TechMahindra +* +* Modifications Copyright (C) 2019 IBM +*================================================================================= +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* ============LICENSE_END========================================================= +*/ + +import { Component, OnInit, ViewChild, EventEmitter, Output } from '@angular/core'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; + +import { MatAutocompleteTrigger } from '@angular/material' +@Component({ + selector: 'app-search-edit-cba', + templateUrl: './search-edit-cba.component.html', + styleUrls: ['./search-edit-cba.component.scss'] +}) +export class SearchEditCBAComponent implements OnInit { + + myControl: FormGroup; + @Output() resourcesData = new EventEmitter(); + options: any[] = []; + //['One','One1', 'Two', 'Three']; + // @ViewChild('resourceSelect') resourceSelect; + @ViewChild('resourceSelect', { read: MatAutocompleteTrigger }) resourceSelect: MatAutocompleteTrigger; + + searchText: string = ''; + constructor(private _formBuilder: FormBuilder, + ) { } + + ngOnInit() { + this.myControl = this._formBuilder.group({ + search_input: ['', Validators.required] + }); + } + selected(value){ + this.resourcesData.emit(value); + } + + fetchResourceByName() { + // this.exsistingModelService.searchByTags(this.searchText) + // .subscribe(data=>{ + // console.log(data); + // data.forEach(element => { + // this.options.push(element) + // }); + // this.resourceSelect.openPanel(); + // }, error=>{ + // window.alert('error' + error); + // }) + } + +} diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.html b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.html index b58be9fce..491c5e06d 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.html +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.html @@ -18,9 +18,24 @@ See the License for the specific language governing permissions and limitations under the License. ============LICENSE_END============================================ --> -<div> - <input type="file" accept=".zip" (change)="fileChanged($event)"> +<div *ngIf="optionSelected==1"> + <div> + <input type="file" accept=".zip" (change)="fileChanged($event)"> + </div> + <div> + <button mat-button matStepperNext (click)="updateBlueprintState()" [ngClass]="{'mat-upload-btn-disabled': !validfile, 'matStepNextBtn': validfile}" [disabled]="!validfile">Upload</button> + </div> </div> -<div> - <button mat-button matStepperNext (click)="updateBlueprintState()" [ngClass] = "{'mat-upload-btn-disabled': !validfile, 'matStepNextBtn': validfile}" [disabled]="!validfile">Upload</button> +<div *ngIf="optionSelected==2"> + <form class="search-form" [formGroup]="myControl"> + <mat-form-field class="search-full-width"> + <input #resourceSelect type="text" [(ngModel)]="searchText" placeholder="Search Resources" matInput [matAutocomplete]="auto" formControlName="search_input"> + <button matSuffix mat-icon-button (click)="fetchResourceByName()"><mat-icon>search</mat-icon></button> + <!-- <mat-autocomplete #auto="matAutocomplete"> + <mat-option (click)="selected(option)" *ngFor="let option of options | search : searchText" [value]="option.tags"> + {{option.tags}} + </mat-option> + </mat-autocomplete> --> + </mat-form-field> + </form> </div>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.ts index 1221e8f2b..64352b224 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.ts +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.component.ts @@ -19,7 +19,7 @@ limitations under the License. ============LICENSE_END============================================ */ -import { Component, OnInit, EventEmitter, Output, ViewChild } from '@angular/core'; +import { Component, OnInit, EventEmitter, Output, ViewChild, Input } from '@angular/core'; import { Store } from '@ngrx/store'; import * as JSZip from 'jszip'; import { Observable } from 'rxjs'; @@ -31,6 +31,8 @@ import { LoadBlueprintSuccess, SET_BLUEPRINT_STATE, SetBlueprintState } from '.. import { json } from 'd3'; import { SortPipe } from '../../../../common/shared/pipes/sort.pipe'; import { LoaderService } from '../../../../common/core/services/loader.service'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { MatAutocompleteTrigger } from '@angular/material'; @Component({ selector: 'app-search-template', @@ -47,6 +49,12 @@ export class SearchTemplateComponent implements OnInit { uploadedFileName: string; @ViewChild('fileInput') fileInput; result: string = ''; + @Input() optionSelected: string; + myControl: FormGroup; + @ViewChild('resourceSelect', { read: MatAutocompleteTrigger }) resourceSelect: MatAutocompleteTrigger; + @Output() resourcesData = new EventEmitter(); + options: any[] = []; + searchText: string = ''; private paths = []; private tree; @@ -57,11 +65,30 @@ export class SearchTemplateComponent implements OnInit { private blueprintName: string; private entryDefinition: string; - constructor(private store: Store<IAppState>, private loader: LoaderService) { } + constructor(private store: Store<IAppState>, private loader: LoaderService,private formBuilder: FormBuilder) { } ngOnInit() { + this.myControl = this.formBuilder.group({ + search_input: ['', Validators.required] + }); + } + + selected(value) { + this.resourcesData.emit(value); } + fetchResourceByName() { + // this.exsistingModelService.searchByTags(this.searchText) + // .subscribe(data => { + // console.log(data); + // data.forEach(element => { + // this.options.push(element) + // }); + // this.resourceSelect.openPanel(); + // }, error => { + // window.alert('error' + error); + // }) + } fileChanged(e: any) { this.paths = []; this.file = e.target.files[0]; diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.service.spec.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.service.spec.ts new file mode 100644 index 000000000..418b7e9ca --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { SearchTemplateService } from './search-template.service'; + +describe('SearchTemplateService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: SearchTemplateService = TestBed.get(SearchTemplateService); + expect(service).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.service.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.service.ts new file mode 100644 index 000000000..fdb261d52 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { ApiService } from '../../../../common/core/services/api.service'; + +@Injectable({ + providedIn: 'root' +}) +export class SearchTemplateService { + + constructor(private _http: HttpClient, private api: ApiService) { } + + searchByTags(uri: string, searchText: String): Observable<any>{ + return this.api.post(uri, searchText); + } +} diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.html b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.html index d11b37144..97c65b220 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.html +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.html @@ -22,7 +22,7 @@ limitations under the License. <mat-step [stepControl]="step1FormGroup"> <ng-template matStepLabel>Choose CBA Template file</ng-template> <div class="matStepContent"> - <app-template-options></app-template-options> + <app-template-options (option)="templateSelected($event)"></app-template-options> <br> <div> <button mat-button matStepperNext class="matStepNextBtn">Proceed</button> @@ -30,10 +30,10 @@ limitations under the License. </div> </mat-step> - <mat-step [stepControl]="step2FormGroup"> + <mat-step [stepControl]="step2FormGroup" *ngIf="templateOption==1 || templateOption == 2"> <ng-template matStepLabel>Browse CBA Template file</ng-template> <div class="matStepContent"> - <app-search-template (cbaFile)="fileChange($event)"></app-search-template> + <app-search-template [optionSelected]="templateOption" (cbaFile)="fileChange($event)"></app-search-template> <!-- <div> <button mat-button matStepperNext class="matStepNextBtn">Upload</button> </div>--> diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.ts index d9591dd80..561f15a5d 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.ts +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.component.ts @@ -38,6 +38,7 @@ export class SelectTemplateComponent implements OnInit { metaData: IMetaData; blueprintState: IBlueprintState; importModel: IImportModel; + templateOption: any; constructor(private store: Store<IBlueprintState>) { // this.importModel.file = ''; @@ -45,6 +46,12 @@ export class SelectTemplateComponent implements OnInit { ngOnInit() { } + + templateSelected(option: any) { + this.templateOption = option; + console.log(this.templateOption); + } + fileChange(topologyTemp: ITopologyTemplate) { this.topologyTemplate = topologyTemp; console.log(topologyTemp); @@ -57,6 +64,7 @@ export class SelectTemplateComponent implements OnInit { upload() { } + // saveBlueprintModel(){ // this.blueprint.toplogyTemplates=this.topologyTemplate; // this.blueprint.metadata= this.metaData; diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/template-options/template-options.component.html b/cds-ui/client/src/app/feature-modules/blueprint/select-template/template-options/template-options.component.html index d66b559f3..57ff00df5 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/template-options/template-options.component.html +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/template-options/template-options.component.html @@ -19,7 +19,7 @@ limitations under the License. ============LICENSE_END============================================ --> <mat-radio-group> - <mat-radio-button value="1" (click)="selected(1)">Upload Template file</mat-radio-button><br><br> - <!-- <mat-radio-button value="2" (click)="selected(2)">Starter Template</mat-radio-button><br><br> - <mat-radio-button value="3" (click)="selected(3)">Existing Model File</mat-radio-button> --> + <mat-radio-button value="1" (click)="selected(1)">Upload Template file</mat-radio-button><br> <br> + <mat-radio-button value="2" (click)="selected(2)">Starter Template</mat-radio-button><br> <br> + <mat-radio-button value="3" (click)="selected(3)">Existing Model File</mat-radio-button> </mat-radio-group>
\ No newline at end of file diff --git a/cds-ui/server/config/app-config.ts b/cds-ui/server/config/app-config.ts deleted file mode 100644 index 80f246427..000000000 --- a/cds-ui/server/config/app-config.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const controllerApiConfig = Object.freeze({ - url: process.env.API_BLUEPRINT_CONTROLLER_BASE_URL || "http://localhost:8080/api/v1", - authToken: process.env.API_BLUEPRINT_CONTROLLER_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==" -}); - -export const processorApiConfig = Object.freeze({ - url: process.env.API_BLUEPRINT_PROCESSOR_BASE_URL || "http://localhost:8081/api/v1", - authToken: process.env.API_BLUEPRINT_PROCESSOR_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==" -});
\ No newline at end of file diff --git a/cds-ui/server/package.json b/cds-ui/server/package.json index 5b8f7e67c..2f33abae7 100644 --- a/cds-ui/server/package.json +++ b/cds-ui/server/package.json @@ -12,7 +12,7 @@ }, "scripts": { "build:apidocs": "lb-apidocs", - "build": "lb-tsc es2017 --outDir dist", + "build": "npm run copy:proto && lb-tsc es2017 --copy-resources --outDir dist", "build:watch": "lb-tsc --watch", "clean": "lb-clean dist", "lint": "npm run prettier:check && npm run tslint", @@ -29,7 +29,8 @@ "migrate": "node ./dist/src/migrate", "prestart": "npm run build", "start": "node .", - "prepublishOnly": "npm run test" + "prepublishOnly": "npm run test", + "copy:proto": "mkdir -p dist; cp -R target/generated/proto-definition/proto/ dist/proto" }, "repository": { "type": "git" @@ -45,6 +46,7 @@ "src" ], "dependencies": { + "@grpc/proto-loader": "^0.5.1", "@loopback/boot": "^1.0.8", "@loopback/context": "^1.16.0", "@loopback/core": "^1.1.3", @@ -55,6 +57,7 @@ "@loopback/service-proxy": "^1.0.8", "@types/form-data": "^2.2.1", "@types/jszip": "^3.1.5", + "@types/uuid": "^3.4.4", "bluebird": "^3.5.3", "cors": "^2.8.5", "file": "^0.2.2", @@ -63,11 +66,13 @@ "form-data": "^2.3.3", "formidable": "^1.2.1", "fs": "0.0.1-security", + "grpc": "^1.21.1", "jszip": "^3.2.1", "loopback-connector-rest": "^3.4.1", "multer": "^1.4.1", "multiparty": "^4.2.1", "nodemon": "^1.18.10", + "uuid": "^3.3.2", "winston": "^3.2.1" }, "devDependencies": { diff --git a/cds-ui/server/pom.xml b/cds-ui/server/pom.xml index ae9b1b293..8d758c710 100644 --- a/cds-ui/server/pom.xml +++ b/cds-ui/server/pom.xml @@ -42,9 +42,38 @@ limitations under the License. <docker.push.phase>deploy</docker.push.phase> </properties> + <build> <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <version>3.1.1</version> + <executions> + <execution> + <id>unpack-blueprint-grpc-proto</id> + <phase>generate-resources</phase> + <goals> + <goal>unpack</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>org.onap.ccsdk.cds.components</groupId> + <artifactId>proto-definition</artifactId> + <version>${project.version}</version> + <type>jar</type> + <overWrite>true</overWrite> + <outputDirectory>${project.build.directory}/generated/proto-definition/proto</outputDirectory> + <includes>**/*.proto</includes> + </artifactItem> + </artifactItems> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <!-- Use the latest released version: https://repo1.maven.org/maven2/com/github/eirslett/frontend-maven-plugin/ --> 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 new file mode 100644 index 000000000..b66b2a771 --- /dev/null +++ b/cds-ui/server/src/clients/blueprint-management-service-grpc-client.ts @@ -0,0 +1,86 @@ +/** + ~ Copyright © 2019 Bell Canada. + ~ + ~ 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 * 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'; + +const PROTO_PATH = processorApiConfig.grpc.bluePrintManagement.protoPath; + +// Suggested options for similarity to existing grpc.load behavior +const packageDefinition: protoLoader.PackageDefinition = protoLoader.loadSync( + PROTO_PATH, + { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true + }); + +const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); +// The protoDescriptor object has the full package hierarchy + +const stub = new protoDescriptor.org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementService( + "" + processorApiConfig.grpc.host + ":" + processorApiConfig.grpc.port + "", + grpc.credentials.createInsecure()); + +const metadata = new grpc.Metadata(); +metadata.add('Authorization', processorApiConfig.grpc.authToken); + +class BluePrintManagementServiceGrpcClient { + + async uploadBlueprint(filePath: string): Promise<any> { + + let input = { + commonHeader: { + timestamp: new Date(), + originatorId: "cds-ui", + requestId: uuidv1(), + subRequestId: "1234-56", + }, + fileChunk: { + chunk: fs.readFileSync(filePath) + } + } + + let removeTempFile = () => { + fs.unlink(filePath, (err: any) => { + if (err) { + console.error(err); + } + }); + } + + return new Promise<any>((resolve, reject) => { + stub.uploadBlueprint(input, metadata, (err: any, output: any) => { + if (err) { + removeTempFile(); + reject(err); + return; + } + + removeTempFile(); + 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 new file mode 100644 index 000000000..24aeb26b5 --- /dev/null +++ b/cds-ui/server/src/config/app-config.ts @@ -0,0 +1,47 @@ +/** + ~ Copyright © 2019 Bell Canada. + ~ + ~ 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. +*/ +export const appConfig = Object.freeze({ + action: Object.freeze({ + deployBlueprint: Object.freeze({ + grpcEnabled: process.env.APP_ACTION_DEPLOY_BLUEPRINT_GRPC_ENABLED || true + }) + }) +}); + +export const controllerApiConfig = Object.freeze({ + http: Object.freeze({ + url: process.env.API_BLUEPRINT_CONTROLLER_HTTP_BASE_URL || "http://localhost:8080/api/v1", + authToken: process.env.API_BLUEPRINT_CONTROLLER_HTTP_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==" + }) +}); + +export const processorApiConfig = Object.freeze({ + http: Object.freeze({ + url: process.env.API_BLUEPRINT_PROCESSOR_HTTP_BASE_URL || "http://localhost:8081/api/v1", + authToken: process.env.API_BLUEPRINT_PROCESSOR_HTTP_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==" + }), + grpc: Object.freeze({ + host: process.env.API_BLUEPRINT_PROCESSOR_GRPC_HOST || "localhost", + port: process.env.API_BLUEPRINT_PROCESSOR_GRPC_PORT || 9111, + authToken: process.env.API_BLUEPRINT_PROCESSOR_GRPC_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==", + bluePrintManagement: Object.freeze({ + //this path is relative to 'dist' folder + protoPath: __dirname + '../../../proto/BluePrintManagement.proto' + }) + }) +}); + + diff --git a/cds-ui/server/src/controllers/blueprint-rest.controller.ts b/cds-ui/server/src/controllers/blueprint-rest.controller.ts index 877fa02bb..52e77ee7b 100644 --- a/cds-ui/server/src/controllers/blueprint-rest.controller.ts +++ b/cds-ui/server/src/controllers/blueprint-rest.controller.ts @@ -48,7 +48,8 @@ import { BlueprintService } from '../services'; import * as fs from 'fs'; import * as multiparty from 'multiparty'; import * as request_lib from 'request'; -import {controllerApiConfig, processorApiConfig} from '../../config/app-config'; +import {controllerApiConfig, processorApiConfig, appConfig} from '../config/app-config'; +import {bluePrintManagementServiceGrpcClient} from '../clients/blueprint-management-service-grpc-client'; export class BlueprintRestController { constructor( @@ -197,11 +198,10 @@ export class BlueprintRestController { ): Promise<Response> { return new Promise((resolve, reject) => { this.getFileFromMultiPartForm(request).then(file=>{ - this.uploadFileToBlueprintProcessor(file, "/execution-service/upload/", response).then(resp=>{ - resolve(resp); - }, err=>{ - reject(err); - }); + if(appConfig.action.deployBlueprint.grpcEnabled) + return this.uploadFileToBlueprintProcessorGrpc(file, response); + else + return this.uploadFileToBlueprintProcessor(file, "/execution-service/upload/", response); }, err=>{ reject(err); }); @@ -209,11 +209,11 @@ export class BlueprintRestController { } async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response>{ - return this.uploadFileToBlueprintService(file, controllerApiConfig.url + uri, controllerApiConfig.authToken, response); + return this.uploadFileToBlueprintService(file, controllerApiConfig.http.url + uri, controllerApiConfig.http.authToken, response); } async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<Response>{ - return this.uploadFileToBlueprintService(file, processorApiConfig.url + uri, processorApiConfig.authToken, response); + return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response); } async uploadFileToBlueprintService(file: multiparty.File, url: string, authToken: string, response: Response): Promise<Response>{ @@ -256,7 +256,7 @@ export class BlueprintRestController { } async downloadFileFromBlueprintController(uri: string, response: Response): Promise<Response> { - return this.downloadFileFromBlueprintService(controllerApiConfig.url + uri, controllerApiConfig.authToken, response); + return this.downloadFileFromBlueprintService(controllerApiConfig.http.url + uri, controllerApiConfig.http.authToken, response); } async downloadFileFromBlueprintService(url: string, authToken: string, response: Response): Promise<Response> { @@ -277,4 +277,16 @@ export class BlueprintRestController { }); }) } + + async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, response: Response): Promise<Response> { + return new Promise<Response>((resolve, reject) => { + bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path).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/cds-ui/server/src/datasources/blueprint.datasource-template.ts b/cds-ui/server/src/datasources/blueprint.datasource-template.ts index f5dad3a1e..35edf33e3 100644 --- a/cds-ui/server/src/datasources/blueprint.datasource-template.ts +++ b/cds-ui/server/src/datasources/blueprint.datasource-template.ts @@ -1,19 +1,19 @@ -import {controllerApiConfig} from '../../config/app-config'; +import {controllerApiConfig} from '../config/app-config'; export default { "name": "blueprint", "connector": "rest", - "baseURL": controllerApiConfig.url, + "baseURL": controllerApiConfig.http.url, "crud": false, "debug": true, "operations": [{ "template": { "method": "GET", - "url": controllerApiConfig.url + "/blueprint-model/", + "url": controllerApiConfig.http.url + "/blueprint-model/", "headers": { "accepts": "application/json", "content-type": "application/json", - "authorization": controllerApiConfig.authToken + "authorization": controllerApiConfig.http.authToken }, "responsePath": "$.*" }, diff --git a/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts b/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts index 1c459e0e7..c749eee62 100644 --- a/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts +++ b/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts @@ -1,19 +1,19 @@ -import {controllerApiConfig} from '../../config/app-config'; +import {controllerApiConfig} from '../config/app-config'; export default { "name": "resourceDictionary", "connector": "rest", - "baseURL": controllerApiConfig.url + "/dictionary", + "baseURL": controllerApiConfig.http.url + "/dictionary", "crud": false, "debug": true, "operations": [{ "template": { "method": "GET", - "url": controllerApiConfig.url + "/dictionary/{name}", + "url": controllerApiConfig.http.url + "/dictionary/{name}", "headers": { "accepts": "application/json", "content-type": "application/json", - "authorization": controllerApiConfig.authToken + "authorization": controllerApiConfig.http.authToken }, "responsePath": "$.*" }, @@ -25,11 +25,11 @@ export default { { "template": { "method": "GET", - "url": controllerApiConfig.url + "/dictionary/source-mapping", + "url": controllerApiConfig.http.url + "/dictionary/source-mapping", "headers": { "accepts": "application/json", "content-type": "application/json", - "authorization": controllerApiConfig.authToken + "authorization": controllerApiConfig.http.authToken }, "responsePath": "$.*" }, @@ -41,11 +41,11 @@ export default { { "template": { "method": "GET", - "url": controllerApiConfig.url + "/dictionary/search/{tags}", + "url": controllerApiConfig.http.url + "/dictionary/search/{tags}", "headers": { "accepts": "application/json", "content-type": "application/json", - "authorization": controllerApiConfig.authToken + "authorization": controllerApiConfig.http.authToken }, "responsePath": "$.*" }, @@ -57,11 +57,11 @@ export default { { "template": { "method": "POST", - "url": controllerApiConfig.url + "/dictionary", + "url": controllerApiConfig.http.url + "/dictionary", "headers": { "accepts": "application/json", "content-type": "application/json", - "authorization": controllerApiConfig.authToken + "authorization": controllerApiConfig.http.authToken }, "body": "{resourceDictionary}", "responsePath": "$.*" @@ -74,11 +74,11 @@ export default { { "template": { "method": "POST", - "url": controllerApiConfig.url + "/dictionary/by-names", + "url": controllerApiConfig.http.url + "/dictionary/by-names", "headers": { "accepts": "application/json", "content-type": "application/json", - "authorization": controllerApiConfig.authToken + "authorization": controllerApiConfig.http.authToken }, "body": "{resourceDictionaryList}", "responsePath": "$.*" diff --git a/cds-ui/server/src/sequence.ts b/cds-ui/server/src/sequence.ts index b282cbc62..84da5249d 100644 --- a/cds-ui/server/src/sequence.ts +++ b/cds-ui/server/src/sequence.ts @@ -31,6 +31,7 @@ import { SequenceHandler, } from '@loopback/rest'; import { logger } from './logger/logger'; +import { v4 as uuid } from 'uuid'; const SequenceActions = RestBindings.SequenceActions; @@ -44,16 +45,22 @@ export class MySequence implements SequenceHandler { ) { } async handle(context: RequestContext) { + const { request, response } = context; try { - const { request, response } = context; - logger.info("Incoming request from %s %s and with header %s query %s params %s", - request.method, request.url, JSON.stringify(request.headers), JSON.stringify(request.query), JSON.stringify(request.params)) + if (!('X-ONAP-RequestID' in request.headers || 'x-onap-requestid' in request.headers)) { + request.headers = { 'X-ONAP-RequestID': uuid(), ...request.headers} + logger.info(JSON.stringify(request.headers)) + } const route = this.findRoute(request); const args = await this.parseParams(request, route); const result = await this.invoke(route, args); this.send(response, result); } catch (err) { this.reject(context, err); + } finally { + const { authorization, ...headers} = request.headers; + logger.info("Incoming request from %s %s and with header %s query %s params %s and response code: %s", + request.method, request.url, JSON.stringify(headers), JSON.stringify(request.query), JSON.stringify(request.params), JSON.stringify(response.statusCode)) } } } diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml index 06726ad11..0f9e08b5f 100755 --- a/ms/blueprintsprocessor/application/pom.xml +++ b/ms/blueprintsprocessor/application/pom.xml @@ -17,7 +17,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> @@ -124,10 +125,6 @@ </resources> <plugins> <plugin> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-maven-plugin</artifactId> - </plugin> - <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <executions> diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java index 2b6f8bcf1..c6400db35 100644 --- a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java @@ -29,8 +29,7 @@ import org.springframework.context.annotation.ComponentScan; */ @SpringBootApplication @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) -@ComponentScan(basePackages = {"org.onap.ccsdk.cds.controllerblueprints", - "org.onap.ccsdk.cds.blueprintsprocessor"}) +@ComponentScan(basePackages = {"org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"}) public class BlueprintProcessorApplication { public static void main(String[] args) { diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties index a94fdf390..fae1adb72 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties @@ -1,3 +1,4 @@ +<<<<<<< HEAD # # Copyright � 2017-2018 AT&T Intellectual Property. # @@ -73,3 +74,12 @@ blueprintsprocessor.cliExecutor.enabled=true ### If enabling remote python executor, set this value to true ### blueprintprocessor.remoteScriptCommand.enabled=true blueprintprocessor.remoteScriptCommand.enabled=false + +# Kafka-message-lib Configurations +blueprintsprocessor.messageclient.self-service-api.topic=producer.t +blueprintsprocessor.messageclient.self-service-api.type=kafka-basic-auth +blueprintsprocessor.messageclient.self-service-api.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageclient.self-service-api.consumerTopic=receiver.t +blueprintsprocessor.messageclient.self-service-api.groupId=receiver-id +blueprintsprocessor.messageclient.self-service-api.clientId=default-client-id +blueprintsprocessor.messageclient.self-service-api.kafkaEnable=false diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties index 1319d9fb5..d6e7dc890 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties @@ -72,3 +72,11 @@ blueprintsprocessor.restclient.primary-aai-data.url=https://aai.onap:8443 blueprintsprocessor.restclient.primary-aai-data.username=aai@aai.onap.org blueprintsprocessor.restclient.primary-aai-data.password=demo123456! +# Kafka-message-lib Configuration +blueprintsprocessor.messageclient.self-service-api.topic=producer.t +blueprintsprocessor.messageclient.self-service-api.type=kafka-basic-auth +blueprintsprocessor.messageclient.self-service-api.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageclient.self-service-api.consumerTopic=receiver.t +blueprintsprocessor.messageclient.self-service-api.groupId=receiver-id +blueprintsprocessor.messageclient.self-service-api.clientId=default-client-id +blueprintsprocessor.messageclient.self-service-api.kafkaEnable=false diff --git a/ms/blueprintsprocessor/application/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplicationTest.java b/ms/blueprintsprocessor/application/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplicationTest.java index 90783d40f..fc36e6287 100644 --- a/ms/blueprintsprocessor/application/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplicationTest.java +++ b/ms/blueprintsprocessor/application/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplicationTest.java @@ -16,7 +16,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor; - import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -34,7 +33,6 @@ import org.springframework.test.context.junit4.SpringRunner; * @author Brinda Santh * DATE : 8/14/2018 */ - @RunWith(SpringRunner.class) @ContextConfiguration(classes = {BlueprintProcessorApplication.class, BluePrintLoadConfiguration.class}) @SpringBootTest(classes = BlueprintProcessorApplication.class, diff --git a/ms/blueprintsprocessor/application/src/test/resources/application.properties b/ms/blueprintsprocessor/application/src/test/resources/application.properties index 09ee651a4..ea2f976a3 100644 --- a/ms/blueprintsprocessor/application/src/test/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/test/resources/application.properties @@ -46,3 +46,13 @@ blueprintprocessor.netconfExecutor.enabled=true blueprintprocessor.restConfExecutor.enabled=true blueprintsprocessor.cliExecutor.enabled=true blueprintprocessor.remoteScriptCommand.enabled=false + + +# Kafka-message-lib Configuration +blueprintsprocessor.messageclient.self-service-api.topic=producer.t +blueprintsprocessor.messageclient.self-service-api.type=kafka-basic-auth +blueprintsprocessor.messageclient.self-service-api.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageclient.self-service-api.consumerTopic=receiver.t +blueprintsprocessor.messageclient.self-service-api.groupId=receiver-id +blueprintsprocessor.messageclient.self-service-api.clientId=default-client-id +blueprintsprocessor.messageclient.self-service-api.kafkaEnable=false diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt deleted file mode 100644 index 65d1c3eee..000000000 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2019 IBM. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor - -import kotlinx.coroutines.runBlocking -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService -import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction -import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants -import org.onap.ccsdk.cds.blueprintsprocessor.ssh.service.BluePrintSshLibPropertyService -import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile -import org.onap.ccsdk.cds.controllerblueprints.core.readNBLines -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService - -abstract class CliComponentFunction : AbstractScriptComponentFunction() { - - open fun bluePrintSshLibPropertyService(): BluePrintSshLibPropertyService = - functionDependencyInstanceAsType(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY) - - open fun resourceResolutionService(): ResourceResolutionService = - functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) - - - open suspend fun readCommandLinesFromArtifact(artifactName: String): List<String> { - val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) - val file = normalizedFile(bluePrintRuntimeService.bluePrintContext().rootPath, artifactDefinition.file) - return file.readNBLines() - } - - fun generateMessage(artifactName: String): String { - return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) - } - - fun resolveFromDatabase(resolutionKey: String, artifactName: String): String = runBlocking { - resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) - } - - fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking { - resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, - artifactPrefix, mapOf()) - } -}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt index 0c1c52320..e1d8825ba 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt @@ -16,12 +16,8 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor -import com.fasterxml.jackson.databind.node.ArrayNode -import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput -import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService -import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants -import org.onap.ccsdk.cds.controllerblueprints.core.getAsString +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor import org.springframework.beans.factory.config.ConfigurableBeanFactory import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component @@ -29,43 +25,4 @@ import org.springframework.stereotype.Component @Component("component-cli-executor") @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) open class ComponentCliExecutor(private var componentFunctionScriptingService: ComponentFunctionScriptingService) - : AbstractComponentFunction() { - - companion object { - const val SCRIPT_TYPE = "script-type" - const val SCRIPT_CLASS_REFERENCE = "script-class-reference" - const val INSTANCE_DEPENDENCIES = "instance-dependencies" - const val RESPONSE_DATA = "response-data" - } - - private lateinit var scriptComponent: CliComponentFunction - - override suspend fun processNB(executionRequest: ExecutionServiceInput) { - - val scriptType = operationInputs.getAsString(SCRIPT_TYPE) - val scriptClassReference = operationInputs.getAsString(SCRIPT_CLASS_REFERENCE) - val instanceDependenciesNode = operationInputs[INSTANCE_DEPENDENCIES] as? ArrayNode - - val scriptDependencies: MutableList<String> = arrayListOf() - scriptDependencies.add(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY) - // May be injected from model, not by default - //scriptDependencies.add(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) - - instanceDependenciesNode?.forEach { instanceName -> - scriptDependencies.add(instanceName.textValue()) - } - - scriptComponent = componentFunctionScriptingService.scriptInstance(this, scriptType, - scriptClassReference, scriptDependencies) - - - // Handles both script processing and error handling - scriptComponent.executeScript(executionServiceInput) - } - - override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { - bluePrintRuntimeService.getBluePrintError() - .addError("Failed in ComponentCliExecutor : ${runtimeException.message}") - - } -}
\ No newline at end of file + : ComponentScriptExecutor(componentFunctionScriptingService)
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ScriptComponentExtensions.kt new file mode 100644 index 000000000..81f1fd821 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ScriptComponentExtensions.kt @@ -0,0 +1,22 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor + +/** + * Register the CLI module exposed dependency + */ + diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts index 0955ace79..e62374747 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts @@ -17,22 +17,23 @@ @file:Suppress("unused") import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput -import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.CliComponentFunction -import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.ComponentCliExecutor +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.sshClientService import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.slf4j.LoggerFactory -open class TestCliScriptFunction : CliComponentFunction() { +open class TestCliScriptFunction : AbstractScriptComponentFunction() { - private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!! + private val log = LoggerFactory.getLogger(TestCliScriptFunction::class.java.canonicalName)!! override fun getName(): String { return "SimpleCliConfigure" } override suspend fun processNB(executionRequest: ExecutionServiceInput) { - log.info("Executing process") + log.info("Executing process ...") } override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { @@ -41,9 +42,9 @@ open class TestCliScriptFunction : CliComponentFunction() { } -open class Check : CliComponentFunction() { +open class Check : AbstractScriptComponentFunction() { - private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!! + private val log = LoggerFactory.getLogger(AbstractScriptComponentFunction::class.java)!! override fun getName(): String { return "Check" @@ -54,12 +55,12 @@ open class Check : CliComponentFunction() { val deviceInformation = bluePrintRuntimeService.resolveDSLExpression("device-properties") // Get the Client Service - val sshClientService = bluePrintSshLibPropertyService().blueprintSshClientService(deviceInformation) + val sshClientService = BluePrintDependencyService.sshClientService(deviceInformation) sshClientService.startSessionNB() // Read Commands - val commands = readCommandLinesFromArtifact("command-template") + val commands = readLinesFromArtifact("command-template") // Execute multiple Commands val responseLog = sshClientService.executeCommandsNB(commands, 5000) @@ -68,7 +69,7 @@ open class Check : CliComponentFunction() { sshClientService.closeSessionNB() // Set the Response Data - setAttribute(ComponentCliExecutor.RESPONSE_DATA, responseLog.asJsonPrimitive()) + setAttribute(ComponentScriptExecutor.RESPONSE_DATA, responseLog.asJsonPrimitive()) log.info("Executing process") } diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt b/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt index 6455513f2..658092f0a 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt +++ b/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt @@ -17,7 +17,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.node.ObjectNode import io.mockk.every import io.mockk.mockk @@ -30,11 +29,13 @@ 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.core.api.data.StepData +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BluePrintSshLibConfiguration import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.onap.ccsdk.cds.controllerblueprints.core.service.DefaultBluePrintRuntimeService import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.scripts.BluePrintScriptsServiceImpl @@ -49,7 +50,7 @@ import kotlin.test.assertNotNull @ContextConfiguration(classes = [CliExecutorConfiguration::class, ExecutionServiceConfiguration::class, BluePrintSshLibConfiguration::class, BluePrintScriptsServiceImpl::class, - BlueprintPropertyConfiguration::class, BluePrintProperties::class]) + BlueprintPropertyConfiguration::class, BluePrintProperties::class, BluePrintDependencyService::class]) @DirtiesContext @TestPropertySource(properties = [], locations = ["classpath:application-test.properties"]) class ComponentCliExecutorTest { @@ -78,10 +79,9 @@ class ComponentCliExecutorTest { operationInputs[BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE] = "activate-cli".asJsonPrimitive() operationInputs[BluePrintConstants.PROPERTY_CURRENT_INTERFACE] = "interfaceName".asJsonPrimitive() operationInputs[BluePrintConstants.PROPERTY_CURRENT_OPERATION] = "operationName".asJsonPrimitive() - operationInputs[ComponentCliExecutor.SCRIPT_TYPE] = BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive() - operationInputs[ComponentCliExecutor.SCRIPT_CLASS_REFERENCE] = + operationInputs[ComponentScriptExecutor.SCRIPT_TYPE] = BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive() + operationInputs[ComponentScriptExecutor.SCRIPT_CLASS_REFERENCE] = "InternalSimpleCli_cba\$TestCliScriptFunction".asJsonPrimitive() - operationInputs[ComponentCliExecutor.INSTANCE_DEPENDENCIES] = JacksonUtils.jsonNode("[]") as ArrayNode val stepInputData = StepData().apply { name = "activate-cli" diff --git a/ms/blueprintsprocessor/functions/netconf-executor/pom.xml b/ms/blueprintsprocessor/functions/netconf-executor/pom.xml index a46e7433d..ca5423432 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/netconf-executor/pom.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - ~ Copyright © 2017-2018 AT&T Intellectual Property. + ~ Copyright © 2017-2019 AT&T, Bell Canada. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. @@ -32,12 +32,6 @@ <artifactId>resource-resolution</artifactId> </dependency> <dependency> - <groupId>org.codehaus.jettison</groupId> - <artifactId>jettison</artifactId> - <version>${jettison.version}</version> - <scope>provided</scope> - </dependency> - <dependency> <groupId>org.apache.sshd</groupId> <artifactId>sshd-core</artifactId> </dependency> diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt index 4cec6a2bf..5e0b4a117 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt @@ -17,51 +17,48 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor -import com.fasterxml.jackson.databind.JsonNode import kotlinx.coroutines.runBlocking -import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction -import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +@Deprecated("Methods defined as extension function of AbstractComponentFunction") abstract class NetconfComponentFunction : AbstractScriptComponentFunction() { + @Deprecated(" Use resourceResolutionService method directly", + replaceWith = ReplaceWith("resourceResolutionService()", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceResolutionService")) open fun resourceResolutionService(): ResourceResolutionService = functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) // Called from python script + @Deprecated(" Use netconfDeviceInfo method directly", + replaceWith = ReplaceWith("netconfDeviceInfo(requirementName)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.netconfDeviceInfo")) fun initializeNetconfConnection(requirementName: String): NetconfDevice { - val deviceInfo = deviceProperties(requirementName) + val deviceInfo = netconfDeviceInfo(requirementName) return NetconfDevice(deviceInfo) } + @Deprecated(" Use artifactContent method directly", + replaceWith = ReplaceWith("artifactContent(artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.services.execution.artifactContent")) fun generateMessage(artifactName: String): String { return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) } + @Deprecated(" Use storedContentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("storedContentFromResolvedArtifact(resolutionKey, artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.storedContentFromResolvedArtifact")) fun resolveFromDatabase(resolutionKey: String, artifactName: String): String = runBlocking { resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) } + @Deprecated(" Use contentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("resolveAndGenerateMessage(artifactPrefix)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resolveAndGenerateMessage")) fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking { resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactPrefix, mapOf()) } - - private fun deviceProperties(requirementName: String): DeviceInfo { - - val blueprintContext = bluePrintRuntimeService.bluePrintContext() - - val requirement = blueprintContext.nodeTemplateRequirement(nodeTemplateName, requirementName) - - val capabilityProperties = bluePrintRuntimeService.resolveNodeTemplateCapabilityProperties(requirement - .node!!, requirement.capability!!) - - return deviceProperties(capabilityProperties) - } - - private fun deviceProperties(capabilityProperty: MutableMap<String, JsonNode>): DeviceInfo { - return JacksonUtils.getInstanceFromMap(capabilityProperty, DeviceInfo::class.java) - } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/ScriptComponentExtensions.kt new file mode 100644 index 000000000..bac211ab2 --- /dev/null +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/ScriptComponentExtensions.kt @@ -0,0 +1,53 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor + +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils + +/** + * Register the Netconf module exposed dependency + */ +fun BluePrintDependencyService.netconfClientService(): ResourceResolutionService = + instance(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + + +fun AbstractComponentFunction.netconfDevice(requirementName: String): NetconfDevice { + val deviceInfo = netconfDeviceInfo(requirementName) + return NetconfDevice(deviceInfo) +} + +fun AbstractComponentFunction.netconfDeviceInfo(requirementName: String): DeviceInfo { + + val blueprintContext = bluePrintRuntimeService.bluePrintContext() + + val requirement = blueprintContext.nodeTemplateRequirement(nodeTemplateName, requirementName) + + val capabilityProperties = bluePrintRuntimeService.resolveNodeTemplateCapabilityProperties(requirement + .node!!, requirement.capability!!) + + return netconfDeviceInfo(capabilityProperties) +} + +private fun AbstractComponentFunction.netconfDeviceInfo(capabilityProperty: MutableMap<String, JsonNode>): DeviceInfo { + return JacksonUtils.getInstanceFromMap(capabilityProperty, DeviceInfo::class.java) +}
\ No newline at end of file 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 2de22424e..c45fb881f 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 @@ -16,6 +16,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor +import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.* import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceConstant @@ -75,8 +76,19 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic val dynamicProperties = getOptionalOperationInput(INPUT_DYNAMIC_PROPERTIES) val packages = getOptionalOperationInput(INPUT_PACKAGES)?.returnNullIfMissing() - val args = getOptionalOperationInput(INPUT_ARGUMENT_PROPERTIES)?.returnNullIfMissing() - ?.rootFieldsToMap()?.toSortedMap()?.values?.map { it.textValue() }?.joinToString(" ") + val argsNode = getOptionalOperationInput(INPUT_ARGUMENT_PROPERTIES)?.returnNullIfMissing() + + // This prevents unescaping values, as well as quoting the each parameter, in order to allow for spaces in values + var args = "" + argsNode?.fields()?.forEach { + if (it.value.isValueNode) { + args = "$args ${it.value}" + } else { + it.value.fields().forEach { item -> + args = "$args ${item.value}" + } + } + } val command = getOperationInput(INPUT_COMMAND).asText() var scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ScriptComponentExtensions.kt new file mode 100644 index 000000000..ab01b15b7 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ScriptComponentExtensions.kt @@ -0,0 +1,57 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution + +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService + + +/** + * Register the Resolution module exposed dependency + */ +fun BluePrintDependencyService.resourceResolutionService(): ResourceResolutionService = + instance(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + + +suspend fun AbstractComponentFunction.storedContentFromResolvedArtifactNB(resolutionKey: String, + artifactName: String): String { + return BluePrintDependencyService.resourceResolutionService() + .resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) +} + +/** + * Return resolved and mashed artifact content for artifact prefix [artifactPrefix] + */ +suspend fun AbstractComponentFunction.contentFromResolvedArtifactNB(artifactPrefix: String): String { + return BluePrintDependencyService.resourceResolutionService() + .resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactPrefix, mapOf()) +} + + +/** + * Blocking Methods called from Jython Scripts + */ + +fun AbstractComponentFunction.storedContentFromResolvedArtifact(resolutionKey: String, artifactName: String) + : String = runBlocking { + storedContentFromResolvedArtifactNB(resolutionKey, artifactName) +} + +fun AbstractComponentFunction.contentFromResolvedArtifact(artifactPrefix: String): String = runBlocking { + contentFromResolvedArtifactNB(artifactPrefix) +} diff --git a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt index b2064cb54..ede833cfb 100644 --- a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt +++ b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt @@ -25,28 +25,42 @@ import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPrope import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction - +@Deprecated("Methods defined as extension function of AbstractComponentFunction") abstract class RestconfComponentFunction : AbstractScriptComponentFunction() { + @Deprecated("Defined in AbstractScriptComponentFunction extension class") open fun bluePrintRestLibPropertyService(): BluePrintRestLibPropertyService = functionDependencyInstanceAsType(RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY) + @Deprecated(" Use resourceResolutionService method directly", + replaceWith = ReplaceWith("resourceResolutionService()", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceResolutionService")) open fun resourceResolutionService(): ResourceResolutionService = functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + @Deprecated("Defined in AbstractScriptComponentFunction extension class") fun restClientService(selector: String): BlueprintWebClientService { return bluePrintRestLibPropertyService().blueprintWebClientService(selector) } + @Deprecated(" Use storedContentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("storedContentFromResolvedArtifact(resolutionKey, artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.storedContentFromResolvedArtifact")) fun resolveFromDatabase(resolutionKey: String, artifactName: String): String = runBlocking { resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) } + @Deprecated(" Use artifactContent method directly", + replaceWith = ReplaceWith("artifactContent(artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.services.execution.artifactContent")) fun generateMessage(artifactName: String): String { return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) } + @Deprecated(" Use contentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("resolveAndGenerateMessage(artifactPrefix)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resolveAndGenerateMessage")) fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking { resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactPrefix, mapOf()) diff --git a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/ScriptComponentExtensions.kt new file mode 100644 index 000000000..9fc685e19 --- /dev/null +++ b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/ScriptComponentExtensions.kt @@ -0,0 +1,36 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.restconf.executor + +/** + * Register the Restconf module exposed dependency + */ + + +/** + * Generic Mount function + */ + + +/** + * Generic Configure function + */ + + +/** + * Generic Unmount function + */
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt index 19e482aab..efefe0290 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt @@ -16,7 +16,9 @@ package org.onap.ccsdk.cds.blueprintsprocessor.db +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.BluePrintDBLibPropertySevice import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.ComponentScan @@ -34,8 +36,18 @@ open class BluePrintDBLibConfiguration(private var bluePrintProperties: BluePrin } } +/** + * Exposed Dependency Service by this SSH Lib Module + */ +//TODO("right now not wired with name ") +fun BluePrintDependencyService.dbLibPropertyService(): BluePrintDBLibPropertySevice = + instance(DBLibConstants.SERVICE_BLUEPRINT_DB_LIB_PROPERTY) + + class DBLibConstants { companion object { + //TODO("right now not wired with name ") + const val SERVICE_BLUEPRINT_DB_LIB_PROPERTY = "blueprint-db-lib-property-service" const val PREFIX_DB_PRIMARY: String = "blueprintsprocessor.db.primary" //list of database 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 52ac346db..008e92437 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 @@ -16,6 +16,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.message.service +import org.apache.commons.lang.builder.ToStringBuilder import org.apache.kafka.clients.producer.ProducerConfig.* import org.apache.kafka.common.serialization.StringSerializer import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageProducerProperties @@ -27,7 +28,6 @@ import org.springframework.kafka.core.ProducerFactory import org.springframework.kafka.support.SendResult import org.springframework.util.concurrent.ListenableFutureCallback - class KafkaBasicAuthMessageProducerService( private val messageProducerProperties: KafkaBasicAuthMessageProducerProperties) : BlueprintMessageProducerService { @@ -64,9 +64,8 @@ class KafkaBasicAuthMessageProducerService( return true } - private fun producerFactory(additionalConfig: Map<String, Any>? = null): ProducerFactory<String, Any> { - log.info("Client Properties : $messageProducerProperties") + log.info("Client Properties : ${ToStringBuilder.reflectionToString(messageProducerProperties)}") val configProps = hashMapOf<String, Any>() configProps[BOOTSTRAP_SERVERS_CONFIG] = messageProducerProperties.bootstrapServers configProps[KEY_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/BluePrintCoreConfiguration.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/BluePrintCoreConfiguration.kt index 5f1ae7d37..1cb66b8ab 100644 --- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/BluePrintCoreConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/BluePrintCoreConfiguration.kt @@ -17,16 +17,19 @@ package org.onap.ccsdk.cds.blueprintsprocessor.core import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintPathConfiguration +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService +import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.bind.Bindable import org.springframework.boot.context.properties.bind.Binder import org.springframework.boot.context.properties.source.ConfigurationPropertySources +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.env.Environment import org.springframework.stereotype.Service - @Configuration open class BluePrintCoreConfiguration(private val bluePrintProperties: BlueprintProcessorProperties) { @@ -59,4 +62,17 @@ open class BlueprintProcessorProperties(private var bluePrintPropertyBinder: Bin fun <T> propertyBeanType(prefix: String, type: Class<T>): T { return bluePrintPropertyBinder.bind(prefix, Bindable.of(type)).get() } +} + +@Configuration +// Add Conditional property , If we try to manage on Application level +open class BlueprintDependencyConfiguration : ApplicationContextAware { + + private val log = LoggerFactory.getLogger(BlueprintDependencyConfiguration::class.java)!! + + override fun setApplicationContext(applicationContext: ApplicationContext) { + BluePrintDependencyService.inject(applicationContext) + log.info("Dependency Management module created...") + } + }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt index fa4ff231d..25d1de881 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt @@ -18,6 +18,10 @@ package org.onap.ccsdk.cds.blueprintsprocessor.rest +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration @@ -27,6 +31,22 @@ import org.springframework.context.annotation.Configuration @EnableConfigurationProperties open class BluePrintRestLibConfiguration +/** + * Exposed Dependency Service by this Rest Lib Module + */ +fun BluePrintDependencyService.restLibPropertyService(): BluePrintRestLibPropertyService = + instance(RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY) + + +fun BluePrintDependencyService.restClientService(selector: String): BlueprintWebClientService { + return restLibPropertyService().blueprintWebClientService(selector) +} + + +fun BluePrintDependencyService.restClientService(jsonNode: JsonNode): BlueprintWebClientService { + return restLibPropertyService().blueprintWebClientService(jsonNode) +} + class RestLibConstants { companion object { diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt index 48e451f03..3c625a6d3 100644 --- a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt @@ -16,6 +16,10 @@ package org.onap.ccsdk.cds.blueprintsprocessor.ssh +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.service.BluePrintSshLibPropertyService +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.service.BlueprintSshClientService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration @@ -25,6 +29,21 @@ import org.springframework.context.annotation.Configuration @EnableConfigurationProperties open class BluePrintSshLibConfiguration +/** + * Exposed Dependency Service by this SSH Lib Module + */ +fun BluePrintDependencyService.sshLibPropertyService(): BluePrintSshLibPropertyService = + instance(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY) + + +fun BluePrintDependencyService.sshClientService(selector: String): BlueprintSshClientService = + sshLibPropertyService().blueprintSshClientService(selector) + + +fun BluePrintDependencyService.sshClientService(jsonNode: JsonNode): BlueprintSshClientService = + sshLibPropertyService().blueprintSshClientService(jsonNode) + + class SshLibConstants { companion object { const val SERVICE_BLUEPRINT_SSH_LIB_PROPERTY = "blueprint-ssh-lib-property-service" diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml index 340f2c618..89ad720f6 100755 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml @@ -42,6 +42,7 @@ <artifactId>proto-definition</artifactId> <version>${project.version}</version> </dependency> + <dependency> <groupId>org.onap.ccsdk.cds.controllerblueprints</groupId> <artifactId>blueprint-core</artifactId> @@ -59,6 +60,30 @@ <artifactId>h2</artifactId> <scope>test</scope> </dependency> + + <!-- For Message libraries --> + <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <artifactId>message-lib</artifactId> + </dependency> + + <!-- For spring-kafka --> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka-test</artifactId> + <scope>test</scope> + </dependency> + + <!-- Apache Kafka --> + <dependency> + <groupId>org.apache.kafka</groupId> + <artifactId>kafka_2.11</artifactId> + <version>${kafka.version}</version> + </dependency> </dependencies> </project> diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/MessagingConfig.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/MessagingConfig.kt new file mode 100644 index 000000000..a04a79921 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/MessagingConfig.kt @@ -0,0 +1,47 @@ +package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api + +import org.apache.kafka.clients.CommonClientConfigs +import org.apache.kafka.clients.consumer.ConsumerConfig +import org.apache.kafka.common.serialization.StringDeserializer +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.kafka.annotation.EnableKafka +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory +import org.springframework.kafka.core.ConsumerFactory +import org.springframework.kafka.core.DefaultKafkaConsumerFactory +import org.springframework.kafka.support.serializer.JsonDeserializer + +@Configuration +open class MessagingConfig { + + @Value("\${blueprintsprocessor.messageclient.self-service-api.groupId}") + lateinit var groupId: String + + @Value("\${blueprintsprocessor.messageclient.self-service-api.bootstrapServers}") + lateinit var bootstrapServers: String + + open fun consumerFactory(): ConsumerFactory<String, ExecutionServiceInput>? { + val configProperties = hashMapOf<String, Any>() + configProperties[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers + configProperties[ConsumerConfig.GROUP_ID_CONFIG] = groupId + configProperties[ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java.name + configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = JsonDeserializer::class.java.name + configProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest") + + return DefaultKafkaConsumerFactory(configProperties, StringDeserializer(), JsonDeserializer(ExecutionServiceInput::class.java)) + } + + /** + * Creation of a Kafka MessageListener Container + * + * @return KafkaListener instance. + */ + @Bean + open fun kafkaListenerContainerFactory(): ConcurrentKafkaListenerContainerFactory<String, ExecutionServiceInput> { + val factory = ConcurrentKafkaListenerContainerFactory<String, ExecutionServiceInput>() + factory.consumerFactory = consumerFactory() + return factory + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/MessagingController.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/MessagingController.kt new file mode 100644 index 000000000..1d219a83e --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/MessagingController.kt @@ -0,0 +1,74 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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 kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking +import org.apache.commons.lang3.builder.ToStringBuilder +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BluePrintMessageLibPropertyService +import org.slf4j.LoggerFactory +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.kafka.annotation.KafkaListener +import org.springframework.stereotype.Service + +@ConditionalOnProperty(name = ["blueprintsprocessor.messageclient.self-service-api.kafkaEnable"], havingValue = "true") +@Service +open class MessagingController(private val propertyService: BluePrintMessageLibPropertyService, + private val executionServiceHandler: ExecutionServiceHandler) { + + private val log = LoggerFactory.getLogger(MessagingController::class.java)!! + + companion object { + // TODO PREFIX should be retrieved from model or from request. + const val PREFIX = "self-service-api" + const val EXECUTION_STATUS = 200 + } + + @KafkaListener(topics = ["\${blueprintsprocessor.messageclient.self-service-api.consumerTopic}"]) + open fun receive(input: ExecutionServiceInput) { + + log.info("Successfully received a message: {}", ToStringBuilder.reflectionToString(input)) + + runBlocking { + log.info("Successfully received a message: {}", ToStringBuilder.reflectionToString(input)) + + // Process the message. + async { + processMessage(input) + } + } + } + + private suspend fun processMessage(executionServiceInput: ExecutionServiceInput) { + + val executionServiceOutput = executionServiceHandler.doProcess(executionServiceInput) + + if (executionServiceOutput.status.code == EXECUTION_STATUS) { + val bluePrintMessageClientService = propertyService + .blueprintMessageClientService(PREFIX) + + val payload = executionServiceOutput.payload + + log.info("The payload to publish is {}", payload) + + bluePrintMessageClientService.sendMessage(payload) + } + else { + log.error("Fail to process the given event due to {}", executionServiceOutput.status.errorMessage) + } + } +} diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandlerTest.kt index fd764d78f..e084c60cf 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandlerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandlerTest.kt @@ -23,6 +23,8 @@ import io.grpc.testing.GrpcServerRule import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.messaginglib.MessagingControllerTest +import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.messaginglib.ProducerConfiguration import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile @@ -33,6 +35,7 @@ import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.FilterType import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner @@ -44,7 +47,9 @@ import kotlin.test.assertTrue @RunWith(SpringRunner::class) @EnableAutoConfiguration @DirtiesContext -@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) +@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"], + excludeFilters = [ComponentScan.Filter(value = [MessagingConfig::class, MessagingController::class, ProducerConfiguration::class, + MessagingControllerTest.ConsumerConfiguration::class, MessagingControllerTest::class], type = FilterType.ASSIGNABLE_TYPE)]) @TestPropertySource(locations = ["classpath:application-test.properties"]) class BluePrintManagementGRPCHandlerTest { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt index f8b972e64..5072b3c6a 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt @@ -36,6 +36,7 @@ import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.FilterType import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner @@ -45,7 +46,8 @@ import kotlin.test.BeforeTest @RunWith(SpringRunner::class) @DirtiesContext @EnableAutoConfiguration -@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) +@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"], + excludeFilters =arrayOf(ComponentScan.Filter(value = [(MessagingController::class)], type = FilterType.ASSIGNABLE_TYPE))) @TestPropertySource(locations = ["classpath:application-test.properties"]) class BluePrintProcessingGRPCHandlerTest { private val log = LoggerFactory.getLogger(BluePrintProcessingGRPCHandlerTest::class.java) 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 index 9cbd898dc..65b41262b 100644 --- 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 @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.security.SecurityProperties import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.FilterType import org.springframework.core.io.ByteArrayResource import org.springframework.http.client.MultipartBodyBuilder import org.springframework.test.context.ContextConfiguration @@ -49,7 +50,8 @@ import kotlin.test.assertTrue @RunWith(SpringRunner::class) @WebFluxTest @ContextConfiguration(classes = [ExecutionServiceHandler::class, BluePrintCoreConfiguration::class, BluePrintCatalogService::class, SecurityProperties::class]) -@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) +@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"], + excludeFilters =arrayOf(ComponentScan.Filter(value = [(MessagingController::class)], type = FilterType.ASSIGNABLE_TYPE))) @TestPropertySource(locations = ["classpath:application-test.properties"]) class ExecutionServiceHandlerTest { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/MessagingControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/MessagingControllerTest.kt new file mode 100644 index 000000000..f7459f522 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/MessagingControllerTest.kt @@ -0,0 +1,211 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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.messaginglib + +import com.fasterxml.jackson.databind.node.ObjectNode +import kotlinx.coroutines.reactive.awaitSingle +import kotlinx.coroutines.runBlocking +import org.apache.commons.lang.builder.ToStringBuilder +import org.apache.kafka.clients.CommonClientConfigs +import org.apache.kafka.clients.consumer.ConsumerConfig +import org.apache.kafka.common.serialization.StringDeserializer +import org.junit.After +import org.junit.Before +import org.junit.Test +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.core.api.data.StepData +import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.MessagingController +import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.autoconfigure.security.SecurityProperties +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration +import org.springframework.core.io.ByteArrayResource +import org.springframework.http.client.MultipartBodyBuilder +import org.springframework.kafka.annotation.EnableKafka +import org.springframework.kafka.annotation.KafkaListener +import org.springframework.kafka.annotation.PartitionOffset +import org.springframework.kafka.annotation.TopicPartition +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory +import org.springframework.kafka.core.ConsumerFactory +import org.springframework.kafka.core.DefaultKafkaConsumerFactory +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.support.serializer.JsonDeserializer +import org.springframework.kafka.test.context.EmbeddedKafka +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.test.web.reactive.server.WebTestClient +import org.springframework.test.web.reactive.server.returnResult +import org.springframework.web.reactive.function.BodyInserters +import java.io.File +import java.nio.file.Files +import java.nio.file.Paths +import kotlin.test.assertNotNull + +@RunWith(SpringRunner::class) +@EnableAutoConfiguration +@ContextConfiguration(classes = [MessagingControllerTest::class, SecurityProperties::class]) +@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) +@TestPropertySource(locations = ["classpath:application-test.properties"]) +@DirtiesContext +@EmbeddedKafka(ports = [9092]) +@WebFluxTest +class MessagingControllerTest { + + private val log = LoggerFactory.getLogger(MessagingControllerTest::class.java)!! + + @Autowired + lateinit var controller: MessagingController + + @Value("\${blueprintsprocessor.messageclient.self-service-api.consumerTopic}") + lateinit var topicUsedForConsumer: String + + @Autowired + lateinit var kt: KafkaTemplate<String, ExecutionServiceInput> + + @Autowired + lateinit var webTestClient: WebTestClient + + var receivedEvent: String? = null + + @Before + fun setup() { + deleteDir("target", "blueprints") + uploadBluePrint() + } + + @After + fun clean() { + deleteDir("target", "blueprints") + } + + @Test + fun testReceive() { + val samplePayload = "{\n" + + " \"resource-assignment-request\": {\n" + + " \"artifact-name\": [\"hostname\"],\n" + + " \"store-result\": true,\n" + + " \"resource-assignment-properties\" : {\n" + + " \"hostname\": \"demo123\"\n" + + " }\n" + + " }\n" + + " }" + + kt.defaultTopic = topicUsedForConsumer + + val input = ExecutionServiceInput().apply { + commonHeader = CommonHeader().apply { + originatorId = "1" + requestId = "1234" + subRequestId = "1234-1234" + } + + actionIdentifiers = ActionIdentifiers().apply { + blueprintName = "golden" + blueprintVersion = "1.0.0" + actionName = "resource-assignment" + mode = "sync" + } + + stepData = StepData().apply { + name = "resource-assignment" + } + + payload = JacksonUtils.jsonNode(samplePayload) as ObjectNode + } + + kt.sendDefault(input) + log.info("test-sender sent message='{}'", ToStringBuilder.reflectionToString(input)) + + Thread.sleep(1000) + } + + @KafkaListener(topicPartitions = [TopicPartition(topic = "\${blueprintsprocessor.messageclient.self-service-api.topic}", partitionOffsets = [PartitionOffset(partition = "0", initialOffset = "0")])]) + fun receivedEventFromBluePrintProducer(event: ExecutionServiceInput) { + assertNotNull(event) + } + + private fun uploadBluePrint() { + runBlocking { + val body = MultipartBodyBuilder().apply { + part("file", object : ByteArrayResource(Files.readAllBytes(loadCbaArchive().toPath())) { + override fun getFilename(): String { + return "test-cba.zip" + } + }) + }.build() + + webTestClient + .post() + .uri("/api/v1/execution-service/upload") + .body(BodyInserters.fromMultipartData(body)) + .exchange() + .expectStatus().isOk + .returnResult<String>() + .responseBody + .awaitSingle() + } + } + + private fun loadCbaArchive():File { + return Paths.get("./src/test/resources/cba-for-kafka-integration.zip").toFile() + } + + @Configuration + @EnableKafka + open class ConsumerConfiguration { + + @Value("\${blueprintsprocessor.messageclient.self-service-api.bootstrapServers}") + lateinit var bootstrapServers: String + + @Value("\${blueprintsprocessor.messageclient.self-service-api.groupId}") + lateinit var groupId:String + + @Bean + open fun consumerFactory2(): ConsumerFactory<String, ExecutionServiceInput>? { + val configProperties = hashMapOf<String, Any>() + configProperties[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers + configProperties[ConsumerConfig.GROUP_ID_CONFIG] = groupId + configProperties[ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java.name + configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = JsonDeserializer::class.java.name + configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = "earliest" + configProperties[ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG] = 1000 + + return DefaultKafkaConsumerFactory(configProperties, StringDeserializer(), + JsonDeserializer(ExecutionServiceInput::class.java)) + } + + @Bean + open fun listenerFactory(): ConcurrentKafkaListenerContainerFactory<String, ExecutionServiceInput> { + val factory = ConcurrentKafkaListenerContainerFactory<String, ExecutionServiceInput>() + factory.consumerFactory = consumerFactory2() + return factory + } + } +} + + diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/ProducerConfiguration.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/ProducerConfiguration.kt new file mode 100644 index 000000000..dc1f38a63 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/messaginglib/ProducerConfiguration.kt @@ -0,0 +1,48 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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.messaginglib + +import org.apache.kafka.clients.producer.ProducerConfig +import org.apache.kafka.common.serialization.StringSerializer +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.kafka.annotation.EnableKafka +import org.springframework.kafka.core.DefaultKafkaProducerFactory +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.core.ProducerFactory +import org.springframework.kafka.support.serializer.JsonSerializer + +@Configuration +open class ProducerConfiguration { + + @Value("\${blueprintsprocessor.messageclient.self-service-api.bootstrapServers}") + lateinit var bootstrapServers: String + + open fun kpf(): ProducerFactory<String, ExecutionServiceInput> { + val configs = HashMap<String, Any>() + configs[ProducerConfig.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers + configs[ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java + configs[ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG] = JsonSerializer::class.java + return DefaultKafkaProducerFactory(configs) + } + + @Bean + open fun kt(): KafkaTemplate<String, ExecutionServiceInput> { + return KafkaTemplate<String, ExecutionServiceInput>(kpf()) + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties index 6705523df..d532b1582 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties @@ -31,3 +31,12 @@ blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints + +# Kafka-message-lib Configuration +blueprintsprocessor.messageclient.self-service-api.kafkaEnable=true +blueprintsprocessor.messageclient.self-service-api.topic=producer.t +blueprintsprocessor.messageclient.self-service-api.type=kafka-basic-auth +blueprintsprocessor.messageclient.self-service-api.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageclient.self-service-api.consumerTopic=receiver.t +blueprintsprocessor.messageclient.self-service-api.groupId=receiver-id +blueprintsprocessor.messageclient.self-service-api.clientId=default-client-id diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration.zip b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration.zip Binary files differnew file mode 100644 index 000000000..23070380c --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration.zip diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt index 23588d25a..408bb58ed 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt @@ -27,6 +27,7 @@ import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType import org.onap.ccsdk.cds.controllerblueprints.core.* import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService import org.slf4j.LoggerFactory /** @@ -146,4 +147,19 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic bluePrintRuntimeService.getBluePrintError().addError(error) } + fun artifactContent(artifactName: String): String { + return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) + } + + suspend fun mashTemplateNData(artifactName: String, json: String): String { + val content = artifactContent(artifactName) + return BluePrintVelocityTemplateService.generateContent(content, json) + } + + suspend fun readLinesFromArtifact(artifactName: String): List<String> { + val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) + val file = normalizedFile(bluePrintRuntimeService.bluePrintContext().rootPath, artifactDefinition.file) + return file.readNBLines() + } + }
\ 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/AbstractScriptComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractScriptComponentFunction.kt index 27cde8a49..f17085ef1 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractScriptComponentFunction.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractScriptComponentFunction.kt @@ -36,11 +36,13 @@ abstract class AbstractScriptComponentFunction : AbstractComponentFunction() { /** * Store Dynamic Script Dependency Instances, Objects present inside won't be persisted or state maintained. */ + @Deprecated("Dependencies will be resolved dynamically") var functionDependencyInstances: MutableMap<String, Any> = hashMapOf() /** * This will be called from the scripts to serve instance from runtime to scripts. */ + @Deprecated("Dependencies will be resolved dynamically") open fun <T> functionDependencyInstanceAsType(name: String): T { return functionDependencyInstances[name] as? T ?: throw BluePrintProcessorException("couldn't get script property instance ($name)") diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentScriptExecutor.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentScriptExecutor.kt new file mode 100644 index 000000000..056f7e96d --- /dev/null +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentScriptExecutor.kt @@ -0,0 +1,108 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.services.execution + +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType +import org.onap.ccsdk.cds.controllerblueprints.core.getAsString +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +/** + * This is generic Script Component Executor function + * @author Brinda Santh + */ +@Component("component-script-executor") +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +open class ComponentScriptExecutor(private var componentFunctionScriptingService: ComponentFunctionScriptingService) + : AbstractComponentFunction() { + + companion object { + const val SCRIPT_TYPE = "script-type" + const val SCRIPT_CLASS_REFERENCE = "script-class-reference" + const val DYNAMIC_PROPERTIES = "dynamic-properties" + const val RESPONSE_DATA = "response-data" + const val STATUS = "status" + } + + lateinit var scriptComponentFunction: AbstractScriptComponentFunction + + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + + val scriptType = operationInputs.getAsString(SCRIPT_TYPE) + val scriptClassReference = operationInputs.getAsString(SCRIPT_CLASS_REFERENCE) + + val scriptDependencies: MutableList<String> = arrayListOf() + populateScriptDependencies(scriptDependencies) + + scriptComponentFunction = componentFunctionScriptingService.scriptInstance(this, scriptType, + scriptClassReference, scriptDependencies) + + // Handles both script processing and error handling + scriptComponentFunction.executeScript(executionServiceInput) + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + bluePrintRuntimeService.getBluePrintError() + .addError("Failed in ComponentCliExecutor : ${runtimeException.message}") + + } + + open fun populateScriptDependencies(scriptDependencies: MutableList<String>) { + /** Place holder for Child to add extra dependencies */ + } +} + +/** Component Extensions **/ + +fun BluePrintTypes.componentScriptExecutor(): NodeType { + return nodeType(id = "component-script-executor", version = BluePrintConstants.DEFAULT_VERSION_NUMBER, + derivedFrom = BluePrintConstants.MODEL_TYPE_NODES_ROOT, + description = "Generic Script Component Executor") { + attribute(ComponentScriptExecutor.RESPONSE_DATA, BluePrintConstants.DATA_TYPE_JSON, false) + attribute(ComponentScriptExecutor.STATUS, BluePrintConstants.DATA_TYPE_STRING, true) + + operation("ComponentScriptExecutor", "ComponentScriptExecutor Operation") { + inputs { + property(ComponentScriptExecutor.SCRIPT_TYPE, BluePrintConstants.DATA_TYPE_STRING, true, + "Script Type") { + defaultValue(BluePrintConstants.SCRIPT_INTERNAL) + constrains { + validValues(listOf(BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive(), + BluePrintConstants.SCRIPT_JYTHON.asJsonPrimitive(), + BluePrintConstants.SCRIPT_KOTLIN.asJsonPrimitive())) + } + } + property(ComponentScriptExecutor.SCRIPT_CLASS_REFERENCE, BluePrintConstants.DATA_TYPE_STRING, + true, "Kotlin Script class name or jython script name.") + property(ComponentScriptExecutor.DYNAMIC_PROPERTIES, BluePrintConstants.DATA_TYPE_JSON, false, + "Dynamic Json Content or DSL Json reference.") + } + outputs { + property(ComponentScriptExecutor.RESPONSE_DATA, BluePrintConstants.DATA_TYPE_JSON, false, + "Output Response") + property(ComponentScriptExecutor.STATUS, BluePrintConstants.DATA_TYPE_STRING, true, + "Status of the Component Execution ( success or failure )") + } + } + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt index b404fbed6..224319c24 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt @@ -34,7 +34,9 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInpu import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.componentScriptExecutor import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext @@ -53,7 +55,7 @@ import kotlin.test.assertNotNull */ @RunWith(SpringRunner::class) @ContextConfiguration(classes = [ComponentFunctionScriptingService::class, - BluePrintScriptsServiceImpl::class,PythonExecutorProperty::class, + BluePrintScriptsServiceImpl::class, PythonExecutorProperty::class, BlueprintJythonService::class]) class AbstractComponentFunctionTest { @@ -183,5 +185,10 @@ class AbstractComponentFunctionTest { return executionServiceInput } + @Test + fun testComponentScriptExecutorNodeType() { + val componentScriptExecutor = BluePrintTypes.componentScriptExecutor() + assertNotNull(componentScriptExecutor.interfaces, "failed to get interface operations") + } } diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index 82c2e6153..5e6502fcb 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -1,8 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - ~ Copyright © 2017-2018 AT&T Intellectual Property. - ~ - ~ Modifications Copyright © 2018 - 2019 IBM, Bell Canada + ~ Copyright © 2017-2019 AT&T, IBM, Bell Canada. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. @@ -479,6 +477,13 @@ <scope>test</scope> </dependency> + <!-- message-lib dependency --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>message-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> </dependencyManagement> 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 365c00188..305c83e17 100644 --- a/ms/command-executor/src/main/python/command_executor_handler.py +++ b/ms/command-executor/src/main/python/command_executor_handler.py @@ -163,9 +163,16 @@ class CommandExecutorHandler(): def activate_venv(self): self.logger.info("{} - Activate Python Virtual Environment".format(self.blueprint_id)) + # Fix: The python generated activate_this.py script concatenates the env bin dir to PATH on every call + # eventually this process PATH variable was so big (128Kb) that no child process could be spawn + # This script will remove all duplicates; while keeping the order of the PATH folders + fixpathenvvar = "os.environ['PATH']=os.pathsep.join(list(dict.fromkeys(os.environ['PATH'].split(':'))))" + path = "%s/bin/activate_this.py" % self.venv_home try: exec (open(path).read(), {'__file__': path}) + exec (fixpathenvvar) + self.logger.info("Running with PATH : {}".format(os.environ['PATH'])) return True except Exception as err: self.logger.info( diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintTypeDSLBuilder.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintTypeDSLBuilder.kt index 07cc20ebd..0f011948d 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintTypeDSLBuilder.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/dsl/BluePrintTypeDSLBuilder.kt @@ -18,6 +18,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core.dsl import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType import org.onap.ccsdk.cds.controllerblueprints.core.data.* @@ -266,16 +267,16 @@ class OperationDefinitionBuilder(private val id: String, class AttributesDefinitionBuilder { private val attributes: MutableMap<String, AttributeDefinition> = hashMapOf() - fun property(id: String, attribute: AttributeDefinition) { + fun attribute(id: String, attribute: AttributeDefinition) { attributes[id] = attribute } - fun property(id: String, type: String?, required: Boolean?, description: String?) { + fun attribute(id: String, type: String?, required: Boolean?, description: String?) { val attribute = AttributeDefinitionBuilder(id, type, required, description).build() attributes[id] = attribute } - fun property(id: String, type: String?, required: Boolean?, description: String?, + fun attribute(id: String, type: String?, required: Boolean?, description: String?, block: AttributeDefinitionBuilder.() -> Unit) { val attribute = AttributeDefinitionBuilder(id, type, required, description).apply(block).build() attributes[id] = attribute @@ -353,7 +354,14 @@ class PropertyDefinitionBuilder(private val id: String, fun entrySchema(entrySchemaType: String, block: EntrySchemaBuilder.() -> Unit) { propertyDefinition.entrySchema = EntrySchemaBuilder(entrySchemaType).apply(block).build() } - // TODO("Constrains") + + fun constrains(block: ConstraintClauseBuilder.() -> Unit) { + propertyDefinition.constraints = ConstraintClauseBuilder().apply(block).build() + } + + fun defaultValue(defaultValue: Any) { + defaultValue(defaultValue.asJsonType()) + } fun defaultValue(defaultValue: JsonNode) { propertyDefinition.defaultValue = defaultValue @@ -372,6 +380,22 @@ class PropertyDefinitionBuilder(private val id: String, } } +class ConstraintClauseBuilder { + private val constraints: MutableList<ConstraintClause> = mutableListOf() + //TODO("Implementation") + + fun validValues(values: List<JsonNode>) { + val constraintClause = ConstraintClause() + constraintClause.validValues = values.toMutableList() + constraints.add(constraintClause) + } + + fun build(): MutableList<ConstraintClause> { + return constraints + } +} + + class EntrySchemaBuilder(private val type: String) { private var entrySchema: EntrySchema = EntrySchema() diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt new file mode 100644 index 000000000..fdaf25c15 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.controllerblueprints.core.service + +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.springframework.context.ApplicationContext + +/** + * Generic Bluepring Dependency Service, which will be used mainly in scripts. + * This will be initialised only once during the Application startup. + * Function modules, shall add their own dependency function names as an extension function. + * + * @author Brinda Santh + */ + +object BluePrintDependencyService { + + lateinit var applicationContext: ApplicationContext + + fun inject(applicationContext: ApplicationContext) { + BluePrintDependencyService.applicationContext = applicationContext + } + + inline fun <reified T> instance(name: String): T { + return applicationContext.getBean(name) as? T + ?: throw BluePrintProcessorException("failed to get instance($name)") + } + + inline fun <reified T> instance(type: Class<T>): T { + return applicationContext.getBean(type) + ?: throw BluePrintProcessorException("failed to get instance($type)") + } +}
\ No newline at end of file @@ -15,7 +15,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.onap.ccsdk.parent</groupId> @@ -35,8 +36,8 @@ limitations under the License. <description>CCSDK Controller Design Studio</description> <modules> - <module>cds-ui</module> <module>components</module> + <module>cds-ui</module> <module>ms</module> </modules> @@ -54,12 +55,7 @@ limitations under the License. <sonar.tests>src/test</sonar.tests> <!--Only include java and kt files to the scan--> <sonar.inclusions>**/*.java,**/*.kt</sonar.inclusions> - <!--Specify path to load jacoco XLM report, as Sonar can't load Kotlin coverage from binary report. - Note: coverage for now is invalid and is failing to load because of: - "Cannot import coverage information for file '{file}', coverage data is invalid." - see https://github.com/jacoco/jacoco/issues/763 - That issue has been fixed in 0.8.3 , so we override the default ONAP - version here to pick up that fix --> + <!--Specify path to load jacoco XLM report, as Sonar can't load Kotlin coverage from binary report--> <sonar.coverage.jacoco.xmlReportPaths>${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml </sonar.coverage.jacoco.xmlReportPaths> <jacoco.version>0.8.3</jacoco.version> |