diff options
42 files changed, 843 insertions, 414 deletions
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 index fdb261d52..dd17a30d2 100644 --- 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 @@ -1,3 +1,24 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2019 IBM Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +============LICENSE_END============================================ +*/ + import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; 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 97c65b220..46e1ea7da 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 @@ -34,9 +34,6 @@ limitations under the License. <ng-template matStepLabel>Browse CBA Template file</ng-template> <div class="matStepContent"> <app-search-template [optionSelected]="templateOption" (cbaFile)="fileChange($event)"></app-search-template> - <!-- <div> - <button mat-button matStepperNext class="matStepNextBtn">Upload</button> - </div>--> </div> </mat-step> <mat-step [stepControl]="step3FormGroup"> 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 561f15a5d..9188b43b8 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 @@ -19,8 +19,6 @@ limitations under the License. ============LICENSE_END============================================ */ import { Component, OnInit } from '@angular/core'; -import { Observable } from 'rxjs'; -import { Store } from '@ngrx/store'; import { IBlueprint } from 'src/app/common/core/store/models/blueprint.model'; import { IBlueprintState } from 'src/app/common/core/store/models/blueprintState.model'; import { IMetaData } from 'src/app/common/core/store/models/metadata.model'; @@ -40,8 +38,7 @@ export class SelectTemplateComponent implements OnInit { importModel: IImportModel; templateOption: any; - constructor(private store: Store<IBlueprintState>) { - // this.importModel.file = ''; + constructor() { } ngOnInit() { @@ -51,23 +48,14 @@ export class SelectTemplateComponent implements OnInit { this.templateOption = option; console.log(this.templateOption); } - + fileChange(topologyTemp: ITopologyTemplate) { this.topologyTemplate = topologyTemp; console.log(topologyTemp); } metaDataDetail(data: IMetaData) { - + this.metaData = data; console.log("parent" + this.metaData.author_email); } - upload() { - - } - - // saveBlueprintModel(){ - // this.blueprint.toplogyTemplates=this.topologyTemplate; - // this.blueprint.metadata= this.metaData; - // // this.store.dispatch(new CreateBlueprint(this.blueprint)); - // } } diff --git a/cds-ui/server/src/controllers/blueprint-rest.controller.ts b/cds-ui/server/src/controllers/blueprint-rest.controller.ts index 52e77ee7b..14aba5617 100644 --- a/cds-ui/server/src/controllers/blueprint-rest.controller.ts +++ b/cds-ui/server/src/controllers/blueprint-rest.controller.ts @@ -42,20 +42,20 @@ import { Response, RestBindings, } from '@loopback/rest'; -import {Blueprint} from '../models'; +import { Blueprint } from '../models'; import { inject } from '@loopback/core'; import { BlueprintService } from '../services'; import * as fs from 'fs'; import * as multiparty from 'multiparty'; import * as request_lib from 'request'; -import {controllerApiConfig, processorApiConfig, appConfig} from '../config/app-config'; -import {bluePrintManagementServiceGrpcClient} from '../clients/blueprint-management-service-grpc-client'; +import { controllerApiConfig, processorApiConfig, appConfig } from '../config/app-config'; +import { bluePrintManagementServiceGrpcClient } from '../clients/blueprint-management-service-grpc-client'; export class BlueprintRestController { constructor( - @inject('services.BlueprintService') + @inject('services.BlueprintService') public bpservice: BlueprintService, - ) {} + ) { } @get('/blueprints', { responses: { @@ -69,6 +69,17 @@ export class BlueprintRestController { return await this.bpservice.getAllblueprints(); } + @get('/searchByTags/{tags}', { + responses: { + '200': { + content: { 'application/json': {} }, + }, + }, + }) + async getByTags(@param.path.string('tags') tags: string) { + return await this.bpservice.getByTags(tags); + } + @post('/create-blueprint') async upload( @requestBody({ @@ -78,21 +89,21 @@ export class BlueprintRestController { 'multipart/form-data': { // Skip body parsing 'x-parser': 'stream', - schema: {type: 'object'}, + schema: { type: 'object' }, }, }, }) request: Request, @inject(RestBindings.Http.RESPONSE) response: Response, ): Promise<Response> { - return new Promise((resolve, reject) => { - this.getFileFromMultiPartForm(request).then(file=>{ - this.uploadFileToBlueprintController(file, "/blueprint-model/", response).then(resp=>{ + return new Promise((resolve, reject) => { + this.getFileFromMultiPartForm(request).then(file => { + this.uploadFileToBlueprintController(file, "/blueprint-model/", response).then(resp => { resolve(resp); - }, err=>{ - reject(err); - }); - }, err=>{ + }, err => { + reject(err); + }); + }, err => { reject(err); }); }); @@ -107,21 +118,21 @@ export class BlueprintRestController { 'multipart/form-data': { // Skip body parsing 'x-parser': 'stream', - schema: {type: 'object'}, + schema: { type: 'object' }, }, }, }) request: Request, @inject(RestBindings.Http.RESPONSE) response: Response, ): Promise<Response> { - return new Promise((resolve, reject) => { - this.getFileFromMultiPartForm(request).then(file=>{ - this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response).then(resp=>{ + return new Promise((resolve, reject) => { + this.getFileFromMultiPartForm(request).then(file => { + this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response).then(resp => { resolve(resp); - }, err=>{ - reject(err); - }); - }, err=>{ + }, err => { + reject(err); + }); + }, err => { reject(err); }); }); @@ -136,21 +147,21 @@ export class BlueprintRestController { 'multipart/form-data': { // Skip body parsing 'x-parser': 'stream', - schema: {type: 'object'}, + schema: { type: 'object' }, }, }, }) request: Request, @inject(RestBindings.Http.RESPONSE) response: Response, ): Promise<Response> { - return new Promise((resolve, reject) => { - this.getFileFromMultiPartForm(request).then(file=>{ - this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response).then(resp=>{ - resolve(resp); - }, err=>{ - reject(err); - }); - }, err=>{ + return new Promise((resolve, reject) => { + this.getFileFromMultiPartForm(request).then(file => { + this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response).then(resp => { + resolve(resp); + }, err => { + reject(err); + }); + }, err => { reject(err); }); }); @@ -159,21 +170,21 @@ export class BlueprintRestController { @get('/download-blueprint/{name}/{version}') async download( @param.path.string('name') name: string, - @param.path.string('version') version:string, + @param.path.string('version') version: string, @inject(RestBindings.Http.RESPONSE) response: Response, ): Promise<Response> { - return this.downloadFileFromBlueprintController("/blueprint-model/download/by-name/"+name+"/version/"+version, response); + return this.downloadFileFromBlueprintController("/blueprint-model/download/by-name/" + name + "/version/" + version, response); } - async getFileFromMultiPartForm(request: Request): Promise<multiparty.File>{ + async getFileFromMultiPartForm(request: Request): Promise<multiparty.File> { return new Promise((resolve, reject) => { let form = new multiparty.Form(); form.parse(request, (err: any, fields: any, files: { [x: string]: any[]; }) => { if (err) reject(err); let file = files['file'][0]; // get the file from the returned files object - if(!file){ + if (!file) { reject('File was not found in form data.'); - }else{ + } else { resolve(file); } }); @@ -189,34 +200,34 @@ export class BlueprintRestController { 'multipart/form-data': { // Skip body parsing 'x-parser': 'stream', - schema: {type: 'object'}, + schema: { type: 'object' }, }, }, }) request: Request, @inject(RestBindings.Http.RESPONSE) response: Response, ): Promise<Response> { - return new Promise((resolve, reject) => { - this.getFileFromMultiPartForm(request).then(file=>{ - if(appConfig.action.deployBlueprint.grpcEnabled) - return this.uploadFileToBlueprintProcessorGrpc(file, response); - else + return new Promise((resolve, reject) => { + this.getFileFromMultiPartForm(request).then(file => { + if (appConfig.action.deployBlueprint.grpcEnabled) + return this.uploadFileToBlueprintProcessorGrpc(file, response); + else return this.uploadFileToBlueprintProcessor(file, "/execution-service/upload/", response); - }, err=>{ + }, err => { reject(err); }); }); } - async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response>{ + async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response> { return this.uploadFileToBlueprintService(file, controllerApiConfig.http.url + uri, controllerApiConfig.http.authToken, response); } - async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<Response>{ + async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<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>{ + async uploadFileToBlueprintService(file: multiparty.File, url: string, authToken: string, response: Response): Promise<Response> { let options = { url: url, headers: { @@ -238,7 +249,7 @@ export class BlueprintRestController { fs.unlink(file.path, (err: any) => { if (err) { console.error(err); - } + } }); } @@ -280,10 +291,10 @@ export class BlueprintRestController { async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, response: Response): Promise<Response> { return new Promise<Response>((resolve, reject) => { - bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path).then(output=>{ + bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path).then(output => { response.send(output.status.message); resolve(response); - }, err=>{ + }, err => { response.status(500).send(err); resolve(response); }); diff --git a/cds-ui/server/src/datasources/blueprint.datasource-template.ts b/cds-ui/server/src/datasources/blueprint.datasource-template.ts index 35edf33e3..1188d9bcf 100644 --- a/cds-ui/server/src/datasources/blueprint.datasource-template.ts +++ b/cds-ui/server/src/datasources/blueprint.datasource-template.ts @@ -21,5 +21,22 @@ export default { "getAllblueprints": [] } - }] + }, + { + "template": { + "method": "GET", + "url": controllerApiConfig.http.url + "/blueprint-model/search/{tags}", + "headers": { + "accepts": "application/json", + "content-type": "application/json", + "authorization": controllerApiConfig.http.authToken + }, + "responsePath": "$.*" + }, + "functions": { + "getByTags": ["tags"] + + } + }, +] };
\ No newline at end of file diff --git a/cds-ui/server/src/services/blueprint.service.ts b/cds-ui/server/src/services/blueprint.service.ts index 970b2afda..0545faca8 100644 --- a/cds-ui/server/src/services/blueprint.service.ts +++ b/cds-ui/server/src/services/blueprint.service.ts @@ -4,6 +4,7 @@ import {BlueprintDataSource} from '../datasources'; export interface BlueprintService { getAllblueprints(): Promise<any>; + getByTags(tags: string): Promise<JSON>; } export class BlueprintServiceProvider implements Provider<BlueprintService> { diff --git a/components/scripts/python/ccsdk_netconf/common.py b/components/scripts/python/ccsdk_netconf/common.py index ad2057f32..896fb9128 100644 --- a/components/scripts/python/ccsdk_netconf/common.py +++ b/components/scripts/python/ccsdk_netconf/common.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 Bell Canada. -# Modifications Copyright © 2018 - 2019 IBM, Bell Canada. +# Modifications Copyright (c) 2018 - 2019 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. diff --git a/docs/datadictionary/index.rst b/docs/datadictionary/index.rst index 0d87158d9..3ac8587ee 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 -resourceDefintionCode + resourcedefinitioncodesnip Resource source: @@ -61,10 +61,10 @@ Also please click below for resource source available details .. _Resource: https://wiki.onap.org/display/DW/Modeling+Concepts#ModelingConcepts-NodeResourceSource -.. |image0| image:: media/mandatory.jpg +.. |image0| image:: media/mandatory.JPG :width: 7.88889in :height: 4.43750in -.. |image1| image:: media/optional.jpg +.. |image1| image:: media/optional.JPG :width: 7.88889in :height: 4.43750in
\ No newline at end of file diff --git a/docs/datadictionary/resourceDefinitionCode.rst b/docs/datadictionary/resourcedefinitioncodesnip.rst index a91767678..a91767678 100644 --- a/docs/datadictionary/resourceDefinitionCode.rst +++ b/docs/datadictionary/resourcedefinitioncodesnip.rst diff --git a/docs/datadictionary/resourcesource.rst b/docs/datadictionary/resourcesource.rst index 1a69fd63f..852a34f07 100644 --- a/docs/datadictionary/resourcesource.rst +++ b/docs/datadictionary/resourcesource.rst @@ -11,10 +11,13 @@ Expects the value to be provided as input to the request. source-input: +.. code: json +print(" "description": "This is Input Resource Source Node Type", "version": "1.0.0", "properties": {}, "derived_from": "tosca.nodes.ResourceSource" +") Default: @@ -39,21 +42,21 @@ CDS is currently deployed along the side of SDNC, hence the primary database con |image0| -.. |image0| image:: media/sqltable.jpg +.. |image0| image:: media/sqltable.JPG :width: 7.88889in :height: 4.43750in .. toctree:: :maxdepth: 1 -sourceprimarydbcode + sourceprimarydbcode Connection to a specific database can be expressed through the endpoint-selector property, which refers to a macro defining the information about the database the connect to. Understand TOSCA Macro in the context of CDS. .. toctree:: :maxdepth: 1 -dbsystemcode + dbsystemcode REST: @@ -65,7 +68,7 @@ CDS is currently deployed along the side of SDNC, hence the default rest connect |image1| -.. |image1| image:: media/resttable.jpg +.. |image1| image:: media/resttable.JPG :width: 7.88889in :height: 4.43750in @@ -96,7 +99,7 @@ Expects a script to be provided. |image2| -.. |image2| image:: media/capabilitytable.jpg +.. |image2| image:: media/capabilitytable.JPG :width: 7.88889in :height: 4.43750in @@ -104,7 +107,7 @@ Expects a script to be provided. .. toctree:: :maxdepth: 1 - sourcecapabilitycode + sourcecapabilitycode Complex Type: ============= @@ -122,14 +125,14 @@ As part of this request, the expected response will be as below. .. toctree:: :maxdepth: 1 - complexResponse + complexResponse What is of interest is the address and id fields. For the process to return these two values, we need to create a custom data-type, as bellow .. toctree:: :maxdepth: 1 - dt-netbox-ip + dt-netbox-ip The type of the data dictionary will be dt-netbox-ip. @@ -138,4 +141,4 @@ To tell the resolution framework what is of interest in the response, the output .. toctree:: :maxdepth: 1 -create_netbox_ip_address
\ No newline at end of file + create_netbox_ip_address
\ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 794d87fb5..45b124f29 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,8 +23,32 @@ its parameters and create a new service without writing a single line of code. This makes SERVICE PROVIDER(S) more responsive to its customers and able to deliver products that more closely match the needs of its customers. +Architecture +------------ +The Controller Design Studio is composed of two major components: + * The GUI (or frontend) + * The Run Time (or backend) + +The GUI handles direct user input and allows for displaying both design time +and run time activities. For design time, it allows for the creation of +controller blueprint, from selecting the DGs to be included, to incorporating +the artifact templates, to adding necessary components. For run time, it +allows the user to direct the system to resolve the unresolved elements of the +controller blueprint and download the resulting configuration into a VNF. +At a more basic level, it allows for creation of data dictionaries, +capabilities catalogs, and controller blueprint, the basic elements that are +used to generate a configuration. The essential function of the Controller +Design Studio is to create and populate a controller blueprint, create a +configuration file from this Controller blueprint, and download this +configuration file (configlet) to a VNF/PNF. + +|image1| + + + Modeling Concept ----------------- +================ + In Dublin release, the CDS community has contributed a framework to automate the resolution of resources for instantiation and any config provisioning operation, such as day0, day1 or day2 configuration. @@ -44,68 +68,45 @@ Tosca Model Reference: |image0| -Design tools ------------- -.. toctree:: - :maxdepth: 1 - :glob: - - CBA/index - datadictionary/index +Modeling Concept Links: +----------------------- -MicroServices -------------- .. toctree:: :maxdepth: 1 microservices/controllerBlueprintStudioProcessorMS microservices/bluePrintsProcessorMS + microservices/expression + microservices/dynamicapi + microservices/flexibleplugin -Architecture ------------- -The Controller Design Studio is composed of two major components: - * The GUI (or frontend) - * The Run Time (or backend) - -The GUI handles direct user input and allows for displaying both design time -and run time activities. For design time, it allows for the creation of -controller blueprint, from selecting the DGs to be included, to incorporating -the artifact templates, to adding necessary components. For run time, it -allows the user to direct the system to resolve the unresolved elements of the -controller blueprint and download the resulting configuration into a VNF. -At a more basic level, it allows for creation of data dictionaries, -capabilities catalogs, and controller blueprint, the basic elements that are -used to generate a configuration. The essential function of the Controller -Design Studio is to create and populate a controller blueprint, create a -configuration file from this Controller blueprint, and download this -configuration file (configlet) to a VNF/PNF. - -|image1| - -User Guide ----------- +Design tools +============ .. toctree:: :maxdepth: 1 + :glob: - userguide + CBA/index + datadictionary/index -Dynamic API ------------ -.. toctree:: - :maxdepth: 1 - microservices/dynamicapi -Controller Design Studio Presentation -------------------------------------- +Scripts +======= -Details about CDS Architecture and Design detail, Please click the link. -:download:`CDS_Architecture_Design.pptx` +Library +------- + +*NetconfClient +-------------- +In order to facilitate NETCONF interaction within scripts, a python NetconfClient binded to our Kotlin implementation is made available. This NetconfClient can be used when using the component-netconf-executor. + +The client can be find here: https://github.com/onap/ccsdk-cds/blob/master/components/scripts/python/ccsdk_netconf/netconfclient.py -ResolutionHelper ----------------- +*ResolutionHelper +----------------- When executing a component executor script, designer might want to perform resource resolution along with template meshing directly from the script itself. @@ -120,4 +121,17 @@ The helper can be find here: https://github.com/onap/ccsdk-apps/blob/master/comp :height: 4.43750in :width: 7.88889in +User Guide +---------- + +.. toctree:: + :maxdepth: 1 + + userguide + + +Controller Design Studio Presentation +------------------------------------- +Details about CDS Architecture and Design detail, Please click the link. +:download:`CDS_Architecture_Design.pptx` diff --git a/docs/microservices/expression.rst b/docs/microservices/expression.rst new file mode 100644 index 000000000..38a7d624c --- /dev/null +++ b/docs/microservices/expression.rst @@ -0,0 +1,45 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 +.. International License. http://creativecommons.org/licenses/by/4.0 +.. Copyright (C) 2019 IBM. + +Expression +========== + +TOSCA provides for a set of functions to reference elements within the template or to retrieve runtime values. + +Below is a list of supported expressions + +get_input +--------- + +The get_input function is used to retrieve the values of properties declared within the inputs section of a TOSCA Service Template. + +http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454178 + +get_property +------------ + +The get_property function is used to retrieve property values between modelable entities defined in the same service template. + +http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454178 + +get_attribute +------------- + +The get_attribute function is used to retrieve the values of named attributes declared by the referenced node or relationship template name. + +http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454179 + +get_operation_output +-------------------- + +The get_operation_output function is used to retrieve the values of variables exposed / exported from an interface operation. + +http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454180 + +get_artifact +------------ + +The get_artifact function is used to retrieve artifact location between modelable entities defined in the same service template. + +http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454182 diff --git a/docs/microservices/workflow.rst b/docs/microservices/workflow.rst new file mode 100644 index 000000000..b74a49d2b --- /dev/null +++ b/docs/microservices/workflow.rst @@ -0,0 +1,73 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 +.. International License. http://creativecommons.org/licenses/by/4.0 +.. Copyright (C) 2019 IBM. + +Workflow +======== + +A workflow defines an overall action to be taken on the service, hence is an entry-point for the run-time execution of the CBA package. + +A workflow also defines inputs and outputs that will defined the payload contract of the request and response (see Dynamic API) + +A workflow can be composed of one or multiple sub-actions to execute. + +A CBA package can have as many workflows as needed. + +Single action +------------- + +The workflow is directly backed by a node_template of type tosca.nodes.Component + +Multiple sub-actions +-------------------- +The workflow is backed by Directed Graph engine, node_template of type dg-generic, and are imperative workflows. + +A DG used as workflow for CDS is composed of multiple execute nodes; each individual execute node refers to a plugin, that is a node_template of type tosca.nodes.Component. + +Below the properties of a workflow: + + + +Workflow Example +---------------- + +.. code:: json + +print(" +{ + "workflow": { + "resource-assignment": { <- workflow-name + "inputs": { + "vnf-id": { <- static inputs + "required": true, + "type": "string" + }, + "resource-assignment-properties": { <- dynamic inputs + "required": true, + "type": "dt-resource-assignment-properties" + } + }, + "steps": { + "call-resource-assignment": { <- step-name + "description": "Resource Assignment Workflow", + "target": "resource-assignment-process" <- node_template targeted by the step + } + }, + "outputs": { + "template-properties": { <- output + "type": "json", <- complex type + "value": { + "get_attribute": [ <- uses expression to retrieve attribute from context + "resource-assignment", + "assignment-params" + ] + } + } + } + } + } +} +") + + +TOSCA definition: http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454203
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt index 3e1f0715b..9faf879f0 100755 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt @@ -26,6 +26,8 @@ import org.onap.ccsdk.cds.controllerblueprints.core.common.ApplicationConstants import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintPathConfiguration import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintValidatorService +import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils import org.onap.ccsdk.cds.controllerblueprints.db.resources.BlueprintCatalogServiceImpl import org.slf4j.LoggerFactory import org.springframework.dao.DataIntegrityViolationException @@ -46,12 +48,17 @@ class BlueprintProcessorCatalogServiceImpl(bluePrintRuntimeValidatorService: Blu private val log = LoggerFactory.getLogger(BlueprintProcessorCatalogServiceImpl::class.toString()) override suspend fun delete(name: String, version: String) { + // Clean blueprint script cache + val cacheKey = BluePrintFileUtils + .compileCacheKey(normalizedPathName(bluePrintPathConfiguration.blueprintDeployPath, name, version)) + BluePrintCompileCache.cleanClassLoader(cacheKey) + log.info("removed cba file name($name), version($version) from cache") // Cleaning Deployed Blueprint deleteNBDir(bluePrintPathConfiguration.blueprintDeployPath, name, version) log.info("removed cba file name($name), version($version) from deploy location") // Cleaning Data Base blueprintModelRepository - .deleteByArtifactNameAndArtifactVersion(name, version) + .deleteByArtifactNameAndArtifactVersion(name, version) log.info("removed cba file name($name), version($version) from database") } @@ -60,7 +67,7 @@ class BlueprintProcessorCatalogServiceImpl(bluePrintRuntimeValidatorService: Blu val deployFile = normalizedFile(bluePrintPathConfiguration.blueprintDeployPath, name, version) val cbaFile = normalizedFile(bluePrintPathConfiguration.blueprintArchivePath, - UUID.randomUUID().toString(), "cba.zip") + UUID.randomUUID().toString(), "cba.zip") if (extract && deployFile.exists()) { log.info("cba file name($name), version($version) already present(${deployFile.absolutePath})") @@ -110,7 +117,7 @@ class BlueprintProcessorCatalogServiceImpl(bluePrintRuntimeValidatorService: Blu log.info("Overwriting blueprint model :$artifactName::$artifactVersion") blueprintModelRepository.deleteByArtifactNameAndArtifactVersion(artifactName, artifactVersion) val deployFile = - normalizedPathName(bluePrintPathConfiguration.blueprintDeployPath, artifactName, artifactVersion) + normalizedPathName(bluePrintPathConfiguration.blueprintDeployPath, artifactName, artifactVersion) deleteNBDir(deployFile).let { if (it) log.info("Deleted deployed blueprint model :$artifactName::$artifactVersion") else log.info("Fail to delete deployed blueprint model :$artifactName::$artifactVersion") 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 index a04a79921..17e157d15 100644 --- 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 @@ -1,5 +1,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.ObjectMapper import org.apache.kafka.clients.CommonClientConfigs import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.common.serialization.StringDeserializer @@ -7,10 +9,10 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInpu 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.ErrorHandlingDeserializer2 import org.springframework.kafka.support.serializer.JsonDeserializer @Configuration @@ -26,11 +28,20 @@ open class MessagingConfig { 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") + configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = "latest" + configProperties[ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java + configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = ErrorHandlingDeserializer2::class.java + configProperties[ErrorHandlingDeserializer2.VALUE_DESERIALIZER_CLASS] = JsonDeserializer::class.java.name - return DefaultKafkaConsumerFactory(configProperties, StringDeserializer(), JsonDeserializer(ExecutionServiceInput::class.java)) + val deserializer = JsonDeserializer<ExecutionServiceInput>() + deserializer.setRemoveTypeHeaders(true) + deserializer.addTrustedPackages("*") + + val jsonDeserializer = JsonDeserializer(ExecutionServiceInput::class.java, + ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)) + + return DefaultKafkaConsumerFactory(configProperties, StringDeserializer(), + ErrorHandlingDeserializer2<ExecutionServiceInput>(jsonDeserializer)) } /** 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 index 1d219a83e..54cc0c129 100644 --- 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 @@ -18,6 +18,7 @@ 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.apache.kafka.clients.consumer.ConsumerRecord import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BluePrintMessageLibPropertyService import org.slf4j.LoggerFactory @@ -39,17 +40,15 @@ open class MessagingController(private val propertyService: BluePrintMessageLibP } @KafkaListener(topics = ["\${blueprintsprocessor.messageclient.self-service-api.consumerTopic}"]) - open fun receive(input: ExecutionServiceInput) { - - log.info("Successfully received a message: {}", ToStringBuilder.reflectionToString(input)) + open fun receive(record: ConsumerRecord<String, ExecutionServiceInput>) { runBlocking { - log.info("Successfully received a message: {}", ToStringBuilder.reflectionToString(input)) + log.info("Successfully received a message: {}", ToStringBuilder.reflectionToString(record.value())) // Process the message. async { - processMessage(input) - } + processMessage(record.value()) + }.await() } } 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 index f7459f522..602033ad9 100644 --- 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 @@ -90,7 +90,7 @@ class MessagingControllerTest { @Autowired lateinit var webTestClient: WebTestClient - var receivedEvent: String? = null + var event: ExecutionServiceInput? = null @Before fun setup() { @@ -142,11 +142,13 @@ class MessagingControllerTest { log.info("test-sender sent message='{}'", ToStringBuilder.reflectionToString(input)) Thread.sleep(1000) + + assertNotNull(event) } @KafkaListener(topicPartitions = [TopicPartition(topic = "\${blueprintsprocessor.messageclient.self-service-api.topic}", partitionOffsets = [PartitionOffset(partition = "0", initialOffset = "0")])]) - fun receivedEventFromBluePrintProducer(event: ExecutionServiceInput) { - assertNotNull(event) + fun receivedEventFromBluePrintProducer(receivedEvent: ExecutionServiceInput) { + event = receivedEvent } private fun uploadBluePrint() { @@ -172,7 +174,7 @@ class MessagingControllerTest { } private fun loadCbaArchive():File { - return Paths.get("./src/test/resources/cba-for-kafka-integration.zip").toFile() + return Paths.get("./src/test/resources/cba-for-kafka-integration_enriched.zip").toFile() } @Configuration 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 differdeleted file mode 100644 index 23070380c..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration.zip +++ /dev/null diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration_enriched.zip b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration_enriched.zip Binary files differnew file mode 100755 index 000000000..9581191d7 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/cba-for-kafka-integration_enriched.zip diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt index 49a2c62b1..a16c52069 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt @@ -76,7 +76,8 @@ class ComponentFunctionScriptingService(private val applicationContext: Applicat } BluePrintConstants.SCRIPT_KOTLIN -> { val bluePrintScriptsService: BluePrintScriptsService = BluePrintScriptsServiceImpl() - scriptComponent = bluePrintScriptsService.scriptInstance<T>(bluePrintContext, scriptClassReference, false) + scriptComponent = bluePrintScriptsService.scriptInstance<T>(bluePrintContext.rootPath, + bluePrintContext.name(), bluePrintContext.version(), scriptClassReference, false) } BluePrintConstants.SCRIPT_JYTHON -> { scriptComponent = blueprintJythonService.jythonComponentInstance(bluePrintContext, scriptClassReference) as T diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index 4d05550ef..b03c7b4d7 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -626,7 +626,24 @@ <repository> <id>spring-libs-milestone</id> <name>Spring Milestone Maven Repository</name> + <url>http://oss.jfrog.org/artifactory/oss-release-local/</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + <repository> + <id>spring-libs-milestone-snapshot</id> + <name>Spring Milestone Maven Repository - snapshots</name> <url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> </repository> </repositories> 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 a5b18a1f6..34a2d9cd3 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 @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.* import org.apache.commons.lang3.ObjectUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.slf4j.LoggerFactory import org.slf4j.helpers.MessageFormatter import kotlin.reflect.KClass @@ -30,6 +31,11 @@ import kotlin.reflect.KClass * @author Brinda Santh */ +fun <T : Any> logger(clazz: T) = LoggerFactory.getLogger(clazz.javaClass)!! + +fun <T : KClass<*>> logger(clazz: T) = LoggerFactory.getLogger(clazz.java)!! + + fun <T : Any> T.bpClone(): T { return ObjectUtils.clone(this) } diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintModel.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintModel.kt index 68e5b0aec..a2cba95d9 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintModel.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BluePrintModel.kt @@ -630,6 +630,8 @@ class ToscaMetaData { lateinit var csarVersion: String lateinit var createdBy: String lateinit var entityDefinitions: String + var templateName: String? = null + var templateVersion: String? = null var templateTags: String? = null } diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintDefinitions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintDefinitions.kt new file mode 100644 index 000000000..8267e5dcc --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintDefinitions.kt @@ -0,0 +1,61 @@ +/* + * 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.interfaces + +import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate + +interface BluePrintDefinitions { + + /** Define the service Template Model */ + fun serviceTemplate(): ServiceTemplate + + /** Load Custom Definitions that may used during runtime **/ + fun loadOtherDefinitions() + + /** Utility Method to add the definition */ + fun addOtherDefinition(key: String, definition: Any) + + /** Utility method to get the definition */ + fun <T : Any> otherDefinition(key: String): T + + fun otherDefinitions(): MutableMap<String, Any> +} + +abstract class AbstractBluePrintDefinitions : BluePrintDefinitions { + + private val otherDefinitionMap: MutableMap<String, Any> = hashMapOf() + + constructor() { + loadOtherDefinitions() + } + + override fun loadOtherDefinitions() { + } + + override fun <T : Any> otherDefinition(key: String): T { + return otherDefinitionMap[key] as T + } + + override fun addOtherDefinition(key: String, definition: Any) { + otherDefinitionMap[key] = definition + } + + override fun otherDefinitions(): MutableMap<String, Any> { + return otherDefinitionMap + } + +}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintScriptsService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintScriptsService.kt index 8bb0cd0ce..7912e781a 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintScriptsService.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintScriptsService.kt @@ -17,12 +17,18 @@ package org.onap.ccsdk.cds.controllerblueprints.core.interfaces -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext +import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintSourceCode interface BluePrintScriptsService { - suspend fun <T> scriptInstance(blueprintContext: BluePrintContext, scriptClassName: String, - reCompile: Boolean): T + suspend fun <T> scriptInstance(bluePrintSourceCode: BluePrintSourceCode, scriptClassName: String): T + + suspend fun <T> scriptInstance(blueprintBasePath: String, artifactName: String, artifactVersion: String, + scriptClassName: String, reCompile: Boolean): T + + suspend fun <T> scriptInstance(blueprintBasePath: String, scriptClassName: String, reCompile: Boolean): T + + suspend fun <T> scriptInstance(cacheKey: String, scriptClassName: String): T suspend fun <T> scriptInstance(scriptClassName: String): T }
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompiledScript.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompiledScript.kt index 03258c252..2f131f6f6 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompiledScript.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompiledScript.kt @@ -16,30 +16,25 @@ package org.onap.ccsdk.cds.controllerblueprints.core.scripts -import java.io.File import java.io.Serializable -import java.net.URL -import java.net.URLClassLoader import kotlin.reflect.KClass import kotlin.script.experimental.api.* -open class BluePrintCompiledScript<out JarFile : File>( - private val scriptCompilationConfiguration: ScriptCompilationConfiguration, - private val compiledJar: File) : - CompiledScript<JarFile>, Serializable { +open class BluePrintCompiledScript<out BCS : String>( + val cacheKey: String, + val scriptCompilationConfiguration: ScriptCompilationConfiguration) : + CompiledScript<BCS>, Serializable { lateinit var scriptClassFQName: String override val compilationConfiguration: ScriptCompilationConfiguration get() = scriptCompilationConfiguration - override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<KClass<*>> = try { + override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?) + : ResultWithDiagnostics<KClass<*>> = try { - val baseClassLoader = Thread.currentThread().contextClassLoader - - val urls = arrayListOf<URL>() - urls.add(compiledJar.toURI().toURL()) - val classLoaderWithDependencies = URLClassLoader(urls.toTypedArray(), baseClassLoader) + /** Get the class loader from the cache */ + val classLoaderWithDependencies = BluePrintCompileCache.classLoader(cacheKey) val clazz = classLoaderWithDependencies.loadClass(scriptClassFQName).kotlin clazz.asSuccess() diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerCache.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerCache.kt new file mode 100644 index 000000000..db139eb59 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerCache.kt @@ -0,0 +1,69 @@ +/* + * 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.scripts + +import com.google.common.cache.CacheBuilder +import com.google.common.cache.CacheLoader +import com.google.common.cache.LoadingCache +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile +import java.net.URL +import java.net.URLClassLoader + + +object BluePrintCompileCache { + val log = logger(BluePrintCompileCache::class) + + private val classLoaderCache: LoadingCache<String, URLClassLoader> = CacheBuilder.newBuilder() + .maximumSize(10) + .build(BluePrintClassLoader) + + fun classLoader(key: String): URLClassLoader { + return classLoaderCache.get(key) + } + + fun cleanClassLoader(key: String) { + classLoaderCache.invalidate(key) + log.info("Cleaned script cache($key)") + } + + fun hasClassLoader(key: String): Boolean { + return classLoaderCache.asMap().containsKey(key) + } +} + +object BluePrintClassLoader : CacheLoader<String, URLClassLoader>() { + + val log = logger(BluePrintClassLoader::class) + + override fun load(key: String): URLClassLoader { + log.info("loading cache key($key)") + val keyPath = normalizedFile(key) + if (!keyPath.exists()) { + throw BluePrintException("failed to load cache($key), missing files.") + } + val urls = arrayListOf<URL>() + keyPath.walkTopDown() + .filter { it.name.endsWith("cba-kts.jar") } + .forEach { + log.debug("Adding (${it.absolutePath}) to cache key($key)") + urls.add(it.toURI().toURL()) + } + return URLClassLoader(urls.toTypedArray(), this.javaClass.classLoader) + } +}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerProxy.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerProxy.kt index df3302518..e231f6d1c 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerProxy.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompilerProxy.kt @@ -30,8 +30,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer import org.jetbrains.kotlin.config.* +import org.onap.ccsdk.cds.controllerblueprints.core.checkFileExists import org.slf4j.LoggerFactory -import java.io.File import kotlin.script.experimental.api.* import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.jvm.util.classpathFromClasspathProperty @@ -60,7 +60,11 @@ open class BluePrintsCompilerProxy(private val hostConfiguration: ScriptingHostC val compiledJarFile = blueprintSourceCode.targetJarFile - if (!compiledJarFile.exists() || blueprintSourceCode.regenerate) { + /** Check cache is present for the blueprint scripts */ + val hasCompiledCache = BluePrintCompileCache.hasClassLoader(blueprintSourceCode.cacheKey) + + if (!compiledJarFile.exists() || blueprintSourceCode.regenerate || !hasCompiledCache) { + log.info("compiling for cache key(${blueprintSourceCode.cacheKey})") var environment: KotlinCoreEnvironment? = null @@ -68,6 +72,11 @@ open class BluePrintsCompilerProxy(private val hostConfiguration: ScriptingHostC try { + // Clean the cache, if present + if (hasCompiledCache) { + BluePrintCompileCache.cleanClassLoader(blueprintSourceCode.cacheKey) + } + val compilerConfiguration = CompilerConfiguration().apply { put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) @@ -83,6 +92,8 @@ open class BluePrintsCompilerProxy(private val hostConfiguration: ScriptingHostC // Add all Kotlin Sources addKotlinSourceRoots(blueprintSourceCode.blueprintKotlinSources) + // for Kotlin 1.3.30 greater + //add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar()) languageVersionSettings = LanguageVersionSettingsImpl( LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlags.skipMetadataVersionCheck to true) @@ -108,9 +119,11 @@ open class BluePrintsCompilerProxy(private val hostConfiguration: ScriptingHostC } } - val res = BluePrintCompiledScript<File>(scriptCompilationConfiguration, compiledJarFile) + checkFileExists(compiledJarFile) { "couldn't generate compiled jar(${compiledJarFile.absolutePath})" } + + val compiledScript = BluePrintCompiledScript<String>(blueprintSourceCode.cacheKey, scriptCompilationConfiguration) - return ResultWithDiagnostics.Success(res, messageCollector.diagnostics) + return compiledScript.asSuccess() } catch (ex: Throwable) { return failure(ex.asDiagnostics()) diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptingHost.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptingHost.kt index 4fcc33d46..05a147171 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptingHost.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptingHost.kt @@ -19,6 +19,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core.scripts import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.slf4j.LoggerFactory import java.util.* +import kotlin.reflect.full.createInstance import kotlin.script.experimental.api.* import kotlin.script.experimental.host.BasicScriptingHost import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration @@ -30,19 +31,16 @@ val blueprintScriptCompiler = JvmScriptCompiler(defaultJvmScriptingHostConfigura open class BlueprintScriptingHost(evaluator: ScriptEvaluator) : BasicScriptingHost(blueprintScriptCompiler, evaluator) { - override fun eval( - script: SourceCode, - scriptCompilationConfiguration: ScriptCompilationConfiguration, - configuration: ScriptEvaluationConfiguration? - ): ResultWithDiagnostics<EvaluationResult> = + override fun eval(script: SourceCode, scriptCompilationConfiguration: ScriptCompilationConfiguration, + configuration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<EvaluationResult> = runInCoroutineContext { - compiler(script, scriptCompilationConfiguration) + blueprintScriptCompiler(script, scriptCompilationConfiguration) .onSuccess { evaluator(it, configuration) }.onFailure { failedResult -> - val messages = failedResult.reports?.joinToString("\n") + val messages = failedResult.reports.joinToString("\n") throw BluePrintProcessorException(messages) } } @@ -52,21 +50,21 @@ open class BluePrintScriptEvaluator(private val scriptClassName: String) : Scrip private val log = LoggerFactory.getLogger(BluePrintScriptEvaluator::class.java)!! - override suspend operator fun invoke( - compiledScript: CompiledScript<*>, - scriptEvaluationConfiguration: ScriptEvaluationConfiguration? + override suspend operator fun invoke(compiledScript: CompiledScript<*>, + scriptEvaluationConfiguration: ScriptEvaluationConfiguration? ): ResultWithDiagnostics<EvaluationResult> = try { log.debug("Getting script class name($scriptClassName) from the compiled sources ") + val bluePrintCompiledScript = compiledScript as BluePrintCompiledScript bluePrintCompiledScript.scriptClassFQName = scriptClassName - val res = compiledScript.getClass(scriptEvaluationConfiguration) - when (res) { - is ResultWithDiagnostics.Failure -> res + val classResult = compiledScript.getClass(scriptEvaluationConfiguration) + when (classResult) { + is ResultWithDiagnostics.Failure -> classResult is ResultWithDiagnostics.Success -> { - val scriptClass = res.value + val scriptClass = classResult.value val args = ArrayList<Any?>() scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.providedProperties)?.forEach { args.add(it.value) @@ -78,10 +76,14 @@ open class BluePrintScriptEvaluator(private val scriptClassName: String) : Scrip args.addAll(it) } - val instance = scriptClass.java.constructors.single().newInstance(*args.toArray()) - ?: throw BluePrintProcessorException("failed to create instance from the script") + val instance = if (args.isNotEmpty()) { + scriptClass.java.constructors.single().newInstance(*args.toArray()) + ?: throw BluePrintProcessorException("failed to create instance from the script") + } else { + scriptClass.createInstance() + } - log.info("Created script instance of type ${instance.javaClass}") + log.debug("Created script instance of type ${instance.javaClass}") ResultWithDiagnostics.Success(EvaluationResult(ResultValue.Value(scriptClass.qualifiedName!!, instance, "", instance), diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsConfiguration.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsConfiguration.kt index 3ac790171..e01923723 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsConfiguration.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsConfiguration.kt @@ -35,7 +35,7 @@ object BluePrintScripCompilationConfiguration : ScriptCompilationConfiguration( //classpathFromClassloader(BluePrintScripCompilationConfiguration::class.java.classLoader) classpathFromClasspathProperty() } - ide{ + ide { acceptedLocations(ScriptAcceptedLocation.Everywhere) } @@ -46,6 +46,7 @@ open class BluePrintSourceCode : SourceCode { lateinit var blueprintKotlinSources: MutableList<String> lateinit var moduleName: String lateinit var targetJarFile: File + lateinit var cacheKey: String var regenerate: Boolean = false override val text: String diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImpl.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImpl.kt index e2c02603a..360035327 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImpl.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImpl.kt @@ -19,42 +19,59 @@ package org.onap.ccsdk.cds.controllerblueprints.core.scripts import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintScriptsService -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext -import java.io.File +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils import java.util.* import kotlin.script.experimental.api.ResultValue import kotlin.script.experimental.api.resultOrNull import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate + open class BluePrintScriptsServiceImpl : BluePrintScriptsService { - override suspend fun <T> scriptInstance(blueprintContext: BluePrintContext, scriptClassName: String, - reCompile: Boolean): T { + val log = logger(BluePrintScriptsServiceImpl::class) - val kotlinScriptPath = blueprintContext.rootPath.plus(File.separator) - .plus(BluePrintConstants.TOSCA_SCRIPTS_KOTLIN_DIR) + override suspend fun <T> scriptInstance(bluePrintSourceCode: BluePrintSourceCode, scriptClassName: String): T { + val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<BluePrintKotlinScript>() + val scriptEvaluator = BluePrintScriptEvaluator(scriptClassName) - val compiledJar = kotlinScriptPath.plus(File.separator) - .plus(bluePrintScriptsJarName(blueprintContext)) + val compiledResponse = BlueprintScriptingHost(scriptEvaluator) + .eval(bluePrintSourceCode, compilationConfiguration, null) - val scriptSource = BluePrintSourceCode() + val returnValue = compiledResponse.resultOrNull()?.returnValue as? ResultValue.Value + return returnValue?.value!! as T + } + + override suspend fun <T> scriptInstance(blueprintBasePath: String, artifactName: String, artifactVersion: String, + scriptClassName: String, reCompile: Boolean): T { val sources: MutableList<String> = arrayListOf() - sources.add(kotlinScriptPath) + sources.add(normalizedPathName(blueprintBasePath, BluePrintConstants.TOSCA_SCRIPTS_KOTLIN_DIR)) + + val scriptSource = BluePrintSourceCode() scriptSource.blueprintKotlinSources = sources - scriptSource.moduleName = "${blueprintContext.name()}-${blueprintContext.version()}-cba-kts" - scriptSource.targetJarFile = File(compiledJar) + scriptSource.moduleName = "$artifactName-$artifactVersion-cba-kts" + scriptSource.cacheKey = BluePrintFileUtils.compileCacheKey(blueprintBasePath) + scriptSource.targetJarFile = BluePrintFileUtils.compileJarFile(blueprintBasePath, artifactName, artifactVersion) scriptSource.regenerate = reCompile + return scriptInstance(scriptSource, scriptClassName) + } - val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<BluePrintKotlinScript>() - val scriptEvaluator = BluePrintScriptEvaluator(scriptClassName) - - val compiledResponse = BlueprintScriptingHost(scriptEvaluator).eval(scriptSource, compilationConfiguration, - null) - - val returnValue = compiledResponse.resultOrNull()?.returnValue as? ResultValue.Value + override suspend fun <T> scriptInstance(blueprintBasePath: String, scriptClassName: String, + reCompile: Boolean): T { + val toscaMetaData = BluePrintMetadataUtils.toscaMetaData(blueprintBasePath) + checkNotNull(toscaMetaData.templateName) { "couldn't find 'Template-Name' key in TOSCA.meta" } + checkNotNull(toscaMetaData.templateVersion) { "couldn't find 'Template-Version' key in TOSCA.meta" } + return scriptInstance(blueprintBasePath, toscaMetaData.templateName!!, toscaMetaData.templateVersion!!, + scriptClassName, reCompile) + } - return returnValue?.value!! as T + override suspend fun <T> scriptInstance(cacheKey: String, scriptClassName: String): T { + val args = ArrayList<Any?>() + return BluePrintCompileCache.classLoader(cacheKey).loadClass(scriptClassName).constructors + .single().newInstance(*args.toArray()) as T } override suspend fun <T> scriptInstance(scriptClassName: String): T { @@ -62,8 +79,4 @@ open class BluePrintScriptsServiceImpl : BluePrintScriptsService { return Thread.currentThread().contextClassLoader.loadClass(scriptClassName).constructors .single().newInstance(*args.toArray()) as T } - - private fun bluePrintScriptsJarName(blueprintContext: BluePrintContext): String { - return "${blueprintContext.name()}-${blueprintContext.version()}-cba-kts.jar" - } }
\ No newline at end of file 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 26181bb19..066516fcc 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 @@ -18,12 +18,12 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service -import org.slf4j.LoggerFactory import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.onap.ccsdk.cds.controllerblueprints.core.data.* import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.slf4j.LoggerFactory /** * @@ -32,7 +32,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils */ class BluePrintContext(val serviceTemplate: ServiceTemplate) { - private val log= LoggerFactory.getLogger(this::class.toString()) + private val log = LoggerFactory.getLogger(this::class.toString()) /** * Blueprint CBA extracted file location @@ -43,6 +43,13 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) { */ var entryDefinition = "" + /** Other definitions along with model, It may Resource Definition, Resource Assignments, Configurations etc..*/ + var otherDefinitions: MutableMap<String, Any> = hashMapOf() + + fun <T> otherDefinition(key: String) = otherDefinitions[key] as T + + fun checkOtherDefinition(key: String) = otherDefinitions.containsKey(key) + fun imports(): List<ImportDefinition>? = serviceTemplate.imports fun dslDefinitions() = serviceTemplate.dslDefinitions diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintFileUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintFileUtils.kt index 5f9725f10..17a7fd348 100755 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintFileUtils.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintFileUtils.kt @@ -1,6 +1,7 @@ /* * Copyright © 2017-2018 AT&T Intellectual Property. * Modifications Copyright © 2019 Bell Canada. + * Modifications 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. @@ -17,7 +18,6 @@ package org.onap.ccsdk.cds.controllerblueprints.core.utils -import org.slf4j.LoggerFactory import kotlinx.coroutines.runBlocking import org.apache.commons.io.FileUtils import org.apache.commons.lang3.StringUtils @@ -26,7 +26,10 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode import org.onap.ccsdk.cds.controllerblueprints.core.data.ImportDefinition import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext +import org.slf4j.LoggerFactory import java.io.File import java.io.FileFilter import java.nio.file.Files @@ -38,7 +41,7 @@ import java.nio.file.StandardOpenOption class BluePrintFileUtils { companion object { - private val log= LoggerFactory.getLogger(this::class.toString()) + private val log = LoggerFactory.getLogger(this::class.toString()) fun createEmptyBluePrint(basePath: String) { @@ -213,11 +216,13 @@ class BluePrintFileUtils { "\nCSAR-Version: <VERSION>" + "\nCreated-By: <AUTHOR NAME>" + "\nEntry-Definitions: Definitions/<BLUEPRINT_NAME>.json" + + "\nTemplate-Name: <BLUEPRINT_NAME>"+ + "\nTemplate-Tags: <BLUEPRINT_VERSION>"+ "\nTemplate-Tags: <TAGS>" } - - fun getBluePrintFile(fileName: String, targetPath: Path) : File { + + fun getBluePrintFile(fileName: String, targetPath: Path): File { val filePath = targetPath.resolve(fileName).toString() val file = File(filePath) check(file.exists()) { @@ -241,6 +246,24 @@ class BluePrintFileUtils { return fileStorageLocation } + fun compileCacheKey(basePath: String): String { + return normalizedPathName(basePath) + } + + private fun compileJarFileName(artifactName: String, artifactVersion: String): String { + return "$artifactName-$artifactVersion-cba-kts.jar" + } + + fun compileJarFilePathName(basePath: String, artifactName: String, artifactVersion: String): String { + return normalizedPathName(basePath, BluePrintConstants.TOSCA_SCRIPTS_KOTLIN_DIR, + compileJarFileName(artifactName, artifactVersion)) + } + + fun compileJarFile(basePath: String, artifactName: String, artifactVersion: String): File { + return normalizedFile(compileJarFilePathName(basePath, + artifactName, artifactVersion)) + } + fun stripFileExtension(fileName: String): String { val dotIndexe = fileName.lastIndexOf('.') diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtils.kt index ef5cb81d9..3a1edccc0 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtils.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtils.kt @@ -22,6 +22,8 @@ import com.fasterxml.jackson.databind.JsonNode import kotlinx.coroutines.runBlocking import org.onap.ccsdk.cds.controllerblueprints.core.* import org.onap.ccsdk.cds.controllerblueprints.core.data.ToscaMetaData +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintDefinitions +import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintScriptsServiceImpl import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintImportService import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService @@ -83,6 +85,8 @@ class BluePrintMetadataUtils { "CSAR-Version" -> toscaMetaData.csarVersion = value "Created-By" -> toscaMetaData.createdBy = value "Entry-Definitions" -> toscaMetaData.entityDefinitions = value + "Template-Name" -> toscaMetaData.templateName = value + "Template-Version" -> toscaMetaData.templateVersion = value "Template-Tags" -> toscaMetaData.templateTags = value } } @@ -133,7 +137,12 @@ class BluePrintMetadataUtils { log.info("Reading blueprint path($blueprintBasePath) and entry definition file (${toscaMetaData.entityDefinitions})") - readBlueprintFile(toscaMetaData.entityDefinitions, blueprintBasePath) + // If the EntryDefinition is Kotlin file, compile and get Service Template + if (toscaMetaData.entityDefinitions.endsWith("kt")) { + readBlueprintKotlinFile(toscaMetaData, blueprintBasePath) + } else { + readBlueprintFile(toscaMetaData.entityDefinitions, blueprintBasePath) + } } private suspend fun getBaseEnhancementBluePrintContext(blueprintBasePath: String): BluePrintContext { @@ -153,15 +162,42 @@ class BluePrintMetadataUtils { } private suspend fun readBlueprintFile(entityDefinitions: String, basePath: String): BluePrintContext { - val rootFilePath: String = basePath.plus(File.separator).plus(entityDefinitions) + val normalizedBasePath = normalizedPathName(basePath) + val rootFilePath = normalizedPathName(normalizedBasePath, entityDefinitions) val rootServiceTemplate = ServiceTemplateUtils.getServiceTemplate(rootFilePath) // Recursively Import Template files - val schemaImportResolverUtils = BluePrintImportService(rootServiceTemplate, basePath) + val schemaImportResolverUtils = BluePrintImportService(rootServiceTemplate, normalizedBasePath) val completeServiceTemplate = schemaImportResolverUtils.getImportResolvedServiceTemplate() val blueprintContext = BluePrintContext(completeServiceTemplate) - blueprintContext.rootPath = basePath + blueprintContext.rootPath = normalizedBasePath blueprintContext.entryDefinition = entityDefinitions return blueprintContext } + + /** Reade the Service Template Definitions from the Kotlin file */ + private suspend fun readBlueprintKotlinFile(toscaMetaData: ToscaMetaData, basePath: String): BluePrintContext { + + checkNotNull(toscaMetaData.templateName) { "couldn't find 'Template-Name' key in TOSCA.meta" } + checkNotNull(toscaMetaData.templateVersion) { "couldn't find 'Template-Version' key in TOSCA.meta" } + + val definitionClassName = toscaMetaData.entityDefinitions.removeSuffix(".kt") + val normalizedBasePath = normalizedPathName(basePath) + + val bluePrintScriptsService = BluePrintScriptsServiceImpl() + val bluePrintDefinitions = bluePrintScriptsService + .scriptInstance<BluePrintDefinitions>(normalizedBasePath, toscaMetaData.templateName!!, + toscaMetaData.templateVersion!!, definitionClassName, true) + // Get the Service Template + val serviceTemplate = bluePrintDefinitions.serviceTemplate() + + // Clean the Default type import Definitions + BluePrintFileUtils.cleanImportTypes(serviceTemplate) + + val blueprintContext = BluePrintContext(serviceTemplate) + blueprintContext.rootPath = normalizedBasePath + blueprintContext.entryDefinition = toscaMetaData.entityDefinitions + blueprintContext.otherDefinitions = bluePrintDefinitions.otherDefinitions() + return blueprintContext + } } }
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImplTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImplTest.kt new file mode 100644 index 000000000..66fec7553 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImplTest.kt @@ -0,0 +1,81 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * Modifications 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.scripts + + +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintDefinitions +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName +import kotlin.script.experimental.jvm.util.classpathFromClass +import kotlin.script.experimental.jvm.util.classpathFromClassloader +import kotlin.script.experimental.jvm.util.classpathFromClasspathProperty +import kotlin.test.assertNotNull + +class BluePrintScriptsServiceImplTest { + + private fun viewClassPathInfo() { + + println(" *********** classpathFromClass *********** ") + classpathFromClass(BluePrintScriptsServiceImplTest::class.java.classLoader, + BluePrintScriptsServiceImplTest::class)!! + .forEach(::println) + + println(" *********** classpathFromClassloader *********** ") + classpathFromClassloader(BluePrintScriptsServiceImplTest::class.java.classLoader)!! + .forEach(::println) + + println(" *********** classpathFromClasspathProperty *********** ") + classpathFromClasspathProperty()!! + .forEach(::println) + } + + @Test + fun testCachedService() { + runBlocking { + + val bluePrintScriptsService = BluePrintScriptsServiceImpl() + + val basePath = normalizedPathName("src/test/resources/compile") + /** Load the Definitions */ + val bluePrintDefinitions = bluePrintScriptsService + .scriptInstance<BluePrintDefinitions>(basePath, + "cba.scripts.ActivateBlueprintDefinitions", true) + assertNotNull(bluePrintDefinitions, "failed to get blueprint definitions") + + val serviceTemplate = bluePrintDefinitions.serviceTemplate() + assertNotNull(serviceTemplate, "failed to get service template") + + val customDataType = bluePrintDefinitions.otherDefinition<DataType>("datatype-custom-datatype") + assertNotNull(customDataType, "failed to get custom definitions") + + val instance = bluePrintScriptsService + .scriptInstance<BlueprintFunctionNode<String, String>>(basePath, + "cba.scripts.SampleBlueprintFunctionNode", false) + assertNotNull(instance, "failed to get compiled instance") + + val cachedInstance = bluePrintScriptsService + .scriptInstance<BlueprintFunctionNode<String, String>>(basePath, + "cba.scripts.SampleBlueprintFunctionNode", false) + assertNotNull(cachedInstance, "failed to get cached compile instance") + } + } + +}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BlueprintScriptingHostTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BlueprintScriptingHostTest.kt deleted file mode 100644 index 2288d62c8..000000000 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BlueprintScriptingHostTest.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright © 2017-2018 AT&T Intellectual Property. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.ccsdk.cds.controllerblueprints.core.scripts - - -import org.apache.commons.io.FileUtils -import org.junit.Test -import java.io.File -import kotlin.script.experimental.jvm.util.classpathFromClass -import kotlin.script.experimental.jvm.util.classpathFromClassloader -import kotlin.script.experimental.jvm.util.classpathFromClasspathProperty -import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate - -class BlueprintScriptingHostTest { - - private fun viewClassPathInfo() { - - println(" *********** classpathFromClass *********** ") - classpathFromClass(BlueprintScriptingHostTest::class.java.classLoader, - BlueprintScriptingHostTest::class)!! - .forEach(::println) - - println(" *********** classpathFromClassloader *********** ") - classpathFromClassloader(BlueprintScriptingHostTest::class.java.classLoader)!! - .forEach(::println) - - println(" *********** classpathFromClasspathProperty *********** ") - classpathFromClasspathProperty()!! - .forEach(::println) - } - - @Test - fun `test same script two folders`() { - - FileUtils.forceMkdir(File("target/scripts1/")) - FileUtils.forceMkdir(File("target/scripts2/")) - - val scriptSource1 = BluePrintSourceCode() - scriptSource1.moduleName = "blueprint-test-script" - - scriptSource1.targetJarFile = File("target/scripts1/blueprint-script-generated.jar") - val sources1: MutableList<String> = arrayListOf() - sources1.add("src/test/resources/scripts1") - scriptSource1.blueprintKotlinSources = sources1 - - val scriptClassName = "Simple_cba\$SampleComponentFunction" - - val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<BluePrintKotlinScript>() - - val scriptEvaluator = BluePrintScriptEvaluator(scriptClassName) - - val scriptSource2 = BluePrintSourceCode() - scriptSource2.moduleName = "blueprint-test-script" - - scriptSource2.targetJarFile = File("target/scripts2/blueprint-script-generated.jar") - val sources2: MutableList<String> = arrayListOf() - sources2.add("src/test/resources/scripts2") - scriptSource2.blueprintKotlinSources = sources2 - - for (i in 1..2) { - val evalResponse = BlueprintScriptingHost(scriptEvaluator).eval(scriptSource1, compilationConfiguration, - null) - } - - for (i in 1..2) { - val evalResponse = BlueprintScriptingHost(scriptEvaluator).eval(scriptSource2, compilationConfiguration, - null) - } - } -}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt index 1a6ccfa17..6c0c30e3d 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt @@ -21,9 +21,12 @@ package org.onap.ccsdk.cds.controllerblueprints.core.utils import kotlinx.coroutines.runBlocking import org.junit.Test import org.onap.ccsdk.cds.controllerblueprints.core.data.ToscaMetaData +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName +import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertNull +import kotlin.test.assertTrue class BluePrintMetadataUtilsTest { @@ -45,6 +48,24 @@ class BluePrintMetadataUtilsTest { } @Test + fun testKotlinBluePrintContext() { + val path = normalizedPathName("src/test/resources/compile") + val blueprintContext = BluePrintMetadataUtils.getBluePrintContext(path) + assertNotNull(blueprintContext, "failed to get blueprint context") + assertNotNull(blueprintContext.serviceTemplate, "failed to get blueprint context service template") + assertNotNull(blueprintContext.serviceTemplate, "failed to get blueprint context service template") + assertNotNull(blueprintContext.otherDefinitions, "failed to get blueprint contextother definitions") + + var cachePresent = BluePrintCompileCache.hasClassLoader(path) + assertTrue(cachePresent, "failed to generate cache key ($path)") + + /** Cleaning Cache */ + BluePrintCompileCache.cleanClassLoader(path) + cachePresent = BluePrintCompileCache.hasClassLoader(path) + assertTrue(!cachePresent, "failed to remove cache key ($path)") + } + + @Test fun environmentDataTest() { val environmentPath = "./src/test/resources/environments" diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/Scripts/kotlin/ActivateBlueprintDefinitions.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/Scripts/kotlin/ActivateBlueprintDefinitions.kt new file mode 100644 index 000000000..4f4d210ca --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/Scripts/kotlin/ActivateBlueprintDefinitions.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 cba.scripts + +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.dataType +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.serviceTemplate +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.AbstractBluePrintDefinitions + +class ActivateBlueprintDefinitions : AbstractBluePrintDefinitions() { + + override fun serviceTemplate(): ServiceTemplate { + + return serviceTemplate("sample-blue-print", "1.0.0", + "brindasanth@onap.com", "sample, blueprints") { + topologyTemplate { + workflowNodeTemplate("activate", "component-resource-resolution", "") { + operation("ResourceResolutionExecutor", "") { + inputs { + property("string-value", "sample") + } + } + } + } + } + } + + override fun loadOtherDefinitions() { + /** Sample Definitions */ + val customDataType = dataType("custom-datatype", "1.0.0", + BluePrintConstants.MODEL_TYPE_DATATYPES_ROOT, "") { + property("name", BluePrintConstants.DATA_TYPE_STRING, true, "") + property("value", BluePrintConstants.DATA_TYPE_STRING, true, "") + } + /** Loading to definitions */ + addOtherDefinition("datatype-custom-datatype", customDataType) + } +}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts/SampleBlueprintFunctionNode.kts b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/Scripts/kotlin/SampleBlueprintFunctionNode.kt index 439351b05..aa77bc30b 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts/SampleBlueprintFunctionNode.kts +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/Scripts/kotlin/SampleBlueprintFunctionNode.kt @@ -14,9 +14,11 @@ * limitations under the License. */ +package cba.scripts + import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode -open class SampleBlueprintFunctionNode : BlueprintFunctionNode<String, String>{ +open class SampleBlueprintFunctionNode : BlueprintFunctionNode<String, String> { override fun getName(): String { return "Kotlin-Script-Function-Node" @@ -41,4 +43,24 @@ open class SampleBlueprintFunctionNode : BlueprintFunctionNode<String, String>{ override fun apply(t: String): String { return "$t-status" } + + override suspend fun prepareRequestNB(executionRequest: String): String { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override suspend fun processNB(executionRequest: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override suspend fun prepareResponseNB(): String { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override suspend fun applyNB(t: String): String { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } }
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/TOSCA-Metadata/TOSCA.meta b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 000000000..b1ffabd13 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/compile/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,7 @@ +TOSCA-Meta-File-Version: 1.0.0 +CSAR-Version: 1.0 +Created-By: Brinda Santh <brindasanth@in.ibm.com> +Entry-Definitions: cba.scripts.ActivateBlueprintDefinitions.kt +Template-Tags: Brinda Santh, activation-blueprint +Template-Name: activate-blueprint +Template-Version: 1.0.0 diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts1/simple.cba.kts b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts1/simple.cba.kts deleted file mode 100644 index 4fffda051..000000000 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts1/simple.cba.kts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2017-2018 AT&T Intellectual Property. - * Modifications 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. - */ - -import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive -import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate -import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode -import org.springframework.stereotype.Service - -@Service -open class SampleComponentFunction : BlueprintFunctionNode<String, String> { - - override fun getName(): String { - println("Printing Name....." + "sample".asJsonPrimitive()) - return "my Name" - } - - override suspend fun prepareRequestNB(executionRequest: String): String { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun processNB(executionRequest: String) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: String) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun prepareResponseNB(): String { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun applyNB(t: String): String { - return "Script 1 response - $t" - } -} - -val blueprintFunction = SampleComponentFunction() - -val serviceTemplate = ServiceTemplate() - -println("Simple script printing....") diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts2/simple.cba.kts b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts2/simple.cba.kts deleted file mode 100644 index 4ba56c491..000000000 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/scripts2/simple.cba.kts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2017-2018 AT&T Intellectual Property. - * Modifications 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. - */ - -import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive -import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate -import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode -import org.springframework.stereotype.Service - -@Service -open class SampleComponentFunction : BlueprintFunctionNode<String, String> { - - override fun getName(): String { - println("Printing Name....." + "sample".asJsonPrimitive()) - return "my Name" - } - - override suspend fun prepareRequestNB(executionRequest: String): String { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun processNB(executionRequest: String) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: String) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun prepareResponseNB(): String { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override suspend fun applyNB(t: String): String { - return "Script 2 response - $t" - } -} - -val blueprintFunction = SampleComponentFunction() - -val serviceTemplate = ServiceTemplate() - -println("Simple script printing....") |