aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts13
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts8
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts19
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.html6
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.ts9
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.module.ts4
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.module.ts13
-rw-r--r--cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.service.ts20
-rw-r--r--cds-ui/server/src/datasources/rest.datasource.json39
-rw-r--r--cds-ui/server/src/datasources/rest.datasource.ts32
-rw-r--r--cds-ui/server/src/services/rest.service.ts46
-rw-r--r--components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml6
-rw-r--r--docs/datadictionary/complexResponse.rst27
-rw-r--r--docs/datadictionary/create_netbox_ip_address.rst61
-rw-r--r--docs/datadictionary/dbsystemcode.rst16
-rw-r--r--docs/datadictionary/dt-netbox-ip.rst33
-rw-r--r--docs/datadictionary/index.rst2
-rw-r--r--docs/datadictionary/resourcedefinitioncodesnip.rst83
-rw-r--r--docs/datadictionary/restauth.rst74
-rw-r--r--docs/microservices/bluePrintsProcessorMS.rst2
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt26
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/MoreMatchers.kt34
-rw-r--r--ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt11
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/ApiDataExtensions.kt28
-rw-r--r--ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt9
-rw-r--r--ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/ImperativeWorkflowExecutionService.kt42
-rw-r--r--ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt20
-rw-r--r--ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/DGWorkflowExecutionServiceTest.kt12
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt1
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt16
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintGraph.kt3
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt5
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowService.kt67
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowServiceTest.kt130
-rw-r--r--ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/ControllerBlueprintExceptionHandler.kt (renamed from ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt)16
35 files changed, 520 insertions, 413 deletions
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts
index 7b2eaeb17..cfd83f7c5 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts
@@ -331,18 +331,7 @@ export class EditorComponent implements OnInit {
download() {
console.log(this.artifactName);
// status = this.editorService.downloadCBA("/download-blueprint/" + this.artifactName + "/" + this.artifactVersion);
- status = this.editorService.downloadCBA("/"+this.artifactName + "/" + this.artifactVersion);
- window.alert(status);
- // .subscribe(response => {
- // console.log(response);
- // var blob = new Blob([response], { type: 'application/zip' });
- // const fileName = 'CBA';
- // saveAs(blob, fileName);
- // },
- // error => {
- // console.log(error);
- // }
- // );
+ this.editorService.downloadCBA("/"+this.artifactName + "/" + this.artifactVersion);
}
setEditorMode() {
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
index 025fc95d4..f1d1d148c 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
@@ -1,7 +1,7 @@
/*
============LICENSE_START==========================================
===================================================================
-Copyright (C) 2018 IBM Intellectual Property. All rights reserved.
+Copyright (C) 2018-19 IBM Intellectual Property. All rights reserved.
===================================================================
Unless otherwise specified, all software contained herein is licensed
@@ -26,10 +26,12 @@ import { Observable, observable } from 'rxjs';
import { ApiService } from '../../../../common/core/services/api.service';
import { saveAs } from 'file-saver';
import { BlueprintURLs } from '../../../../common/constants/app-constants';
+import { NotificationHandlerService } from 'src/app/common/core/services/notification-handler.service';
@Injectable()
export class EditorService {
- constructor(private _http: HttpClient, private api: ApiService) {
+ constructor(private _http: HttpClient, private api: ApiService,
+ private alertService: NotificationHandlerService,) {
}
enrich(body: FormData): Observable<any> {
@@ -40,7 +42,7 @@ export class EditorService {
.subscribe(response => {
let blob = new Blob([response], { 'type': "application/octet-stream" });
saveAs(blob, "CBA.zip");
- window.alert('Blueprint download successfull' );
+ this.alertService.success('Blueprint downloaded successfully' );
});
return "Download Success";
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts
index 174bdf183..f49517017 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts
@@ -48,7 +48,7 @@ export class MetadataComponent implements OnInit {
blueprintName: string;
uploadedFileName: string;
entryDefinition: string;
-
+
constructor(private formBuilder: FormBuilder, private store: Store<IAppState>,
private loader: LoaderService, private dataService: SelectTemplateService) {
this.bpState = this.store.select('blueprint');
@@ -60,12 +60,17 @@ export class MetadataComponent implements OnInit {
template_version: ['', Validators.required],
template_tags: ['', Validators.required]
});
+
}
ngOnInit() {
- this.dataService.getCbaOption().subscribe(
- res => {console.log("data from service " + res);}
+ this.dataService.currentMessage.subscribe(
+ res => {
+ let options = res;
+ console.log(options + " data from service ngoninit" + res);
+ }
);
+
this.bpState.subscribe(
blueprintdata => {
var blueprintState: IBlueprintState = { blueprint: blueprintdata.blueprint, isLoadSuccess: blueprintdata.isLoadSuccess, isSaveSuccess: blueprintdata.isSaveSuccess, isUpdateSuccess: blueprintdata.isUpdateSuccess };
@@ -76,8 +81,6 @@ export class MetadataComponent implements OnInit {
this.uploadedFileName = blueprintdata.uploadedFileName;
this.entryDefinition = blueprintdata.entryDefinition;
-
-
var blueprintState: IBlueprintState = { blueprint: blueprintdata.blueprint, isLoadSuccess: blueprintdata.isLoadSuccess, isSaveSuccess: blueprintdata.isSaveSuccess, isUpdateSuccess: blueprintdata.isUpdateSuccess };
this.metadata = blueprintState.blueprint.metadata;
this.blueprint = blueprintState.blueprint;
@@ -99,11 +102,7 @@ export class MetadataComponent implements OnInit {
});
})
}
-ngAfterInit(){
- this.dataService.getCbaOption().subscribe(
- res => {console.log("data from service after init" + res);}
- );
-}
+
UploadMetadata() {
this.loader.showLoader();
this.metadata = Object.assign({}, this.CBAMetadataForm.value);
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.html b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.html
index 648271028..9cab6c44d 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.html
+++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.html
@@ -41,9 +41,9 @@ limitations under the License.
<br>{{option.blueprintModel.updatedBy}}
</mat-card-content>
<mat-card-actions class="flexBox">
- <button matStepperNext mat-menu-item (click)="editCBA(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,edit)">Edit</button>
- <button matStepperNext mat-menu-item (click)="editCBA(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,clone)">Clone</button>
- <button matStepperNext mat-menu-item (click)="editCBA(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,info)">Info</button>
+ <button matStepperNext mat-menu-item (click)="editCBA(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,1)">Edit</button>
+ <button matStepperNext mat-menu-item (click)="editCBA(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,2)">Clone</button>
+ <button matStepperNext mat-menu-item (click)="editCBA(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,3)">Info</button>
</mat-card-actions>
</mat-card>
</div>
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.ts
index 588854f6b..47771a7aa 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-from-database/search-from-database.component.ts
@@ -33,7 +33,7 @@ import { IBlueprint } from '../../../../../common/core/store/models/blueprint.mo
import { IBlueprintState } from '../../../../../common/core/store/models/blueprintState.model';
import { IAppState } from '../../../../../common/core/store/state/app.state';
import { SetBlueprintState } from '../../../../../common/core/store/actions/blueprint.action';
-
+import { SelectTemplateService } from '../../select-template.service';
@Component({
selector: 'app-search-from-database',
templateUrl: './search-from-database.component.html',
@@ -61,8 +61,8 @@ export class SearchFromDatabaseComponent implements OnInit {
searchText: string = '';
constructor(private _formBuilder: FormBuilder,
- private searchService: SearchTemplateService, private alertService: NotificationHandlerService,
- private loader: LoaderService, private store: Store<IAppState>) { }
+ private searchService: SearchTemplateService, private alertService: NotificationHandlerService,
+ private loader: LoaderService, private store: Store<IAppState>, private cbEditOption: SelectTemplateService) { }
ngOnInit() {
this.myControl = this._formBuilder.group({
@@ -85,7 +85,8 @@ export class SearchFromDatabaseComponent implements OnInit {
})
}
- editCBA(artifactName: string,artifactVersion:string, option: string) {
+ editCBA(artifactName: string, artifactVersion: string, option: string) {
+ this.cbEditOption.setCbaOption(option);
this.zipFile.generateAsync({ type: "blob" })
.then(blob => {
const formData = new FormData();
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.module.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.module.ts
index 9bafaebdc..a4e30a494 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.module.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/search-template/search-template.module.ts
@@ -26,7 +26,7 @@ import { SearchTemplateComponent } from './search-template.component';
import { ReactiveFormsModule } from '@angular/forms';
import { AppMaterialModule } from 'src/app/common/modules/app-material.module';
import { SharedModule} from 'src/app/common/shared/shared.module';
-import { SelectTemplateService } from 'src/app/feature-modules/blueprint/select-template/select-template.service';
+// import { SelectTemplateService } from 'src/app/feature-modules/blueprint/select-template/select-template.service';
@NgModule({
declarations: [
@@ -42,6 +42,6 @@ import { SelectTemplateService } from 'src/app/feature-modules/blueprint/select-
SearchTemplateComponent,
SearchFromDatabaseComponent
],
- providers:[ SelectTemplateService]
+ // providers:[ SelectTemplateService]
})
export class SearchTemplateModule { }
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.module.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.module.ts
index f66b78c08..085da7247 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.module.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.module.ts
@@ -27,15 +27,15 @@ import { MetadataComponent } from './metadata/metadata.component';
import { SelectTemplateComponent } from './select-template.component';
import { SelectTemplateRoutingModule } from './select-template-routing.module';
import { AppMaterialModule } from 'src/app/common/modules/app-material.module';
-import { SearchTemplateModule} from './search-template/search-template.module';
-
+import { SearchTemplateModule } from './search-template/search-template.module';
+import { SelectTemplateService } from './select-template.service';
@NgModule({
declarations: [
TemplateOptionsComponent,
- MetadataComponent,
- SelectTemplateComponent
+ MetadataComponent,
+ SelectTemplateComponent
],
- exports: [
+ exports: [
TemplateOptionsComponent,
SearchTemplateComponent,
MetadataComponent,
@@ -47,6 +47,9 @@ import { SearchTemplateModule} from './search-template/search-template.module';
ReactiveFormsModule,
AppMaterialModule,
SearchTemplateModule
+ ],
+ providers: [
+ SelectTemplateService
]
})
export class SelectTemplateModule { }
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.service.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.service.ts
index fa18cbd25..d6bcfb33b 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.service.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/select-template.service.ts
@@ -20,21 +20,29 @@ limitations under the License.
*/
import { Injectable } from '@angular/core';
-import { Observable, of } from 'rxjs';
+import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SelectTemplateService {
cbaOption: string;
+ private messageSource = new BehaviorSubject('default message');
+ currentMessage = this.messageSource.asObservable();
constructor() { }
setCbaOption(option: string) {
- this.cbaOption = option;
- }
-
- getCbaOption(): Observable<string> {
- return of(this.cbaOption);
+ this.messageSource.next(option);
}
+ // setCbaOption(option: string) {
+ // this.cbaOption = option;
+ // console.log("CBA option set to"+this.cbaOption+":"+option);
+ // }
+
+ // getCbaOption(): Observable<any> {
+ // console.log("CBA option is "+this.cbaOption);
+ // // return of(this.cbaOption);
+ // return this.cbaOption.asObservable();
+ // }
}
diff --git a/cds-ui/server/src/datasources/rest.datasource.json b/cds-ui/server/src/datasources/rest.datasource.json
deleted file mode 100644
index 86f33fbd4..000000000
--- a/cds-ui/server/src/datasources/rest.datasource.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "restConfig",
- "connector": "rest",
- "options": {
- "headers": {
- "accept": "application/json",
- "content-type": "application/json"
- }
- },
- "operations": [
- {
- "template": {
- "method": "GET",
- "url": ""
- },
- "functions": {
- "getEnricheddata": [""]
- }
- },
- {
- "template": {
- "method": "POST",
- "url": ""
- },
- "functions": {
- "saveBlueprint": [""]
- }
- },
- {
- "template": {
- "method": "POST",
- "url": ""
- },
- "functions": {
- "test": [""]
- }
- }
-]
-} \ No newline at end of file
diff --git a/cds-ui/server/src/datasources/rest.datasource.ts b/cds-ui/server/src/datasources/rest.datasource.ts
deleted file mode 100644
index 1b5a44d79..000000000
--- a/cds-ui/server/src/datasources/rest.datasource.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-============LICENSE_START==========================================
-===================================================================
-Copyright (C) 2018-19 IBM Intellectual Property. All rights reserved.
-===================================================================
-
-Unless otherwise specified, all software contained herein is licensed
-under the Apache License, Version 2.0 (the License);
-you may not use this software except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-============LICENSE_END============================================
-*/
-
-
-import { juggler } from '@loopback/service-proxy';
-import * as config from './rest.datasource.json';
-
-
-export class RestDataSource extends juggler.DataSource {
- static dataSourceName = 'rest';
- constructor(dsConfig: object = config) {
- super(dsConfig);
- }
-}
diff --git a/cds-ui/server/src/services/rest.service.ts b/cds-ui/server/src/services/rest.service.ts
deleted file mode 100644
index b94ea4dd3..000000000
--- a/cds-ui/server/src/services/rest.service.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-============LICENSE_START==========================================
-===================================================================
-Copyright (C) 2018-19 IBM Intellectual Property. All rights reserved.
-===================================================================
-
-Unless otherwise specified, all software contained herein is licensed
-under the Apache License, Version 2.0 (the License);
-you may not use this software except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-============LICENSE_END============================================
-*/
-
-import {getService, juggler} from '@loopback/service-proxy';
-import {inject, Provider} from '@loopback/core';
-import {RestDataSource} from '../datasources/rest.datasource';
-
-
-export interface RestResponseData {
- userId: number;
- id: number;
- title: string;
- completed: boolean;
-}
-
-export interface RestService {
- getrestdata(id?: number): Promise<RestResponseData>;
-}
-export class RestProvider implements Provider<RestService> {
- constructor(
- @inject('datasources.rest')
- protected dataSource: juggler.DataSource = new RestDataSource(),
- ) {}
-
- value(): Promise<RestService> {
- return getService(this.dataSource);
- }
-} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml
index 789659eb2..3a5903c49 100644
--- a/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml
+++ b/components/model-catalog/blueprint-model/uat-blueprints/pnf_config/Tests/uat.yaml
@@ -96,7 +96,8 @@ external-services:
- request:
method: PUT
path: &configUri [ restconf/config, &nodeIdentifier [network-topology:network-topology/topology/topology-netconf/node, *pnfId]]
- content-type: application/json
+ headers:
+ Content-Type: application/json
body:
node:
- node-id: *pnfId
@@ -124,7 +125,8 @@ external-services:
- request:
method: PATCH
path: [*configUri, *configletResourcePath]
- content-type: application/yang.patch+json
+ headers:
+ Content-Type: application/yang.patch+json
body: *assignPatch
- request:
method: DELETE
diff --git a/docs/datadictionary/complexResponse.rst b/docs/datadictionary/complexResponse.rst
index aa39ff235..d32d13de5 100644
--- a/docs/datadictionary/complexResponse.rst
+++ b/docs/datadictionary/complexResponse.rst
@@ -5,16 +5,17 @@
complex Response code
=====================
-{
- "id": 4,
- "address": "192.168.10.2/32",
- "vrf": null,
- "tenant": null,
- "status": 1,
- "role": null,
- "interface": null,
- "description": "",
- "nat_inside": null,
- "created": "2018-08-30",
- "last_updated": "2018-08-30T14:59:05.277820Z"
-}
+.. code-block:: json
+ :linenos:
+
+ "id": 4,
+ "address": "192.168.10.2/32",
+ "vrf": null,
+ "tenant": null,
+ "status": 1,
+ "role": null,
+ "interface": null,
+ "description": "",
+ "nat_inside": null,
+ "created": "2018-08-30",
+ "last_updated": "2018-08-30T14:59:05.277820Z" \ No newline at end of file
diff --git a/docs/datadictionary/create_netbox_ip_address.rst b/docs/datadictionary/create_netbox_ip_address.rst
index 5d9a9be87..f17ddb407 100644
--- a/docs/datadictionary/create_netbox_ip_address.rst
+++ b/docs/datadictionary/create_netbox_ip_address.rst
@@ -5,32 +5,35 @@
create_netbox_ip_address code
=============================
-{
- "tags" : "oam-local-ipv4-address",
- "name" : "create_netbox_ip",
- "property" : {
- "description" : "netbox ip",
- "type" : "dt-netbox-ip"
- },
- "updated-by" : "adetalhouet",
- "sources" : {
- "primary-config-data" : {
- "type" : "source-rest",
- "properties" : {
- "type" : "JSON",
- "verb" : "POST",
- "endpoint-selector" : "ipam-1",
- "url-path" : "/api/ipam/prefixes/$prefixId/available-ips/",
- "path" : "",
- "input-key-mapping" : {
- "prefixId" : "prefix-id"
- },
- "output-key-mapping" : {
- "address" : "address",
- "id" : "id"
- },
- "key-dependencies" : [ "prefix-id" ]
- }
- }
- }
- } \ No newline at end of file
+.. code-block:: json
+ :linenos:
+
+ {
+ "tags" : "oam-local-ipv4-address",
+ "name" : "create_netbox_ip",
+ "property" : {
+ "description" : "netbox ip",
+ "type" : "dt-netbox-ip"
+ },
+ "updated-by" : "adetalhouet",
+ "sources" : {
+ "primary-config-data" : {
+ "type" : "source-rest",
+ "properties" : {
+ "type" : "JSON",
+ "verb" : "POST",
+ "endpoint-selector" : "ipam-1",
+ "url-path" : "/api/ipam/prefixes/$prefixId/available-ips/",
+ "path" : "",
+ "input-key-mapping" : {
+ "prefixId" : "prefix-id"
+ },
+ "output-key-mapping" : {
+ "address" : "address",
+ "id" : "id"
+ },
+ "key-dependencies" : [ "prefix-id" ]
+ }
+ }
+ }
+ } \ No newline at end of file
diff --git a/docs/datadictionary/dbsystemcode.rst b/docs/datadictionary/dbsystemcode.rst
index 5051d1e7d..d6cda5b6c 100644
--- a/docs/datadictionary/dbsystemcode.rst
+++ b/docs/datadictionary/dbsystemcode.rst
@@ -4,12 +4,14 @@
Dbsystemcode
============
-
-"dsl_definitions": {
- "dynamic-db-source": {
+.. code-block:: json
+ :linenos:
+
+ "dsl_definitions": {
+ "dynamic-db-source": {
"type": "maria-db",
"url": "jdbc:mysql://localhost:3306/sdnctl",
- "username": "sdnctl",
- "password": "sdnctl"
- }
-} \ No newline at end of file
+ "username": <username>,
+ "password": <password>
+ }
+ } \ No newline at end of file
diff --git a/docs/datadictionary/dt-netbox-ip.rst b/docs/datadictionary/dt-netbox-ip.rst
index 9410580fb..6dc3c8464 100644
--- a/docs/datadictionary/dt-netbox-ip.rst
+++ b/docs/datadictionary/dt-netbox-ip.rst
@@ -5,18 +5,21 @@
dt-netbox-ip code
=================
-{
- "version": "1.0.0",
- "description": "This is Netbox IP Data Type",
- "properties": {
- "address": {
- "required": true,
- "type": "string"
- },
- "id": {
- "required": true,
- "type": "integer"
- }
- },
- "derived_from": "tosca.datatypes.Root"
-}
+.. code-block:: none
+ :linenos:
+
+ {
+ "version": "1.0.0",
+ "description": "This is Netbox IP Data Type",
+ "properties": {
+ "address": {
+ "required": true,
+ "type": "string"
+ },
+ "id": {
+ "required": true,
+ "type": "integer"
+ }
+ },
+ "derived_from": "tosca.datatypes.Root"
+ }
diff --git a/docs/datadictionary/index.rst b/docs/datadictionary/index.rst
index 3ac8587ee..4039cca6d 100644
--- a/docs/datadictionary/index.rst
+++ b/docs/datadictionary/index.rst
@@ -40,7 +40,7 @@ Here is how input-key-mapping, output-key-mapping and key-dependencies can be us
.. toctree::
:maxdepth: 1
- resourcedefinitioncodesnip
+ resourcedefinitioncodesnip
Resource source:
diff --git a/docs/datadictionary/resourcedefinitioncodesnip.rst b/docs/datadictionary/resourcedefinitioncodesnip.rst
index a91767678..6504a07c3 100644
--- a/docs/datadictionary/resourcedefinitioncodesnip.rst
+++ b/docs/datadictionary/resourcedefinitioncodesnip.rst
@@ -5,44 +5,45 @@
Source Capability Code
======================
-{
- "description": "This is Component Resource Source Node Type",
- "version": "1.0.0",
- "properties": {
- "script-type": {
- "required": true,
- "type": "string",
- "default": "kotlin",
- "constraints": [
- {
- "valid_values": [
- "kotlin",
- "jython"
- ]
- }
- ]
- },
- "script-class-reference": {
- "description": "Capability reference name for internal and kotlin, for jython script file path",
- "required": true,
- "type": "string"
- },
- "instance-dependencies": {
- "required": false,
- "description": "Instance dependency Names to Inject to Kotlin / Jython Script.",
- "type": "list",
- "entry_schema": {
- "type": "string"
- }
- },
- "key-dependencies": {
- "description": "Resource Resolution dependency dictionary names.",
- "required": true,
- "type": "list",
- "entry_schema": {
- "type": "string"
- }
- }
- },
- "derived_from": "tosca.nodes.ResourceSource"
-}
+.. code-block:: json
+ :linenos:
+
+ "description": "This is Component Resource Source Node Type",
+ "version": "1.0.0",
+ "properties": {
+ "script-type": {
+ "required": true,
+ "type": "string",
+ "default": "kotlin",
+ "constraints": [
+ {
+ "valid_values": [
+ "kotlin",
+ "jython"
+ ]
+ }
+ ]
+ },
+ "script-class-reference": {
+ "description": "Capability reference name for internal and kotlin, for jython script file path",
+ "required": true,
+ "type": "string"
+ },
+ "instance-dependencies": {
+ "required": false,
+ "description": "Instance dependency Names to Inject to Kotlin / Jython Script.",
+ "type": "list",
+ "entry_schema": {
+ "type": "string"
+ }
+ },
+ "key-dependencies": {
+ "description": "Resource Resolution dependency dictionary names.",
+ "required": true,
+ "type": "list",
+ "entry_schema": {
+ "type": "string"
+ }
+ }
+ },
+ "derived_from": "tosca.nodes.ResourceSource" \ No newline at end of file
diff --git a/docs/datadictionary/restauth.rst b/docs/datadictionary/restauth.rst
index 40c179375..9f628696c 100644
--- a/docs/datadictionary/restauth.rst
+++ b/docs/datadictionary/restauth.rst
@@ -7,36 +7,48 @@ Resource Rest Authentication
----------------------------
token-auth:
-
-"dsl_definitions": {
- "dynamic-rest-source": {
- "type" : "token-auth",
- "url" : "http://localhost:32778",
- "token" : "Token 0123456789abcdef0123456789abcdef01234567"
- }
-}
-
+~~~~~~~~~~~
+
+.. code-block:: json
+ :linenos:
+
+ "dsl_definitions": {
+ "dynamic-rest-source": {
+ "type" : "token-auth",
+ "url" : "http://localhost:32778",
+ "token" : <token>
+ }
+ }
+
basic-auth:
-
-"dsl_definitions": {
- "dynamic-rest-source": {
- "type" : "basic-auth",
- "url" : "http://localhost:32778",
- "username" : "bob",
- "password": "marley"
- }
-}
-
+~~~~~~~~~~~
+
+.. code-block:: json
+ :linenos:
+
+ "dsl_definitions": {
+ "dynamic-rest-source": {
+ "type" : "basic-auth",
+ "url" : "http://localhost:32778",
+ "username" : <username>,
+ "password": <password>
+ }
+ }
+
ssl-basic-auth:
-
-"dsl_definitions": {
- "dynamic-rest-source": {
- "type" : "ssl-basic-auth",
- "url" : "http://localhost:32778",
- "keyStoreInstance": "JKS or PKCS12",
- "sslTrust": "trusture",
- "sslTrustPassword": "trustore password",
- "sslKey": "keystore",
- "sslKeyPassword: "keystore password"
- }
-} \ No newline at end of file
+~~~~~~~~~~~~~~~
+
+.. code-block:: json
+ :linenos:
+
+ "dsl_definitions": {
+ "dynamic-rest-source": {
+ "type" : "ssl-basic-auth",
+ "url" : "http://localhost:32778",
+ "keyStoreInstance": "JKS or PKCS12",
+ "sslTrust": "trusture",
+ "sslTrustPassword": <password>,
+ "sslKey": "keystore",
+ "sslKeyPassword: <password>
+ }
+ } \ No newline at end of file
diff --git a/docs/microservices/bluePrintsProcessorMS.rst b/docs/microservices/bluePrintsProcessorMS.rst
index bd0b6997d..292f99e51 100644
--- a/docs/microservices/bluePrintsProcessorMS.rst
+++ b/docs/microservices/bluePrintsProcessorMS.rst
@@ -84,4 +84,4 @@ Testing the environment:
Point your browser to http://localhost:8000/api/v1/execution-service/ping (please note that the port is 8000, not 8080)
-To authenticate, use ccsdkapps / ccsdkapps as login / password. \ No newline at end of file
+To authenticate, use login user id and password. \ No newline at end of file
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt
index ad4173c9e..dfa0a8563 100644
--- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintsAcceptanceTest.kt
@@ -35,6 +35,7 @@ import org.junit.ClassRule
import org.junit.Rule
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
+import org.mockito.Answers
import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestLibConstants
import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
@@ -105,7 +106,7 @@ class BlueprintsAcceptanceTest(private val blueprintName: String, private val fi
@JvmField
val springMethodRule = SpringMethodRule()
- @MockBean(name = RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY)
+ @MockBean(name = RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY, answer = Answers.RETURNS_SMART_NULLS)
lateinit var restClientFactory: BluePrintRestLibPropertyService
@Autowired
@@ -130,10 +131,10 @@ class BlueprintsAcceptanceTest(private val blueprintName: String, private val fi
uploadBlueprint(blueprintName)
- // Configure mocked external services
- val expectationPerClient = uat.externalServices.associateBy(
+ // Configure mocked external services and save their expected requests for further validation
+ val requestsPerClient = uat.externalServices.associateBy(
{ service -> createRestClientMock(service.selector, service.expectations) },
- { service -> service.expectations }
+ { service -> service.expectations.map { it.request } }
)
// Run processes
@@ -143,14 +144,14 @@ class BlueprintsAcceptanceTest(private val blueprintName: String, private val fi
JsonNormalizer.getNormalizer(mapper, process.responseNormalizerSpec))
}
- // Validate request payloads to external services
- for ((mockClient, expectations) in expectationPerClient) {
- expectations.forEach { expectation ->
+ // Validate requests to external services
+ for ((mockClient, requests) in requestsPerClient) {
+ requests.forEach { request ->
verify(mockClient, atLeastOnce()).exchangeResource(
- eq(expectation.request.method),
- eq(expectation.request.path),
- argThat { assertJsonEqual(expectation.request.body, this) },
- expectation.request.requestHeadersMatcher())
+ eq(request.method),
+ eq(request.path),
+ argThat { assertJsonEqual(request.body, this) },
+ argThat(RequiredMapEntriesMatcher(request.headers)))
}
// Don't mind the invocations to the overloaded exchangeResource(String, String, String)
verify(mockClient, atLeast(0)).exchangeResource(any(), any(), any())
@@ -160,7 +161,8 @@ class BlueprintsAcceptanceTest(private val blueprintName: String, private val fi
private fun createRestClientMock(selector: String, restExpectations: List<ExpectationDefinition>)
: BlueprintWebClientService {
- val restClient = mock<BlueprintWebClientService>(verboseLogging = true)
+ val restClient = mock<BlueprintWebClientService>(verboseLogging = true,
+ defaultAnswer = Answers.RETURNS_SMART_NULLS)
// Delegates to overloaded exchangeResource(String, String, String, Map<String, String>)
whenever(restClient.exchangeResource(any(), any(), any()))
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/MoreMatchers.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/MoreMatchers.kt
new file mode 100644
index 000000000..71e07ab4c
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/MoreMatchers.kt
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import com.google.common.collect.Maps
+import org.mockito.ArgumentMatcher
+
+class RequiredMapEntriesMatcher<K, V>(private val requiredEntries: Map<K, V>) : ArgumentMatcher<Map<K, V>> {
+ override fun matches(argument: Map<K, V>?): Boolean {
+ val missingEntries = Maps.difference(requiredEntries, argument).entriesOnlyOnLeft()
+ return missingEntries.isEmpty()
+ }
+
+ override fun toString(): String {
+ return requiredEntries.toString()
+ }
+}
diff --git a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt
index ce2061168..abb1dfcd1 100644
--- a/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt
+++ b/ms/blueprintsprocessor/application/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/UatDefinition.kt
@@ -24,8 +24,6 @@ import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.node.MissingNode
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.eq
import org.yaml.snakeyaml.Yaml
import java.nio.file.Path
@@ -35,13 +33,8 @@ data class ProcessDefinition(val name: String, val request: JsonNode, val expect
data class RequestDefinition(val method: String,
@JsonDeserialize(using = PathDeserializer::class)
val path: String,
- @JsonAlias("content-type")
- val contentType: String? = null,
- val body: JsonNode = MissingNode.getInstance()) {
- fun requestHeadersMatcher(): Map<String, String> {
- return if (contentType != null) eq(mapOf("Content-Type" to contentType)) else any()
- }
-}
+ val headers: Map<String, String> = emptyMap(),
+ val body: JsonNode = MissingNode.getInstance())
data class ResponseDefinition(val status: Int = 200, val body: JsonNode = MissingNode.getInstance()) {
companion object {
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/ApiDataExtensions.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/ApiDataExtensions.kt
new file mode 100644
index 000000000..47b55b018
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/ApiDataExtensions.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.core
+
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.cds.controllerblueprints.core.asType
+import kotlin.reflect.KClass
+
+
+fun <T : Any> ExecutionServiceInput.payloadAsType(clazzType: KClass<T>): T {
+ val actionName = this.actionIdentifiers.actionName
+ val requestJsonNode = this.payload.get("$actionName-request")
+ return requestJsonNode.asType(clazzType.java)
+} \ 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/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
index 408bb58ed..8759338b7 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
@@ -19,6 +19,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.services.execution
import com.fasterxml.jackson.databind.JsonNode
+import kotlinx.coroutines.withTimeout
import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.Status
@@ -47,6 +48,7 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
lateinit var interfaceName: String
lateinit var operationName: String
lateinit var nodeTemplateName: String
+ var timeout: Int = 180
var operationInputs: MutableMap<String, JsonNode> = hashMapOf()
override fun getName(): String {
@@ -87,6 +89,9 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
this.operationInputs.putAll(operationResolvedProperties)
+ val timeout = this.operationInputs.getOptionalAsInt(BluePrintConstants.PROPERTY_CURRENT_TIMEOUT)
+ timeout?.let { this.timeout = timeout }
+
return executionRequest
}
@@ -118,7 +123,9 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
override suspend fun applyNB(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
try {
prepareRequestNB(executionServiceInput)
- processNB(executionServiceInput)
+ withTimeout((timeout * 1000).toLong()) {
+ processNB(executionServiceInput)
+ }
} catch (runtimeException: RuntimeException) {
log.error("failed in ${getName()} : ${runtimeException.message}", runtimeException)
recoverNB(runtimeException, executionServiceInput)
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/ImperativeWorkflowExecutionService.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/ImperativeWorkflowExecutionService.kt
index 2a14be216..6bee17f4b 100644
--- a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/ImperativeWorkflowExecutionService.kt
+++ b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/ImperativeWorkflowExecutionService.kt
@@ -44,10 +44,8 @@ class ImperativeWorkflowExecutionService(
val graph = bluePrintContext.workflowByName(workflowName).asGraph()
- val deferredOutput = CompletableDeferred<ExecutionServiceOutput>()
- imperativeBluePrintWorkflowService.executeWorkflow(graph, bluePrintRuntimeService,
- executionServiceInput, deferredOutput)
- return deferredOutput.await()
+ return imperativeBluePrintWorkflowService.executeWorkflow(graph, bluePrintRuntimeService,
+ executionServiceInput)
}
}
@@ -60,35 +58,41 @@ open class ImperativeBluePrintWorkflowService(private val nodeTemplateExecutionS
lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*>
lateinit var executionServiceInput: ExecutionServiceInput
lateinit var workflowName: String
- lateinit var deferredExecutionServiceOutput: CompletableDeferred<ExecutionServiceOutput>
override suspend fun executeWorkflow(graph: Graph, bluePrintRuntimeService: BluePrintRuntimeService<*>,
- input: ExecutionServiceInput,
- output: CompletableDeferred<ExecutionServiceOutput>) {
+ input: ExecutionServiceInput): ExecutionServiceOutput {
this.graph = graph
this.bluePrintRuntimeService = bluePrintRuntimeService
this.executionServiceInput = input
this.workflowName = this.executionServiceInput.actionIdentifiers.actionName
- this.deferredExecutionServiceOutput = output
this.workflowId = bluePrintRuntimeService.id()
+ val output = CompletableDeferred<ExecutionServiceOutput>()
val startMessage = WorkflowExecuteMessage(input, output)
- workflowActor().send(startMessage)
+ val workflowActor = workflowActor()
+ if (!workflowActor.isClosedForSend) {
+ workflowActor.send(startMessage)
+ } else {
+ throw BluePrintProcessorException("workflow($workflowActor) actor is closed")
+ }
+ return output.await()
}
override suspend fun initializeWorkflow(input: ExecutionServiceInput): EdgeLabel {
return EdgeLabel.SUCCESS
}
- override suspend fun prepareWorkflowOutput(exception: BluePrintProcessorException?): ExecutionServiceOutput {
- val wfStatus = if (exception != null) {
- val status = Status()
- status.message = BluePrintConstants.STATUS_FAILURE
- status.errorMessage = exception.message
- status
- } else {
- val status = Status()
- status.message = BluePrintConstants.STATUS_SUCCESS
- status
+ override suspend fun prepareWorkflowOutput(): ExecutionServiceOutput {
+ val wfStatus = Status().apply {
+ if (exceptions.isNotEmpty()) {
+ exceptions.forEach {
+ val errorMessage = it.message ?: ""
+ bluePrintRuntimeService.getBluePrintError().addError(errorMessage)
+ log.error("workflow($workflowId) exception :", it)
+ }
+ message = BluePrintConstants.STATUS_FAILURE
+ } else {
+ message = BluePrintConstants.STATUS_SUCCESS
+ }
}
return ExecutionServiceOutput().apply {
commonHeader = executionServiceInput.commonHeader
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt
index 89732e300..b64177aab 100644
--- a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt
+++ b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt
@@ -22,7 +22,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutp
import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData
import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
-import org.onap.ccsdk.cds.controllerblueprints.core.putJsonElement
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
import org.slf4j.LoggerFactory
@@ -37,15 +37,22 @@ open class NodeTemplateExecutionService {
executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
// Get the Blueprint Context
val blueprintContext = bluePrintRuntimeService.bluePrintContext()
+
+ val nodeTemplate = blueprintContext.nodeTemplateByName(nodeTemplateName)
// Get the Component Name, NodeTemplate type is mapped to Component Name
- val componentName = blueprintContext.nodeTemplateByName(nodeTemplateName).type
+ val componentName = nodeTemplate.type
val interfaceName = blueprintContext.nodeTemplateFirstInterfaceName(nodeTemplateName)
val operationName = blueprintContext.nodeTemplateFirstInterfaceFirstOperationName(nodeTemplateName)
+ val nodeTemplateImplementation = blueprintContext
+ .nodeTemplateOperationImplementation(nodeTemplateName, interfaceName, operationName)
+
+ val timeout: Int = nodeTemplateImplementation?.timeout ?: 180
+
log.info("executing node template($nodeTemplateName) component($componentName) " +
- "interface($interfaceName) operation($operationName)")
+ "interface($interfaceName) operation($operationName) with timeout($timeout) sec.")
// Get the Component Instance
val plugin = BluePrintDependencyService.instance<AbstractComponentFunction>(componentName)
@@ -62,9 +69,10 @@ open class NodeTemplateExecutionService {
// Populate Step Meta Data
val stepInputs: MutableMap<String, JsonNode> = hashMapOf()
- stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, nodeTemplateName)
- stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, interfaceName)
- stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, operationName)
+ stepInputs[BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE] = nodeTemplateName.asJsonPrimitive()
+ stepInputs[BluePrintConstants.PROPERTY_CURRENT_INTERFACE] = interfaceName.asJsonPrimitive()
+ stepInputs[BluePrintConstants.PROPERTY_CURRENT_OPERATION] = operationName.asJsonPrimitive()
+ stepInputs[BluePrintConstants.PROPERTY_CURRENT_TIMEOUT] = timeout.asJsonPrimitive()
val stepInputData = StepData().apply {
name = nodeTemplateName
properties = stepInputs
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/DGWorkflowExecutionServiceTest.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/DGWorkflowExecutionServiceTest.kt
index ac2d7d62c..6e7e3cb8d 100644
--- a/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/DGWorkflowExecutionServiceTest.kt
+++ b/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/workflow/DGWorkflowExecutionServiceTest.kt
@@ -18,14 +18,18 @@
package org.onap.ccsdk.cds.blueprintsprocessor.services.workflow
import kotlinx.coroutines.runBlocking
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
import org.onap.ccsdk.cds.blueprintsprocessor.services.workflow.executor.ComponentExecuteNodeExecutor
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonReactorUtils
import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.ApplicationContext
+import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringRunner
import kotlin.test.assertEquals
@@ -36,9 +40,17 @@ import kotlin.test.assertNotNull
class DGWorkflowExecutionServiceTest {
@Autowired
+ lateinit var applicationContext: ApplicationContext
+
+ @Autowired
lateinit var dgWorkflowExecutionService: DGWorkflowExecutionService
+ @Before
+ fun init() {
+ BluePrintDependencyService.inject(applicationContext)
+ }
+
@Test
fun testExecuteDirectedGraph() {
runBlocking {
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt
index 064c196ed..ba5815bb6 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt
@@ -180,6 +180,7 @@ object BluePrintConstants {
const val PROPERTY_CURRENT_NODE_TEMPLATE = "current-node-template"
const val PROPERTY_CURRENT_INTERFACE = "current-interface"
const val PROPERTY_CURRENT_OPERATION = "current-operation"
+ const val PROPERTY_CURRENT_TIMEOUT = "current-timeout"
const val PROPERTY_CURRENT_IMPLEMENTATION = "current-implementation"
const val PROPERTY_EXECUTION_REQUEST = "execution-request"
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
index 93ba15e99..08bc6c3fd 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
@@ -242,6 +242,22 @@ fun Map<String, JsonNode>.getAsDouble(key: String): Double {
return this[key]?.asDouble() ?: throw BluePrintException("couldn't find value for key($key)")
}
+fun Map<String, JsonNode>.getOptionalAsString(key: String): String? {
+ return if (this.containsKey(key)) this[key]!!.asText() else null
+}
+
+fun Map<String, JsonNode>.getOptionalAsBoolean(key: String): Boolean? {
+ return if (this.containsKey(key)) this[key]!!.asBoolean() else null
+}
+
+fun Map<String, JsonNode>.getOptionalAsInt(key: String): Int? {
+ return if (this.containsKey(key)) this[key]!!.asInt() else null
+}
+
+fun Map<String, JsonNode>.getOptionalAsDouble(key: String): Double? {
+ return if (this.containsKey(key)) this[key]!!.asDouble() else null
+}
+
// Checks
inline fun checkEquals(value1: String?, value2: String?, lazyMessage: () -> Any): Boolean {
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintGraph.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintGraph.kt
index 9e1b7498e..fc796c9ed 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintGraph.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintGraph.kt
@@ -33,7 +33,8 @@ enum class NodeStatus(val id: String) {
READY("ready"),
EXECUTING("executing"),
EXECUTED("executed"),
- SKIPPED("skipped")
+ SKIPPED("skipped"),
+ TERMINATED("terminated")
}
class Graph {
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt
index 066516fcc..b368c01aa 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt
@@ -216,6 +216,11 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) {
?: throw BluePrintException("could't get NodeTemplate($nodeTemplateName)'s first InterfaceAssignment's first OperationAssignment name")
}
+ fun nodeTemplateOperationImplementation(nodeTemplateName: String, interfaceName: String, operationName: String)
+ : Implementation? {
+ return nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName).implementation
+ }
+
fun nodeTemplateInterfaceOperationInputs(nodeTemplateName: String, interfaceName: String, operationName: String): MutableMap<String, JsonNode>? {
return nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName).inputs
}
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowService.kt
index 905150213..5cec3c947 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowService.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowService.kt
@@ -30,13 +30,12 @@ import kotlin.coroutines.CoroutineContext
interface BluePrintWorkFlowService<In, Out> {
/** Executes imperative workflow graph [graph] for the bluePrintRuntimeService [bluePrintRuntimeService]
- * and workflow input [input], response will be retrieve from output [output]*/
- suspend fun executeWorkflow(graph: Graph, bluePrintRuntimeService: BluePrintRuntimeService<*>,
- input: In, output: CompletableDeferred<Out>)
+ * and workflow input [input]*/
+ suspend fun executeWorkflow(graph: Graph, bluePrintRuntimeService: BluePrintRuntimeService<*>, input: In): Out
suspend fun initializeWorkflow(input: In): EdgeLabel
- suspend fun prepareWorkflowOutput(exception: BluePrintProcessorException?): Out
+ suspend fun prepareWorkflowOutput(): Out
/** Prepare the message for the Node */
suspend fun prepareNodeExecutionMessage(node: Graph.Node): NodeExecuteMessage<In, Out>
@@ -91,6 +90,8 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
lateinit var workflowId: String
+ var exceptions: MutableList<Exception> = arrayListOf()
+
final override val coroutineContext: CoroutineContext
get() = job + CoroutineName("Wf")
@@ -100,7 +101,7 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
throw CancellationException("Workflow($workflowId) cancelled as requested")
}
- fun workflowActor() = actor<WorkflowMessage<In, Out>>(coroutineContext, Channel.UNLIMITED) {
+ suspend fun workflowActor() = actor<WorkflowMessage<In, Out>>(coroutineContext, Channel.UNLIMITED) {
/** Process the workflow execution message */
suspend fun executeMessageActor(workflowExecuteMessage: WorkflowExecuteMessage<In, Out>) {
@@ -119,13 +120,11 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
// Wait for workflow completion or Error
nodeActor.invokeOnClose { exception ->
launch {
- log.info("End Node Completed, processing completion message")
- val bluePrintProcessorException: BluePrintProcessorException? =
- if (exception != null) BluePrintProcessorException(exception) else null
-
- val workflowOutput = prepareWorkflowOutput(bluePrintProcessorException)
+ if (exception != null) exceptions.add(BluePrintProcessorException(exception))
+ log.info("workflow($workflowId) nodes completed with (${exceptions.size})exceptions")
+ val workflowOutput = prepareWorkflowOutput()
workflowExecuteMessage.output.complete(workflowOutput)
- channel.close(exception)
+ channel.close()
}
}
}
@@ -135,7 +134,11 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
when (message) {
is WorkflowExecuteMessage<In, Out> -> {
launch {
- executeMessageActor(message)
+ try {
+ executeMessageActor(message)
+ } catch (e: Exception) {
+ exceptions.add(e)
+ }
}
}
is WorkflowRestartMessage<In, Out> -> {
@@ -153,7 +156,7 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
}
- private fun nodeActor() = actor<NodeMessage<In, Out>>(coroutineContext, Channel.UNLIMITED) {
+ private suspend fun nodeActor() = actor<NodeMessage<In, Out>>(coroutineContext, Channel.UNLIMITED) {
/** Send message to process from one state to other state */
fun sendNodeMessage(nodeMessage: NodeMessage<In, Out>) = launch {
@@ -164,7 +167,6 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
fun processNextNodes(node: Graph.Node, nodeState: EdgeLabel) {
// Process only Next Success Node
val stateEdges = graph.outgoingEdges(node.id, arrayListOf(nodeState))
- log.debug("Next Edges :$stateEdges")
if (stateEdges.isNotEmpty()) {
stateEdges.forEach { stateEdge ->
// Prepare next node ready message and Send NodeReadyMessage
@@ -213,7 +215,7 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
}
triggerToExecuteOrSkip(newMessage)
} else {
- log.info("node(${node.id}) waiting for not completed edges($notCompletedEdges)")
+ log.info("node(${node.id}) is waiting for incoming edges($notCompletedEdges)")
}
} else {
triggerToExecuteOrSkip(message)
@@ -233,15 +235,19 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
}
// Update Node Completed
node.status = NodeStatus.EXECUTED
- log.info("Execute Node($node) -> Executed State($nodeState)")
+ log.info("Execute node(${node.id}) -> executed state($nodeState)")
+ // Check if the Node status edge is there, If not close processing
+ val edgePresent = graph.outgoingEdges(node.id, nodeState).isNotEmpty()
// If End Node, Send End Message
if (graph.isEndNode(node)) {
// Close the current channel
channel.close()
+ } else if (!edgePresent) {
+ throw BluePrintProcessorException("node(${node.id}) outgoing edge($nodeState) is missing.")
} else {
val skippingEdges = graph.outgoingEdgesNotInLabels(node.id, arrayListOf(nodeState))
- log.debug("Skipping node($node) outgoing Edges($skippingEdges)")
+ log.debug("Skipping node($node)'s outgoing edges($skippingEdges)")
// Process Skip Edges
skippingEdges.forEach { skippingEdge ->
// Prepare next node ready message and Send NodeReadyMessage
@@ -266,7 +272,7 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
log.debug("$$$$$ Skipping workflow($workflowId) node($node) $$$$$")
// Call the Extension Function
val nodeState = skipNode(node, message.nodeInput, message.nodeOutput)
- log.info("Skip Node($node) -> Executed State($nodeState)")
+ log.info("Skip node(${node.id}) -> executed state($nodeState)")
// Mark the Current node as Skipped
node.status = NodeStatus.SKIPPED
// Look for next possible skip nodes
@@ -283,7 +289,7 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
fun cancelNodeWorker(messageWorkflow: WorkflowCancelMessage<In, Out>) = launch {
channel.close()
- throw CancellationException("Workflow($workflowId) actor cancelled as requested ...")
+ throw CancellationException("Workflow($workflowId) actor cancelled as requested.")
}
/** Process each actor message received based on type **/
@@ -294,7 +300,8 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
try {
readyNodeWorker(nodeMessage)
} catch (e: Exception) {
- channel.close(e)
+ exceptions.add(e)
+ channel.close()
}
}
is NodeExecuteMessage<In, Out> -> {
@@ -302,7 +309,9 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
try {
executeNodeWorker(nodeMessage)
} catch (e: Exception) {
- channel.close(e)
+ nodeMessage.node.status = NodeStatus.TERMINATED
+ exceptions.add(e)
+ channel.close()
}
}
}
@@ -311,7 +320,9 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
try {
skipNodeWorker(nodeMessage)
} catch (e: Exception) {
- channel.close(e)
+ nodeMessage.node.status = NodeStatus.TERMINATED
+ exceptions.add(e)
+ channel.close()
}
}
}
@@ -320,20 +331,12 @@ abstract class AbstractBluePrintWorkFlowService<In, Out> : CoroutineScope, BlueP
try {
restartNodeWorker(nodeMessage)
} catch (e: Exception) {
- channel.close(e)
+ exceptions.add(e)
+ channel.close()
}
}
}
}
}
}
-
- override suspend fun executeWorkflow(graph: Graph, bluePrintRuntimeService: BluePrintRuntimeService<*>,
- input: In, output: CompletableDeferred<Out>) {
- log.info("Executing Graph : $graph")
- this.graph = graph
- this.workflowId = bluePrintRuntimeService.id()
- val startMessage = WorkflowExecuteMessage(input, output)
- workflowActor().send(startMessage)
- }
} \ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowServiceTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowServiceTest.kt
index b8d8cea3e..4d97f8bc3 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowServiceTest.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintWorkflowServiceTest.kt
@@ -18,13 +18,13 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service
import io.mockk.every
import io.mockk.mockk
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.*
import org.junit.Test
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
import org.onap.ccsdk.cds.controllerblueprints.core.data.EdgeLabel
import org.onap.ccsdk.cds.controllerblueprints.core.data.Graph
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
import org.onap.ccsdk.cds.controllerblueprints.core.toGraph
import kotlin.test.assertNotNull
@@ -36,10 +36,66 @@ class BluePrintWorkflowServiceTest {
.toGraph()
val simpleWorkflow = TestBluePrintWorkFlowService()
simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D", "E"), null)
- val deferredOutput = CompletableDeferred<String>()
val input = "123456"
- simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
- val response = deferredOutput.await()
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
+ assertNotNull(response, "failed to get response")
+ }
+ }
+
+ @Test
+ fun testMultipleFlows() {
+ runBlocking {
+ coroutineScope {
+ val wfs = listOf("12345", "12346").map {
+ async {
+ val graph = "[START>A/SUCCESS, A>B/SUCCESS, B>C/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
+ .toGraph()
+ val simpleWorkflow = TestBluePrintWorkFlowService()
+ simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D"), null)
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(it), it)
+ assertNotNull(response, "failed to get response")
+ }
+ }
+ wfs.awaitAll()
+ }
+ }
+ }
+
+ @Test
+ fun testMissingEdgeForBFailureState() {
+ runBlocking {
+ val graph = "[START>A/SUCCESS, A>B/SUCCESS, B>C/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
+ .toGraph()
+ val simpleWorkflow = TestBluePrintWorkFlowService()
+ simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "C", "D", "E"), arrayListOf("B"))
+ val input = "123456"
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
+ assertNotNull(response, "failed to get response")
+ }
+ }
+
+ @Test
+ fun testBExceptionFlow() {
+ runBlocking {
+ val graph = "[START>A/SUCCESS, A>B/SUCCESS, B>C/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
+ .toGraph()
+ val simpleWorkflow = TestBluePrintWorkFlowService()
+ simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "C", "D", "E"), null)
+ val input = "123456"
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
+ assertNotNull(response, "failed to get response")
+ }
+ }
+
+ @Test
+ fun testTimeoutExceptionFlow() {
+ runBlocking {
+ val graph = "[START>A/SUCCESS, A>TO/SUCCESS, TO>C/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
+ .toGraph()
+ val simpleWorkflow = TestBluePrintWorkFlowService()
+ simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "TO", "C", "D", "E"), null)
+ val input = "123456"
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
assertNotNull(response, "failed to get response")
}
}
@@ -51,10 +107,8 @@ class BluePrintWorkflowServiceTest {
.toGraph()
val simpleWorkflow = TestBluePrintWorkFlowService()
simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D", "E"), null)
- val deferredOutput = CompletableDeferred<String>()
val input = "123456"
- simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
- val response = deferredOutput.await()
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
assertNotNull(response, "failed to get response")
}
}
@@ -68,10 +122,8 @@ class BluePrintWorkflowServiceTest {
val failurePathWorkflow = TestBluePrintWorkFlowService()
failurePathWorkflow.simulatedState = prepareSimulation(arrayListOf("B", "C", "D", "E"),
arrayListOf("A"))
- val failurePathWorkflowDeferredOutput = CompletableDeferred<String>()
val failurePathWorkflowInput = "123456"
- failurePathWorkflow.executeWorkflow(failurePatGraph, mockBluePrintRuntimeService(), failurePathWorkflowInput, failurePathWorkflowDeferredOutput)
- val failurePathResponse = failurePathWorkflowDeferredOutput.await()
+ val failurePathResponse = failurePathWorkflow.executeWorkflow(failurePatGraph, mockBluePrintRuntimeService(), failurePathWorkflowInput)
assertNotNull(failurePathResponse, "failed to get response")
}
}
@@ -83,10 +135,8 @@ class BluePrintWorkflowServiceTest {
.toGraph()
val simpleWorkflow = TestBluePrintWorkFlowService()
simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D", "E"), null)
- val deferredOutput = CompletableDeferred<String>()
val input = "123456"
- simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
- val response = deferredOutput.await()
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
assertNotNull(response, "failed to get response")
}
}
@@ -98,17 +148,19 @@ class BluePrintWorkflowServiceTest {
.toGraph()
val simpleWorkflow = TestBluePrintWorkFlowService()
simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D"), null)
- val deferredOutput = CompletableDeferred<String>()
val input = "123456"
- simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
- val response = deferredOutput.await()
+ val response = simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input)
assertNotNull(response, "failed to get response")
}
}
private fun mockBluePrintRuntimeService(): BluePrintRuntimeService<*> {
+ return mockBluePrintRuntimeService("123456")
+ }
+
+ private fun mockBluePrintRuntimeService(id: String): BluePrintRuntimeService<*> {
val bluePrintRuntimeService = mockk<BluePrintRuntimeService<*>>()
- every { bluePrintRuntimeService.id() } returns "123456"
+ every { bluePrintRuntimeService.id() } returns id
return bluePrintRuntimeService
}
@@ -126,6 +178,7 @@ class BluePrintWorkflowServiceTest {
class TestBluePrintWorkFlowService
: AbstractBluePrintWorkFlowService<String, String>() {
+ val log = logger(TestBluePrintWorkFlowService::class)
lateinit var simulatedState: MutableMap<String, EdgeLabel>
@@ -133,6 +186,21 @@ class TestBluePrintWorkFlowService
return EdgeLabel.SUCCESS
}
+ override suspend fun executeWorkflow(graph: Graph, bluePrintRuntimeService: BluePrintRuntimeService<*>, input: String): String {
+ log.info("Executing Graph : $graph")
+ this.graph = graph
+ this.workflowId = bluePrintRuntimeService.id()
+ val output = CompletableDeferred<String>()
+ val startMessage = WorkflowExecuteMessage(input, output)
+ val workflowActor = workflowActor()
+ if (!workflowActor.isClosedForSend) {
+ workflowActor().send(startMessage)
+ } else {
+ throw BluePrintProcessorException("workflow actor is closed for send $workflowActor")
+ }
+ return startMessage.output.await()
+ }
+
override suspend fun prepareNodeExecutionMessage(node: Graph.Node)
: NodeExecuteMessage<String, String> {
return NodeExecuteMessage(node, "$node Input", "")
@@ -140,23 +208,26 @@ class TestBluePrintWorkFlowService
override suspend fun executeNode(node: Graph.Node, nodeInput: String,
nodeOutput: String): EdgeLabel {
-// val random = (1..10).random() * 1000
-// println("will reply in $random ms")
+// val random = (1..10).random() * 100
+// log.info("workflow($workflowId) node(${node.id}) will reply in $random ms")
// kotlinx.coroutines.delay(random.toLong())
- val status = simulatedState[node.id] ?: throw BluePrintException("failed to get status for the node($node)")
- return status
+// //Simulation for timeout
+ if (node.id == "TO") {
+ withTimeout(1) {
+ kotlinx.coroutines.delay(2)
+ }
+ }
+ return simulatedState[node.id] ?: throw BluePrintException("failed to get status for the node($node)")
}
override suspend fun prepareNodeSkipMessage(node: Graph.Node): NodeSkipMessage<String, String> {
val nodeOutput = ""
- val nodeSkipMessage = NodeSkipMessage(node, "$node Skip Input", nodeOutput)
- return nodeSkipMessage
+ return NodeSkipMessage(node, "$node Skip Input", nodeOutput)
}
override suspend fun skipNode(node: Graph.Node, nodeInput: String,
nodeOutput: String): EdgeLabel {
- val status = simulatedState[node.id] ?: throw BluePrintException("failed to get status for the node($node)")
- return status
+ return simulatedState[node.id] ?: throw BluePrintException("failed to get status for the node($node)")
}
override suspend fun cancelNode(node: Graph.Node, nodeInput: String,
@@ -169,7 +240,12 @@ class TestBluePrintWorkFlowService
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
- override suspend fun prepareWorkflowOutput(exception: BluePrintProcessorException?): String {
+ override suspend fun prepareWorkflowOutput(): String {
+ if (exceptions.isNotEmpty()) {
+ exceptions.forEach {
+ log.error("workflow($workflowId) exceptions :", it)
+ }
+ }
return "Final Response"
}
} \ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/ControllerBlueprintExceptionHandler.kt
index de8ba93e3..5b92369f8 100644
--- a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt
+++ b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/ControllerBlueprintExceptionHandler.kt
@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode
import org.onap.ccsdk.cds.controllerblueprints.service.common.ErrorMessage
+import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ExceptionHandler
@@ -32,19 +33,26 @@ import org.springframework.web.bind.annotation.ExceptionHandler
* @version 1.0
*/
@RestControllerAdvice("org.onap.ccsdk.cds.controllerblueprints")
-open class ControllerBlueprintExeptionHandler {
+open class ControllerBlueprintExceptionHandler {
+
+ companion object ControllerBlueprintExeptionHandler {
+ val LOG = LoggerFactory.getLogger(ControllerBlueprintExceptionHandler::class.java)
+ }
@ExceptionHandler
- fun ControllerBlueprintException(e: BluePrintException): ResponseEntity<ErrorMessage> {
+ fun ControllerBlueprintExceptionHandler(e: BluePrintException): ResponseEntity<ErrorMessage> {
var errorCode = ErrorCode.valueOf(e.code)
val errorMessage = ErrorMessage(errorCode?.message(e.message!!), errorCode?.value, "ControllerBluePrint_Error_Message")
+ LOG.error("Error: $errorCode ${e.message}")
return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode!!.httpCode))
}
@ExceptionHandler
- fun ControllerBlueprintException(e: Exception): ResponseEntity<ErrorMessage> {
+ fun ControllerBlueprintExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> {
var errorCode = ErrorCode.GENERIC_FAILURE
val errorMessage = ErrorMessage(errorCode?.message(e.message!!), errorCode?.value, "ControllerBluePrint_Error_Message")
+ LOG.error("Error: $errorCode ${e.message}")
return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode!!.httpCode))
}
-} \ No newline at end of file
+}
+