diff options
32 files changed, 571 insertions, 136 deletions
diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts index 9f5e1400f..ea4a2dd19 100644 --- a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts @@ -20,19 +20,20 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule, MatAutocompleteModule, MatDialogModule} from '@angular/material'; +import { MatIconModule } from '@angular/material/icon'; +import { FormsModule,ReactiveFormsModule } from '@angular/forms'; +import { NgJsonEditorModule } from 'ang-jsoneditor'; + +import { SharedModule } from '../../../app/common/shared/shared.module'; import { ControllerCatalogRoutingModule } from './controller-catalog-routing.module'; import { ControllerCatalogComponent } from './controller-catalog.component'; -import { SharedModule } from '../../../app/common/shared/shared.module'; -import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule, MatAutocompleteModule} from '@angular/material'; -import { MatIconModule } from '@angular/material/icon'; import { SelectTemplateComponent } from './select-template/select-template.component'; import { TemplateOptionsComponent } from './select-template/template-options/template-options.component'; import { SearchCatalogComponent } from './search-catalog/search-catalog.component'; import { CreateCatalogComponent } from './create-catalog/create-catalog.component'; import { CreateCatalogModule } from './create-catalog/create-catalog.module'; import { SearchCatalogModule } from './search-catalog/search-catalog.module'; -import { FormsModule,ReactiveFormsModule } from '@angular/forms'; -import { NgJsonEditorModule } from 'ang-jsoneditor'; @NgModule({ declarations: [ ControllerCatalogComponent, SelectTemplateComponent, TemplateOptionsComponent, SearchCatalogComponent, CreateCatalogComponent ], @@ -59,6 +60,7 @@ import { NgJsonEditorModule } from 'ang-jsoneditor'; MatFormFieldModule, MatStepperModule, MatAutocompleteModule, + MatDialogModule, FormsModule, ReactiveFormsModule, NgJsonEditorModule diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.html new file mode 100644 index 000000000..ca4a679ed --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.html @@ -0,0 +1,54 @@ +<!--/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* ============LICENSE_END========================================================= +*/--> + +<div> + <h1 mat-dialog-title>Details</h1> + <mat-dialog-content [formGroup]="CatalogFormData"> + <mat-form-field class="form-field"> + <input matInput placeholder="Model Name" formControlName="Model_Name"> + </mat-form-field> + <mat-form-field class="form-field" > + <input matInput placeholder="User Id" formControlName="User_id"> + </mat-form-field> + <mat-form-field class="form-field"> + <input matInput placeholder="Tags" formControlName="_tags"> + </mat-form-field> + <mat-form-field class="form-field"> + <!-- <mat-select matInput placeholder="Definition Type" formControlName="_type"> + <mat-option [value]="item" *ngFor="let item of definitionType">{{item.definitionType}}</mat-option> + </mat-select> --> + <input matInput placeholder="Definition Type" formControlName="_type"> + </mat-form-field> + <mat-form-field class="form-field" > + <!-- <mat-select matInput placeholder="Derived From" formControlName="Derived_From"> + <mat-option [value]="item" *ngFor="let item of derivedFrom">{{item.derivedFrom}}</mat-option> + </mat-select> --> + <input matInput placeholder="Derived From" formControlName="Derived_From"> + </mat-form-field> + <br> + </mat-dialog-content> + <mat-dialog-actions *ngIf="!isDisabled"> + <button mat-button (click)="onNoClick()">Cancel</button> + <button mat-button (click)="onClickSave()">Save</button> + </mat-dialog-actions> + <mat-dialog-actions *ngIf="isDisabled"> + <button mat-button (click)="onNoClick()">Close</button> + </mat-dialog-actions> +</div>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.scss new file mode 100644 index 000000000..9afb1da1b --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.scss @@ -0,0 +1,35 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ============LICENSE_END=========================================================
+*/
+
+.form-field {
+ width: 40%;
+ padding:10px;
+}
+.mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after, .mat-input-element:disabled {
+ color: rgba(0,0,0,.87);
+}
+.mat-button{
+ float: center;
+ color:white;
+ background-color:#3f51b5;
+ margin-top: 10px;
+ margin: 5px;
+ border-radius: 6px;
+}
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.spec.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.spec.ts new file mode 100644 index 000000000..a1f62d1fc --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.spec.ts @@ -0,0 +1,44 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* ============LICENSE_END========================================================= +*/ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CatalogDataDialogComponent } from './catalog-data-dialog.component'; + +describe('CatalogDataDialogComponent', () => { + let component: CatalogDataDialogComponent; + let fixture: ComponentFixture<CatalogDataDialogComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CatalogDataDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CatalogDataDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.ts new file mode 100644 index 000000000..215f311e9 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/catalog-data-dialog/catalog-data-dialog.component.ts @@ -0,0 +1,84 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* ============LICENSE_END========================================================= +*/ +import { Component, OnInit, Inject } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; + +import { ICatalog } from 'src/app/common/core/store/models/catalog.model'; +import { ICatalogState } from 'src/app/common/core/store/models/catalogState.model'; +import { IAppState } from 'src/app/common/core/store/state/app.state'; + +@Component({ + selector: 'app-catalog-data-dialog', + templateUrl: './catalog-data-dialog.component.html', + styleUrls: ['./catalog-data-dialog.component.scss'] +}) +export class CatalogDataDialogComponent implements OnInit{ + + catalog:any=[]; + + CatalogFormData: FormGroup; + ccState: Observable<ICatalogState>; + isDisabled: boolean=true; + optionSelected:string; + // derivedFrom: any[] = [{derivedFrom: 'tosca.nodes.Component'},{derivedFrom:'tosca.nodes.VNF'},{derivedFrom:'tosca.nodes.Artifact'},{derivedFrom:'tosca.nodes.ResourceSource'}, {derivedFrom:'tosca.nodes.Workflow'},{derivedFrom:'tosca.nodes.Root'}]; + // definitionType: any[] = [{definitionType: 'node_type'}]; + property:any=[]; + constructor(public dialogRef: MatDialogRef<CatalogDataDialogComponent>, @Inject(MAT_DIALOG_DATA) public item: any,private formBuilder: FormBuilder, private store: Store<IAppState> ) { + console.log(item); + this.optionSelected=item['option']; + for (let key in item['item']) { + this.catalog.push(item['item'][key]); + } + console.log(this.catalog); + for (let key in this.catalog) { + this.property.push(this.catalog[key]); + } + if(this.optionSelected == 'Info'){ + this.isDisabled = true; + } + else{ + this.isDisabled = false; + } + + this.ccState = this.store.select('catalog'); + this.CatalogFormData = this.formBuilder.group({ + Model_Name: [{value:this.property[0], disabled: this.isDisabled}, Validators.required], + User_id: [{value:this.property[8], disabled: this.isDisabled}, Validators.required], + _tags: [{value:this.property[6], disabled: this.isDisabled}, Validators.required], + _type: [{value:this.property[2], disabled: this.isDisabled}, Validators.required], + Derived_From: [{value:this.property[1], disabled: this.isDisabled}, Validators.required], + }); + } + + ngOnInit(){ + } + + onNoClick(): void { + this.dialogRef.close(); + } + + onClickSave(){ + //this.catalog = Object.assign({}, this.CatalogFormData.value); + this.dialogRef.close(this.CatalogFormData.value); + } +} diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html index 47813829d..c8452e2ff 100644 --- a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html @@ -19,7 +19,7 @@ */--> <form class="search-form" [formGroup]="myControl"> <mat-form-field class="search-full-width"> - <input matInput type="text" [(ngModel)]="searchText" placeholder="Search Resources" formControlName="search_input"> + <input matInput type="text" [(ngModel)]="searchText" placeholder="Search Catalog" formControlName="search_input"> <button matSuffix mat-icon-button (click)="fetchCatalogByName()"> <mat-icon>search</mat-icon> </button> @@ -30,10 +30,12 @@ <div *ngFor="let option of options" style="position: relative !important;width:20% !important"> <mat-card class="example-card"> <mat-card-content class="card-content"> - {{option.modelName}} + {{option.modelName}}<br> + {{option.derivedFrom}} </mat-card-content> <mat-card-actions class="flexBox"> - <button matStepperNext mat-menu-item (click)="editInfo(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,3)">Info</button> + <button class="matStepNextBtn" matStepperNext mat-menu-item (click)="editInfo(option,'Info')">Info</button> + <button class="matStepNextBtn" matStepperNext mat-menu-item (click)="editInfo(option,'Edit')">Edit</button> </mat-card-actions> </mat-card> </div> diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss index a24aebed0..c4eb84ac9 100644 --- a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss @@ -36,14 +36,14 @@ position: relative;
}
-button.mat-menu-item {
+.matStepNextBtn {
width: auto;
- float: left;
- border-radius: 4px;
- background-color: #3f51b5;
+ float: center;
+ color:white;
+ background-color:#3f51b5;
+ margin-top: 10px;
margin: 5px;
- cursor: pointer;
- color: white;
+ border-radius: 6px;
}
.flexBox {
@@ -72,7 +72,7 @@ button.mat-menu-item { }
.mat-card-actions {
- margin-left: 0px !important;
+ margin-left: 50px !important;
margin-right: 0px !important;
padding: 0px 0 !important;
}
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts index b30fc3a78..717e1088f 100644 --- a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts @@ -20,8 +20,19 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { SearchCatalogService } from './search-catalog.service'; +import { MatDialog ,MatDialogRef } from '@angular/material'; import { MatAutocompleteTrigger } from '@angular/material'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; + +import { SearchCatalogService } from './search-catalog.service'; +import { CatalogDataDialogComponent } from './catalog-data-dialog/catalog-data-dialog.component'; +import { ICatalog } from 'src/app/common/core/store/models/catalog.model'; +import { CreateCatalogService } from '../create-catalog/create-catalog.service'; +import { NotificationHandlerService } from 'src/app/common/core/services/notification-handler.service'; +import { ICatalogState } from 'src/app/common/core/store/models/catalogState.model'; +import { IAppState } from 'src/app/common/core/store/state/app.state'; + @Component({ selector: 'app-search-catalog', @@ -31,28 +42,87 @@ import { MatAutocompleteTrigger } from '@angular/material'; export class SearchCatalogComponent implements OnInit { myControl: FormGroup; searchText: string = ''; - options: any[] = []; + + options: any[] = []; + private dialogRef: MatDialogRef<CatalogDataDialogComponent>; + data: any; + catalog: ICatalog; + ccState: Observable<ICatalogState>; @ViewChild('catalogSelect', { read: MatAutocompleteTrigger }) catalogSelect: MatAutocompleteTrigger; - constructor(private _formBuilder: FormBuilder, private searchCatalogService: SearchCatalogService) { } + constructor(private _formBuilder: FormBuilder, private store: Store<IAppState>, private searchCatalogService: SearchCatalogService, private dialog: MatDialog, private catalogCreateService: CreateCatalogService, private alertService: NotificationHandlerService) { + this.ccState = this.store.select('catalog'); + } + ngOnInit() { + + this.ccState.subscribe( + catalogdata => { + var catalogState: ICatalogState = { catalog: catalogdata.catalog, isLoadSuccess: catalogdata.isLoadSuccess, isSaveSuccess: catalogdata.isSaveSuccess, isUpdateSuccess: catalogdata.isUpdateSuccess }; + this.catalog = catalogState.catalog; + console.log( this.catalog ); + }); + this.myControl = this._formBuilder.group({ search_input: ['', Validators.required] }); } fetchCatalogByName() { - this.searchCatalogService.searchByTags(this.searchText) - .subscribe(data=>{ - console.log(data); - data.forEach(element => { - this.options.push(element) - }); - this.catalogSelect.openPanel(); - }, error=>{ - window.alert('Catalog not matching the search tag' + error); - }) + // this.searchCatalogService.searchByTags(this.searchText) + // .subscribe(data=>{ + // console.log(data); + // data.forEach(element => { + // this.options.push(element) + // }); + // this.catalogSelect.openPanel(); + // }, error=>{ + // window.alert('Catalog not matching the search tag' + error); + // }) + + this.options=[ { + "modelName": "tosca.nodes.Artifact", + "derivedFrom": "tosca.nodes.Root", + "definitionType": "node_type", + "definition": { + "description": "This is Deprecated Artifact Node Type.", + "version": "1.0.0", + "derived_from": "tosca.nodes.Root" + }, + "description": "This is Deprecated Artifact Node Type.", + "version": "1.0.0", + "tags": "tosca.nodes.Artifact,tosca.nodes.Root,node_type", + "creationDate": "2019-09-16T07:35:24.000Z", + "updatedBy": "System" + }]; } - editInfo(artifactName: string, artifactVersion: string, option: string) { + editInfo(item: ICatalog, option: string) { + + this.dialogRef = this.dialog.open(CatalogDataDialogComponent, { + height: '500px', + width: '700px', + disableClose: true, + data: {item, option} + }); + + this.dialogRef.afterClosed().subscribe(result => { + if(result == undefined || result == null){ + console.log("dialogbox is closed"); + }else{ + this.catalog.Model_Name=result['Model_Name']; + this.catalog.User_id=result['User_id']; + this.catalog._tags=result['_tags']; + this.catalog._type=result['_type']; + this.catalog.Derived_From=result['Derived_From']; + console.log(this.catalog); + this.catalogCreateService.saveCatalog(this.catalog) + .subscribe(response=>{ + this.alertService.success("save success"+ response) + }, + error=>{ + this.alertService.error('Error saving resources'); + }) + } + }); } } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts index 2aa1a509e..eb608ed6a 100644 --- a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts @@ -21,14 +21,15 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SearchCatalogRoutingModule } from './search-catalog-routing.module'; -import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule, MatAutocompleteModule} from '@angular/material'; +import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatDialogModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule, MatAutocompleteModule } from '@angular/material'; import { MatIconModule } from '@angular/material/icon'; import { SharedModule } from 'src/app/common/shared/shared.module'; import { FormsModule,ReactiveFormsModule } from '@angular/forms'; import { SearchCatalogService } from './search-catalog.service'; +import { CatalogDataDialogComponent } from './catalog-data-dialog/catalog-data-dialog.component'; @NgModule({ - declarations: [], + declarations: [ CatalogDataDialogComponent ], imports: [ CommonModule, SearchCatalogRoutingModule, @@ -51,8 +52,10 @@ import { SearchCatalogService } from './search-catalog.service'; MatRadioModule, MatFormFieldModule, MatStepperModule, - MatAutocompleteModule + MatAutocompleteModule, + MatDialogModule ], - providers: [ SearchCatalogService ] + providers: [ SearchCatalogService ], + entryComponents: [ CatalogDataDialogComponent ] }) export class SearchCatalogModule { } diff --git a/cds-ui/server/src/controllers/blueprint-rest.controller.ts b/cds-ui/server/src/controllers/blueprint-rest.controller.ts index 1eef6fbcb..b52952826 100644 --- a/cds-ui/server/src/controllers/blueprint-rest.controller.ts +++ b/cds-ui/server/src/controllers/blueprint-rest.controller.ts @@ -69,6 +69,20 @@ export class BlueprintRestController { return await this.bpservice.getAllblueprints(); } + @get('/controllerblueprint/meta-data/{keyword}', { + responses: { + '200': { + description: 'Blueprint model instance', + content: { 'application/json': { schema: { 'x-ts-type': Blueprint } } }, + }, + }, + }) + async getAllPacakgesByKeword(@param.path.string('keyword') keyword: string) { + return await this.bpservice.getBlueprintsByKeyword(keyword); + } + + + @get('/controllerblueprint/searchByTags/{tags}', { responses: { '200': { @@ -344,4 +358,4 @@ export class BlueprintRestController { }); }); } -}
\ No newline at end of file +} diff --git a/cds-ui/server/src/datasources/blueprint.datasource-template.ts b/cds-ui/server/src/datasources/blueprint.datasource-template.ts index 85e0aa342..b0aaf01eb 100644 --- a/cds-ui/server/src/datasources/blueprint.datasource-template.ts +++ b/cds-ui/server/src/datasources/blueprint.datasource-template.ts @@ -38,5 +38,21 @@ export default { } }, + { + "template": { + "method": "GET", + "url": processorApiConfig.http.url + "/blueprint-model/meta-data/{keyword}", + "headers": { + "accepts": "application/json", + "content-type": "application/json", + "authorization": processorApiConfig.http.authToken + }, + "responsePath": "$.*" + }, + "functions": { + "getBlueprintsByKeyword": ["keyword"] + + } + }, ] -};
\ 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 0545faca8..7952859d1 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>; + getBlueprintsByKeyword(keyword: string): Promise<any>; getByTags(tags: string): Promise<JSON>; } @@ -17,4 +18,4 @@ export class BlueprintServiceProvider implements Provider<BlueprintService> { value(): Promise<BlueprintService> { return getService(this.dataSource); } -}
\ No newline at end of file +} diff --git a/ms/blueprintsprocessor/application/src/main/docker/Dockerfile b/ms/blueprintsprocessor/application/src/main/docker/Dockerfile index 207cec5cb..2a85f1c95 100755 --- a/ms/blueprintsprocessor/application/src/main/docker/Dockerfile +++ b/ms/blueprintsprocessor/application/src/main/docker/Dockerfile @@ -1,7 +1,6 @@ FROM omahoco1/alpine-java-python # add entrypoint -COPY run.source /etc/run.source COPY startService.sh /startService.sh RUN chmod 777 /startService.sh && dos2unix /startService.sh @@ -12,4 +11,4 @@ RUN tar -xzf /source.tar.gz -C /tmp \ && rm -rf /source.tar.gz \ && rm -rf /tmp/@project.build.finalName@ -ENTRYPOINT /startService.sh +ENTRYPOINT [ "/startService.sh" ] diff --git a/ms/blueprintsprocessor/application/src/main/docker/run.source b/ms/blueprintsprocessor/application/src/main/docker/run.source deleted file mode 100755 index f3d8c7ca6..000000000 --- a/ms/blueprintsprocessor/application/src/main/docker/run.source +++ /dev/null @@ -1,12 +0,0 @@ -java -classpath "/etc:${APP_HOME}/lib/*:/lib/*:/src:/schema:/generated-sources:${APP_CONFIG_HOME}:${APP_HOME}" \ --DappName=${APPLICATIONNAME} -DappVersion=${BUNDLEVERSION} \ --DrouteOffer=${ROUTEOFFER} \ --DVERSION_ROUTEOFFER_ENVCONTEXT=${BUNDLEVERSION}/${STICKYSELECTORKEY}/${ENVCONTEXT} \ --DSecurityFilePath=/etc \ --DREST_NAME_NORMALIZER_PATTERN_FILE=/etc/PatternInputs.txt \ --Dms_name=org.onap.ccsdk.cds.blueprintsprocessor \ --Dlogging.config=${APP_CONFIG_HOME}/logback.xml \ --Djava.security.egd=file:/dev/./urandom \ --DAPPNAME=${APP_NAME} -DAPPENV=${APP_ENV} -DAPPVERSION=${APP_VERSION} -DNAMESPACE=${NAMESPACE} \ --Dspring.config.location=${APP_CONFIG_HOME}/ \ -org.onap.ccsdk.cds.blueprintsprocessor.BlueprintProcessorApplicationKt diff --git a/ms/blueprintsprocessor/application/src/main/docker/startService.sh b/ms/blueprintsprocessor/application/src/main/docker/startService.sh index 14d772e41..11c471f2d 100644 --- a/ms/blueprintsprocessor/application/src/main/docker/startService.sh +++ b/ms/blueprintsprocessor/application/src/main/docker/startService.sh @@ -7,4 +7,15 @@ export APP_HOME=/opt/app/onap keytool -import -noprompt -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias ONAP -import -file $APP_CONFIG_HOME/ONAP_RootCA.cer -source /etc/run.source +exec java -classpath "/etc:${APP_HOME}/lib/*:/lib/*:/src:/schema:/generated-sources:${APP_CONFIG_HOME}:${APP_HOME}" \ +-DappName=${APPLICATIONNAME} -DappVersion=${BUNDLEVERSION} \ +-DrouteOffer=${ROUTEOFFER} \ +-DVERSION_ROUTEOFFER_ENVCONTEXT=${BUNDLEVERSION}/${STICKYSELECTORKEY}/${ENVCONTEXT} \ +-DSecurityFilePath=/etc \ +-DREST_NAME_NORMALIZER_PATTERN_FILE=/etc/PatternInputs.txt \ +-Dms_name=org.onap.ccsdk.cds.blueprintsprocessor \ +-Dlogging.config=${APP_CONFIG_HOME}/logback.xml \ +-Djava.security.egd=file:/dev/./urandom \ +-DAPPNAME=${APP_NAME} -DAPPENV=${APP_ENV} -DAPPVERSION=${APP_VERSION} -DNAMESPACE=${NAMESPACE} \ +-Dspring.config.location=${APP_CONFIG_HOME}/ \ +org.onap.ccsdk.cds.blueprintsprocessor.BlueprintProcessorApplicationKt diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt index f5567b7a2..2395dddb8 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt @@ -29,11 +29,11 @@ class DeviceInfo { @get:JsonProperty("port-number") var port: Int = 0 @get:JsonProperty("connection-time-out") - var connectTimeout: Long = 5 + var connectTimeout: Long = 30 @get:JsonIgnore var source: String? = null @get:JsonIgnore - var replyTimeout: Int = 5 + var replyTimeout: Int = 20 @get:JsonIgnore var idleTimeout: Int = 99999 @@ -50,4 +50,4 @@ class DeviceInfo { override fun hashCode(): Int { return javaClass.hashCode() } -}
\ No newline at end of file +} diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt index bc91b7d92..06a71cad3 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt @@ -195,7 +195,7 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, } fun sendMessage(request: String, messageId: String): CompletableFuture<String> { - log.info("$deviceInfo: Sending message: \n $request") + log.info("$deviceInfo: Sending message with message-id: $messageId: message: \n $request") val future = CompletableFuture<String>() replies.put(messageId, future) val outputStream = OutputStreamWriter(out, StandardCharsets.UTF_8) diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt index 6a045e365..2e33b9aa2 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt @@ -38,15 +38,36 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ this.netconfSession = netconfSession } + /** + * accept a user-supplied RPC message WITH HEADER + * <rpc message-id="abc123" xmlns="....."> + * ..... + * ..... + * </rpc> + * + * and replace the user-supplied message-id with the one that is passed. + * Used by NetconfRpcServiceImpl.invokeRpc to keep the message-id consistent + * with auto-incremented numbering scheme. + * @param rpc: Complete custom RPC call including the header + * @param updatedMessageID new message-id to substitute + * @return updated RPC message with message-id replaced. + */ + private fun replaceUserSuppliedNetconfMessageID(rpc: String, updatedMessageID: String): String { + return rpc.replaceFirst("message-id=\".+\"".toRegex(), "message-id=\"$updatedMessageID\"") + } + override fun invokeRpc(rpc: String): DeviceResponse { var output = DeviceResponse() - val messageId = messageIdInteger.getAndIncrement().toString() - log.info("$deviceInfo: invokeRpc: messageId($messageId)") + //Attempt to extract the message-id field from the <rpc call + val updatedMessageId = messageIdInteger.getAndIncrement().toString() + val origMessageId = NetconfMessageUtils.getMsgId(rpc) + log.info("$deviceInfo: invokeRpc: updating rpc original message-id:($origMessageId) to messageId($updatedMessageId)") try { - output = asyncRpc(rpc, messageId) + output = asyncRpc(replaceUserSuppliedNetconfMessageID(rpc, updatedMessageId), updatedMessageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'invokeRpc' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'invokeRpc' command. Message: ${e.message}." + log.error("$deviceInfo: failed in 'invokeRpc' command. Exception: $e") } return output } @@ -60,7 +81,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(message, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'get' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'get' command. Message: ${e.message}..." + log.error("$deviceInfo: failed in 'get' command. Exception: $e") } return output } @@ -74,7 +96,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(message, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'get-config' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'get-config' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'get-config' command. Exception: $e") } return output } @@ -89,7 +112,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(deleteConfigMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'delete-config' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'delete-config' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'deleteConfig' command. Exception: $e") } return output } @@ -104,7 +128,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(lockMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'lock' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'lock' command. Message ${e.message}" + log.error("$deviceInfo: failed in 'lock' command. Exception: $e") } return output @@ -120,7 +145,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(unlockMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'unLock' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'unLock' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'unLock' command. Exception: $e") } return output } @@ -134,7 +160,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(messageContent, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'commit' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'commit' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'commit' command. Exception: $e") } return output } @@ -148,7 +175,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(messageContent, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'cancelCommit' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'cancelCommit' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'cancelCommit' command. Exception: $e") } return output } @@ -163,7 +191,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(discardChangesMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'discard-config' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'discard-config' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'discard-config' command. Exception: $e") } return output } @@ -180,7 +209,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ response = asyncRpc(editMessage, messageId) } catch (e: Exception) { response.status = RpcStatus.FAILURE - response.errorMessage = "$deviceInfo: failed in 'editConfig' command ${e.message}" + response.errorMessage = "$deviceInfo: failed in 'editConfig' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'editConfig' command. Exception: $e") } return response } @@ -194,7 +224,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(validateMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'validate' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'validate' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'validate' command. Exception: $e") } return output } @@ -208,7 +239,8 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(messageContent, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in 'closeSession' command ${e.message}" + output.errorMessage = "$deviceInfo: failed in 'closeSession' command. Message: ${e.message}" + log.error("$deviceInfo: failed in 'closeSession' command. Exception: $e") } return output } @@ -220,7 +252,9 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ response.requestMessage = request val rpcResponse = netconfSession.asyncRpc(request, messageId).get(responseTimeout.toLong(), TimeUnit.SECONDS) + //TODO catch TimeoutException and ExecutionException if (!NetconfMessageUtils.checkReply(rpcResponse)) { + log.error("RPC response didn't pass validation... $rpcResponse") throw NetconfException(rpcResponse) } response.responseMessage = rpcResponse diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt index a0f653591..6be93179f 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt @@ -66,8 +66,15 @@ class NetconfSessionImpl(private val deviceInfo: DeviceInfo, private val rpcServ } override fun disconnect() { - if (rpcService.closeSession(false).status.equals( - RpcStatus.FAILURE, true)) { + var retryNum = 3 + while(rpcService.closeSession(false).status + .equals(RpcStatus.FAILURE, true) &&retryNum>0) { + log.error("disconnect: graceful disconnect failed, retrying $retryNum times...") + retryNum--; + } + //if we can't close the session, try to force terminate. + if(retryNum == 0) { + log.error("disconnect: trying to force-terminate the session.") rpcService.closeSession(true) } try { @@ -241,6 +248,7 @@ class NetconfSessionImpl(private val deviceInfo: DeviceInfo, private val rpcServ if (sessionIDMatcher.find()) { sessionId = sessionIDMatcher.group(1) + log.info("netconf exchangeHelloMessage sessionID: $sessionId") } else { throw NetconfException("$deviceInfo: Missing sessionId in server hello message: $serverHelloResponse") } @@ -276,6 +284,7 @@ class NetconfSessionImpl(private val deviceInfo: DeviceInfo, private val rpcServ */ @Throws(IOException::class) private fun close() { + log.debug("close was called.") session.close() // Closes the socket which should interrupt the streamHandler channel.close() diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt index 4d65d36bb..34816b79b 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt @@ -221,7 +221,15 @@ class NetconfMessageUtils { fun closeSession(messageId: String, force: Boolean): String { val request = StringBuilder() - + //TODO: kill-session without session-id is a cisco-only variant. + //will fail on JUNIPER device. + //netconf RFC for kill-session requires session-id + //Cisco can accept <kill-session/> for current session + //or <kill-session><session-id>####</session-id></kill-session> + //as long as session ID is not the same as the current session. + + //Juniperhttps://www.juniper.net/documentation/en_US/junos/topics/task/operational/netconf-session-terminating.html + //will accept only with session-id if (force) { request.append("<kill-session/>") } else { @@ -413,4 +421,4 @@ class NetconfMessageUtils { } } -}
\ No newline at end of file +} diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/repository/BlueprintModelSearchRepository.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/repository/BlueprintModelSearchRepository.kt index f5ef0740e..60ca1fec1 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/repository/BlueprintModelSearchRepository.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/repository/BlueprintModelSearchRepository.kt @@ -1,5 +1,6 @@ /* * Copyright © 2019 IBM. + * Modifications Copyright © 2019 Orange. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,4 +60,20 @@ interface BlueprintModelSearchRepository : JpaRepository<BlueprintModelSearch, L * @return Optional<BlueprintModelSearch> </BlueprintModelSearch> */ fun findByTagsContainingIgnoreCase(tags: String): List<BlueprintModelSearch> -}
\ No newline at end of file + + /** + * This is a findby some attributes method + * + * @author Shaaban Ebrahim + * + * @param updatedBy + * @param tags + * @param artifactName + * @param artifactVersion + * @param artifactType + * @return Optional<BlueprintModelSearch> + </BlueprintModelSearch> + */ + fun findByUpdatedByOrTagsOrOrArtifactNameOrOrArtifactVersionOrArtifactType(updatedBy: String, tags: String, artifactName: String, artifactVersion: String, + artifactType: String): List<BlueprintModelSearch> +} diff --git a/ms/blueprintsprocessor/modules/commons/dmaap-lib/src/main/resources/event.properties b/ms/blueprintsprocessor/modules/commons/dmaap-lib/src/main/resources/event.properties index 320b08e85..b44dba30a 100644 --- a/ms/blueprintsprocessor/modules/commons/dmaap-lib/src/main/resources/event.properties +++ b/ms/blueprintsprocessor/modules/commons/dmaap-lib/src/main/resources/event.properties @@ -18,7 +18,7 @@ # ============LICENSE_END========================================================= # -#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH > +#TransportType-Specify which way user want to use. I.e. <HTTPAAF,HTTPAUTH > Protocol =http partition=1 contenttype = application/json diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt index b68627fec..182d5defa 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibConfiguration.kt @@ -57,7 +57,6 @@ class RestLibConstants { const val TYPE_SSL_BASIC_AUTH = "ssl-basic-auth" const val TYPE_SSL_TOKEN_AUTH = "ssl-token-auth" const val TYPE_SSL_NO_AUTH = "ssl-no-auth" - const val TYPE_DME2_PROXY = "dme2-proxy" const val TYPE_POLICY_MANAGER = "policy-manager" } -}
\ No newline at end of file +} diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt index 1e6e23b86..ea32a1635 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/BluePrintRestLibData.kt @@ -52,16 +52,6 @@ open class TokenAuthRestClientProperties : RestClientProperties() { var token: String? = null } -open class DME2RestClientProperties : RestClientProperties() { - lateinit var service: String - lateinit var subContext: String - lateinit var version: String - lateinit var envContext: String - lateinit var routeOffer: String - var partner: String? = null - lateinit var appId: String -} - open class PolicyManagerRestClientProperties : RestClientProperties() { lateinit var env: String lateinit var clientAuth: String diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt index 384946ae8..9a7b3c303 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/BluePrintRestLibPropertyService.kt @@ -76,9 +76,7 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: RestLibConstants.TYPE_SSL_NO_AUTH -> { sslNoAuthRestClientProperties(prefix) } - RestLibConstants.TYPE_DME2_PROXY -> { - dme2ProxyClientProperties(prefix) - } + RestLibConstants.TYPE_POLICY_MANAGER -> { policyManagerRestClientProperties(prefix) } @@ -99,9 +97,7 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: RestLibConstants.TYPE_BASIC_AUTH -> { JacksonUtils.readValue(jsonNode, BasicAuthRestClientProperties::class.java)!! } - RestLibConstants.TYPE_DME2_PROXY -> { - JacksonUtils.readValue(jsonNode, DME2RestClientProperties::class.java)!! - } + RestLibConstants.TYPE_POLICY_MANAGER -> { JacksonUtils.readValue(jsonNode, PolicyManagerRestClientProperties::class.java)!! } @@ -134,9 +130,6 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: is BasicAuthRestClientProperties -> { return BasicAuthRestClientService(restClientProperties) } - is DME2RestClientProperties -> { - return DME2ProxyRestClientService(restClientProperties) - } else -> { throw BluePrintProcessorException("couldn't get rest service for type:${restClientProperties.type} uri: ${restClientProperties.url}") } @@ -187,12 +180,6 @@ open class BluePrintRestLibPropertyService(private var bluePrintProperties: prefix, SSLRestClientProperties::class.java) } - private fun dme2ProxyClientProperties(prefix: String): - DME2RestClientProperties { - return bluePrintProperties.propertyBeanType( - prefix, DME2RestClientProperties::class.java) - } - private fun policyManagerRestClientProperties(prefix: String): PolicyManagerRestClientProperties { return bluePrintProperties.propertyBeanType( diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt deleted file mode 100644 index 8e0a2d3f0..000000000 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/DME2ProxyRestClientService.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2017-2019 AT&T, Bell Canada - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.ccsdk.cds.blueprintsprocessor.rest.service - -import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties - -class DME2ProxyRestClientService(restClientProperties: RestClientProperties) : BlueprintWebClientService { - override fun defaultHeaders(): Map<String, String> { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override fun host(uri: 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/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt index bf251f6c3..ea5023cd5 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt @@ -1,6 +1,7 @@ /* * Copyright © 2019 Bell Canada Intellectual Property. * Modifications Copyright © 2019 IBM. + * Modifications Copyright © 2019 Orange. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +20,16 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam +import org.jetbrains.annotations.NotNull import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler.BluePrintModelHandler +import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils.BlueprintSortByOption import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.monoMdc import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.springframework.core.io.Resource +import org.springframework.data.domain.Page +import org.springframework.data.domain.PageRequest +import org.springframework.data.domain.Sort import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.http.codec.multipart.FilePart @@ -56,6 +62,24 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint return this.bluePrintModelHandler.allBlueprintModel() } + @GetMapping("/paged", produces = [MediaType.APPLICATION_JSON_VALUE]) + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun allBlueprintModel(@RequestParam(defaultValue = "20") limit: Int, + @RequestParam(defaultValue = "0") offset: Int, + @RequestParam(defaultValue = "DATE") sort: BlueprintSortByOption): Page<BlueprintModelSearch> { + val pageRequest = PageRequest.of(offset, limit, Sort.Direction.ASC, sort.columnName) + return this.bluePrintModelHandler.allBlueprintModel(pageRequest) + } + + @GetMapping("meta-data/{keyword}", produces = [MediaType.APPLICATION_JSON_VALUE]) + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun allBlueprintModelMetaData(@NotNull @PathVariable(value = "keyword") keyWord: String): List<BlueprintModelSearch> { + return this.bluePrintModelHandler.searchBluePrintModelsByKeyWord(keyWord) + } + + @DeleteMapping("/{id}") @Throws(BluePrintException::class) @PreAuthorize("hasRole('USER')") diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/BluePrintModelHandler.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/BluePrintModelHandler.kt index 526e92cea..19076c681 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/BluePrintModelHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/BluePrintModelHandler.kt @@ -2,6 +2,7 @@ * Copyright © 2017-2018 AT&T Intellectual Property. * Modifications Copyright © 2019 Bell Canada. * Modifications Copyright © 2019 IBM. + * Modifications Copyright © 2019 Orange. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +34,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCach import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils import org.springframework.core.io.ByteArrayResource import org.springframework.core.io.Resource +import org.springframework.data.domain.Page import org.springframework.http.HttpHeaders import org.springframework.http.MediaType import org.springframework.http.ResponseEntity @@ -41,6 +43,8 @@ import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.io.IOException import java.util.* +import org.springframework.data.domain.Pageable + /** * BlueprintModelHandler Purpose: Handler service to handle the request from BlurPrintModelRest @@ -69,6 +73,15 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService: } /** + * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database + * + * @return List<BlueprintModelSearch> list of the controller blueprint archives + </BlueprintModelSearch> */ + open fun allBlueprintModel(pageRequest: Pageable): Page<BlueprintModelSearch> { + return blueprintModelSearchRepository.findAll(pageRequest) + } + + /** * This is a saveBlueprintModel method * * @param filePart filePart @@ -220,6 +233,20 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService: } /** + * This is a searchBluePrintModelsByKeyWord method to retrieve specific BlueprintModel in Database + * where keyword equals updatedBy or tags or artifcat name or artifcat version or artifact type + * @author Shaaban Ebrahim + * @param keyWord + * + * @return List<BlueprintModelSearch> list of the controller blueprint + </BlueprintModelSearch> */ + open fun searchBluePrintModelsByKeyWord(keyWord: String): List<BlueprintModelSearch> { + return blueprintModelSearchRepository. + findByUpdatedByOrTagsOrOrArtifactNameOrOrArtifactVersionOrArtifactType( + keyWord,keyWord,keyWord,keyWord,keyWord) + } + + /** * This is a deleteBlueprintModel method * * @param id id diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/utils/SortByOptionsEnum.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/utils/SortByOptionsEnum.kt new file mode 100644 index 000000000..6f5636516 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/utils/SortByOptionsEnum.kt @@ -0,0 +1,6 @@ +package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils + +enum class BlueprintSortByOption(val columnName: String) { + DATE("createdDate"), + NAME("artifactName") +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt index eb450d73b..636a55423 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt @@ -27,6 +27,8 @@ import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOu import org.slf4j.LoggerFactory import org.springframework.security.access.prepost.PreAuthorize import org.springframework.stereotype.Service +import java.util.concurrent.Phaser +import javax.annotation.PreDestroy @Service open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration, @@ -34,6 +36,8 @@ open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration : BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase() { private val log = LoggerFactory.getLogger(BluePrintProcessingGRPCHandler::class.java) + private val ph = Phaser(1) + @PreAuthorize("hasRole('USER')") override fun process( responseObserver: StreamObserver<ExecutionServiceOutput>): StreamObserver<ExecutionServiceInput> { @@ -41,12 +45,16 @@ open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration return object : StreamObserver<ExecutionServiceInput> { override fun onNext(executionServiceInput: ExecutionServiceInput) { try { + ph.register() runBlocking { executionServiceHandler.process(executionServiceInput.toJava(), responseObserver) } } catch (e: Exception) { onError(e) } + finally { + ph.arriveAndDeregister() + } } override fun onError(error: Throwable) { @@ -61,4 +69,12 @@ open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration } } } + + @PreDestroy + fun preDestroy() { + val name = "BluePrintProcessingGRPCHandler" + log.info("Starting to shutdown $name waiting for in-flight requests to finish ...") + ph.arriveAndAwaitAdvance() + log.info("Done waiting in $name") + } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumer.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumer.kt index b339903c5..a9dda7e0c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumer.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumer.kt @@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.event.ApplicationReadyEvent import org.springframework.context.event.EventListener import org.springframework.stereotype.Service +import java.util.concurrent.Phaser import javax.annotation.PreDestroy @ConditionalOnProperty(name = ["blueprintsprocessor.messageconsumer.self-service-api.kafkaEnable"], @@ -40,6 +41,8 @@ open class BluePrintProcessingKafkaConsumer( val log = logger(BluePrintProcessingKafkaConsumer::class) + private val ph = Phaser(1) + private lateinit var blueprintMessageConsumerService: BlueprintMessageConsumerService companion object { @@ -76,6 +79,7 @@ open class BluePrintProcessingKafkaConsumer( channel.consumeEach { message -> launch { try { + ph.register() log.trace("Consumed Message : $message") val executionServiceInput = message.jsonAsType<ExecutionServiceInput>() val executionServiceOutput = executionServiceHandler.doProcess(executionServiceInput) @@ -85,6 +89,9 @@ open class BluePrintProcessingKafkaConsumer( } catch (e: Exception) { log.error("failed in processing the consumed message : $message", e) } + finally { + ph.arriveAndDeregister() + } } } } @@ -100,6 +107,7 @@ open class BluePrintProcessingKafkaConsumer( log.info("Shutting down message consumer($CONSUMER_SELECTOR) and " + "message producer($PRODUCER_SELECTOR)...") blueprintMessageConsumerService.shutDown() + ph.arriveAndAwaitAdvance() } catch (e: Exception) { log.error("failed to shutdown message listener($CONSUMER_SELECTOR)", e) } diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt index 345650686..130e23ecc 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt @@ -1,6 +1,6 @@ /* * Copyright © 2017-2018 AT&T Intellectual Property. - * Modifications Copyright © 2019 IBM. + * Modifications Copyright © 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. @@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam +import kotlinx.coroutines.Dispatchers import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_ASYNC import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput @@ -33,6 +34,8 @@ import org.springframework.http.ResponseEntity import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import reactor.core.publisher.Mono +import java.util.concurrent.Phaser +import javax.annotation.PreDestroy @RestController @RequestMapping("/api/v1/execution-service") @@ -41,6 +44,8 @@ import reactor.core.publisher.Mono open class ExecutionServiceController { val log = logger(ExecutionServiceController::class) + private val ph = Phaser(1) + @Autowired lateinit var executionServiceHandler: ExecutionServiceHandler @@ -49,8 +54,7 @@ open class ExecutionServiceController { produces = [MediaType.APPLICATION_JSON_VALUE]) @ResponseBody @ApiOperation(value = "Health Check", hidden = true) - fun executionServiceControllerHealthCheck() = monoMdc { - log.info("Health check success...") + fun executionServiceControllerHealthCheck() = monoMdc(Dispatchers.IO) { "Success".asJsonPrimitive() } @@ -63,12 +67,24 @@ open class ExecutionServiceController { @PreAuthorize("hasRole('USER')") fun process(@ApiParam(value = "ExecutionServiceInput payload.", required = true) @RequestBody executionServiceInput: ExecutionServiceInput) - : Mono<ResponseEntity<ExecutionServiceOutput>> = monoMdc { + : Mono<ResponseEntity<ExecutionServiceOutput>> = monoMdc(Dispatchers.IO) { if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) { throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.") } + + ph.register() val processResult = executionServiceHandler.doProcess(executionServiceInput) + ph.arriveAndDeregister() ResponseEntity(processResult, determineHttpStatusCode(processResult.status.code)) } + + @PreDestroy + fun preDestroy() { + val name = "ExecutionServiceController" + log.info("Starting to shutdown $name waiting for in-flight requests to finish ...") + ph.arriveAndAwaitAdvance() + log.info("Done waiting in $name") + } } + |