diff options
255 files changed, 6218 insertions, 1669 deletions
diff --git a/cds-ui/application/pom.xml b/cds-ui/application/pom.xml index b773bebd3..5a8325e3a 100644 --- a/cds-ui/application/pom.xml +++ b/cds-ui/application/pom.xml @@ -18,18 +18,19 @@ 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============================================ --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ui</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <artifactId>application</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CDS UI Application</name> diff --git a/cds-ui/client/pom.xml b/cds-ui/client/pom.xml index 9cc4d2549..d2309f89d 100644 --- a/cds-ui/client/pom.xml +++ b/cds-ui/client/pom.xml @@ -18,18 +18,19 @@ 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============================================ --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ui</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <artifactId>ui-client</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CDS UI Client</name> diff --git a/cds-ui/client/src/app/common/constants/app-constants.ts b/cds-ui/client/src/app/common/constants/app-constants.ts index 1b4720c4a..30b4ece0b 100644 --- a/cds-ui/client/src/app/common/constants/app-constants.ts +++ b/cds-ui/client/src/app/common/constants/app-constants.ts @@ -119,5 +119,5 @@ export const ControllerCatalogURLs = { saveControllerCatalog: '/controllercatalog/save', getDefinition: '/controllercatalog/model-type/by-definition', getDerivedFrom: '/controllercatalog/model-type/by-derivedfrom', - deleteCatalog: '/controllercatalog/model-type' + deleteCatalog:'/controllercatalog' }
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/services/api.service.ts b/cds-ui/client/src/app/common/core/services/api.service.ts index addf51ca5..af93787fd 100644 --- a/cds-ui/client/src/app/common/core/services/api.service.ts +++ b/cds-ui/client/src/app/common/core/services/api.service.ts @@ -30,20 +30,21 @@ export class ApiService { constructor(private _http: HttpClient) { } + get(url: string, params?: any): Observable<any> { return this._http.get(url,params); } post(url: string, body: any | null, options?:any): Observable<any> { - return this._http.post(url, body,options); } + put() { // to do } - delete() { - // to do + delete(url: string, params?: any): Observable<any> { + return this._http.delete(url,params); } }
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts index 35643ee62..5ee3cb0de 100644 --- a/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts +++ b/cds-ui/client/src/app/feature-modules/blueprint/select-template/metadata/metadata.component.ts @@ -149,7 +149,7 @@ export class MetadataComponent implements OnInit { this.metadata = Object.assign({}, this.CBAMetadataForm.value); this.blueprint.metadata = this.metadata; this.filesData.forEach((fileNode) => { - if (fileNode.name.includes(this.blueprintName) && fileNode.name == this.entryDefinition) { + if (fileNode.name.includes(this.blueprintName.trim()) && fileNode.name == this.entryDefinition) { let tempNodeData = JSON.parse(fileNode.data); tempNodeData.metadata = this.blueprint.metadata; fileNode.data = JSON.stringify(tempNodeData, null, "\t"); 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 efafe5e8f..7c379599f 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 @@ -82,37 +82,20 @@ export class SearchCatalogComponent implements OnInit { }, 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(item: ICatalog, option: string) { - if(option == 'Delete'){ -// this.catalogCreateService.deleteCatalog(item.modelName) -// .subscribe(response=>{ -// this.alertService.success("Delete Success"+ response) -// }, -// error=>{ -// console.log(error); -// this.alertService.error('Error while deleting catalog'+ error); -// -// }) - } + if(option == 'Delete'){ + this.searchCatalogService.deleteCatalog(item.modelName) + .subscribe(response=>{ + this.alertService.success("Delete Success"+ response) + }, + error=>{ + console.log(error); + this.alertService.error('Error while deleting catalog'+ error); + }) + } else{ this.dialogRef = this.dialog.open(CatalogDataDialogComponent, { height: '500px', diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts index 47896058a..362eab030 100644 --- a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts @@ -33,4 +33,8 @@ export class SearchCatalogService { searchByTags(tag) { return this.api.get(ControllerCatalogURLs.searchControllerCatalogByTags + '/' + tag); } + + deleteCatalog(modelName) { + return this.api.delete(ControllerCatalogURLs.deleteCatalog + '/' + modelName); + } } diff --git a/cds-ui/designer-client/angular.json b/cds-ui/designer-client/angular.json index a84b95e39..256c35c1e 100644 --- a/cds-ui/designer-client/angular.json +++ b/cds-ui/designer-client/angular.json @@ -61,10 +61,12 @@ }, "configurations": { "production": { - "fileReplacements": [{ - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - }], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], "optimization": true, "outputHashing": "all", "sourceMap": false, @@ -74,7 +76,8 @@ "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "budgets": [{ + "budgets": [ + { "type": "initial", "maximumWarning": "2mb", "maximumError": "5mb" @@ -122,10 +125,7 @@ "./node_modules/@angular/material/prebuilt-themes/purple-green.css", "./node_modules/font-awesome/css/font-awesome.css" ], - "scripts": [ - - - ] + "scripts": [] } }, "lint": { diff --git a/cds-ui/designer-client/package-lock.json b/cds-ui/designer-client/package-lock.json index 9df5d033f..46997c4ab 100644 --- a/cds-ui/designer-client/package-lock.json +++ b/cds-ui/designer-client/package-lock.json @@ -361,6 +361,8 @@ "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { @@ -2998,6 +3000,16 @@ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", @@ -5142,6 +5154,13 @@ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fileset": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", @@ -6751,6 +6770,8 @@ "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { @@ -8015,6 +8036,13 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "dev": true, + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -8060,6 +8088,11 @@ "brace": "^0.11.1" } }, + "ngx-bootstrap": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-5.6.1.tgz", + "integrity": "sha512-8fDs3VaaWgKpupakPKS0QaUc+1E/JMBGJDxUUODjyIkLtFr1A8vH4cjXiV3AfrPvhK27GH0oyTPyKWKcCjEtVg==" + }, "ngx-file-drop": { "version": "8.0.8", "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-8.0.8.tgz", @@ -11575,6 +11608,8 @@ "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { @@ -12405,6 +12440,8 @@ "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { diff --git a/cds-ui/designer-client/package.json b/cds-ui/designer-client/package.json index ffad818c0..ec968ba7a 100644 --- a/cds-ui/designer-client/package.json +++ b/cds-ui/designer-client/package.json @@ -41,6 +41,7 @@ "lodash": "^4.17.15", "ng-sidebar": "^9.1.1", "ng2-ace-editor": "^0.3.9", + "ngx-bootstrap": "^5.6.1", "ngx-file-drop": "^8.0.8", "rxjs": "~6.4.0", "stream": "0.0.2", diff --git a/cds-ui/designer-client/pom.xml b/cds-ui/designer-client/pom.xml index 24e1d2305..0d3331d92 100644 --- a/cds-ui/designer-client/pom.xml +++ b/cds-ui/designer-client/pom.xml @@ -18,18 +18,19 @@ 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============================================ --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ui</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <artifactId>designer-client</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CDS designer Client</name> diff --git a/cds-ui/designer-client/src/app/app-routing.module.ts b/cds-ui/designer-client/src/app/app-routing.module.ts index c6e42cb0b..2610dc59f 100644 --- a/cds-ui/designer-client/src/app/app-routing.module.ts +++ b/cds-ui/designer-client/src/app/app-routing.module.ts @@ -23,7 +23,10 @@ import {NgModule} from '@angular/core'; import {Routes, RouterModule} from '@angular/router'; const routes: Routes = [ - {path: 'packages', loadChildren: './modules/feature-modules/packages/packages.module#PackagesModule'}, + {path: 'packages', + loadChildren: './modules/feature-modules/packages/packages.module#PackagesModule'}, + {path: 'resource-dictionary', + loadChildren: './modules/feature-modules/resource-dictionary/resource-dictionary.module#ResourceDictionaryModule'}, // { path: '', component: MainAppComponent }, { path: '', diff --git a/cds-ui/designer-client/src/app/app.module.ts b/cds-ui/designer-client/src/app/app.module.ts index 9817edf70..da7ddfbd0 100644 --- a/cds-ui/designer-client/src/app/app.module.ts +++ b/cds-ui/designer-client/src/app/app.module.ts @@ -1,4 +1,3 @@ - /* ============LICENSE_START========================================== =================================================================== @@ -31,9 +30,11 @@ import {MatTabsModule} from '@angular/material/tabs'; import {ApiService} from './common/core/services/api.service'; import {HttpClientModule} from '@angular/common/http'; import {PackagesModule} from './modules/feature-modules/packages/packages.module'; -import { SidebarModule } from 'ng-sidebar'; +import {SidebarModule} from 'ng-sidebar'; import {SharedModulesModule} from './modules/shared-modules/shared-modules.module'; -import { NgxFileDropModule } from 'ngx-file-drop'; +import {NgxFileDropModule} from 'ngx-file-drop'; +import {ResourceDictionaryModule} from './modules/feature-modules/resource-dictionary/resource-dictionary.module'; + @NgModule({ declarations: [ @@ -50,6 +51,8 @@ import { NgxFileDropModule } from 'ngx-file-drop'; PackagesModule, SharedModulesModule, NgxFileDropModule, + ResourceDictionaryModule, + SidebarModule, ], providers: [ApiService], diff --git a/cds-ui/designer-client/src/app/common/constants/app-constants.ts b/cds-ui/designer-client/src/app/common/constants/app-constants.ts index 14cb001c8..e29748535 100644 --- a/cds-ui/designer-client/src/app/common/constants/app-constants.ts +++ b/cds-ui/designer-client/src/app/common/constants/app-constants.ts @@ -109,7 +109,10 @@ export const ResourceDictionaryURLs = { searchResourceDictionaryByNames: '/resourcedictionary/search/by-names', getSources: '/resourcedictionary/source-mapping', getModelType: '/resourcedictionary/model-type', - getResourceDictionary: '/resourcedictionary/model-type/by-definition' + getResourceDictionary: '/resourcedictionary/model-type/by-definition', + getMetaDatePageable: '/resourcedictionary/metadata/paged', + getDictionaryByName: '/resourcedictionary/by-name/', + getPagedDictionary: '/resourcedictionary/paged', }; export const ControllerCatalogURLs = { diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html index df1911a7d..6c7e1efc6 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html @@ -7,70 +7,112 @@ <h2 class="col m-0"> <ul class="breadcrumb-header"> <li><a routerLink="/packages">CBA Packages</a></li> + <i class="fa fa-angle-right ml-2 mr-2"></i> <li>Package Name</li> </ul> </h2> - <div class="col d-flex justify-content-end header-button-save"> - <button class="float btn btn-sm btn-outline-secondary" (click)="goBacktoDashboard()">Discard - Changes</button> - <button class="float btn btn-sm btn-primary" (click)="editBluePrint()">Apply Changes</button> + <div class="col"> </div> </div> </header> - <div class="container-fluid body-container"> <div class="container"> - <!-- <div class="creat-action-container"> + <div class="creat-action-container"> + + <a href="#" class="action-button save" (click)="editBluePrint()"> + <i class="icon-save-sm" aria-hidden="true"></i> + <span>Save</span> + </a> + <a href="#" class="action-button" (click)="goBacktoDashboard()"> + <i class="icon-discard-sm" aria-hidden="true"></i> + <span>Discard Changes</span> + </a> + + <hr> <a href="#" class="action-button"> - <i class="icon-clone" aria-hidden="true"></i> + <i class="icon-clone-sm" aria-hidden="true"></i> <span>Clone</span> </a> <a href="#" class="action-button"> - <i class="icon-archive" aria-hidden="true"></i> + <i class="icon-archive-sm" aria-hidden="true"></i> <span>Archive</span> </a> - <a href="#" class="action-button delete"> - <i class="icon-delete" aria-hidden="true"></i> + <a class="action-button" + (click)="downloadPackage(viewedPackage.artifactName,viewedPackage.artifactVersion)"> + <i class="icon-download" aria-hidden="true"></i> + <span>Download</span> + </a> + + <a class="action-button delete"> + <i class="icon-delete-sm" aria-hidden="true"></i> <span>Delete</span> </a> - </div>--> + </div> <div class="card creat-card view-package-container"> <div class="row"> - <div class="col-8"> - <div class="row"> - <div class="col d-flex"> - <i class="package-type-icon icon-designer-mode"></i> - <div class="package-name-container"> - <div class="row"> - <div class="col-12 package-name deployed"> - {{viewedPackage.artifactName}} - <span>.vLB.CDS</span> - <i class="icon-deploy"></i> - </div> - <div class="col-12 package-description"> - Last modified {{ viewedPackage.createdDate | date:'short' }} By - {{viewedPackage.updatedBy}} - </div> - </div> - - </div> + <div class="col-1 text-center"><i class="package-type-icon icon-topologyView-active"></i></div> + <div class="col-9"> + <div class="row mb-4"> + <div class="col-12 package-name deployed"> + {{viewedPackage.artifactName}} + <img src="/assets/img/icon-deploy-inactive.svg" class="deply-status-icon"> + <span class="package-version">Version 1.0.2</span> + </div> + <div class="col-12 package-description"> + Last modified {{ viewedPackage.createdDate | date:'short' }} By + {{viewedPackage.updatedBy}} + </div> + </div> + <div class="row package-auth-info"> + <div class="col-3"> + <p><b>Author Name</b></p> + <span>Shaaban Ebrahim</span> + </div> + <div class="col-4"> + <p><b>Author Email</b></p> + <span>shaaban.eltanany.ext@orange.com</span> + </div> + <div class="col-5"> + <p><b>Contributions</b></p> + <ul class="package-contributers"> + <li> + <button type="button" class="border-fade" data-toggle="tooltip" + data-placement="bottom" title="User name"> + <img src="/assets/img/img-user1.jpeg"> + </button> + </li> + <li> + <button type="button" data-toggle="tooltip" data-placement="bottom" + title="User name"> + <img src="/assets/img/img-user2.jpg"> + </button> + </li> + <li> + <button type="button" data-toggle="tooltip" data-placement="bottom" + title="User name"> + <img src="/assets/img/img-user3.jpg"> + </button> + </li> + <li> + <a href="">5 contributors</a> + </li> + </ul> </div> </div> </div> - <div class="col-4 package-view-button"> + <div class="col-2 package-view-button pt-3"> + <button class="btn btn-sm btn-primary mb-2" (click)="goToDesignerMode()">Designer + Mode + </button> <button class="btn btn-sm btn-outline-secondary" (click)="deployCurrentPackage()"><i - class="fa fa-play-circle"></i> Deploy</button> - <button class="btn btn-sm btn-outline-secondary" - (click)="downloadPackage(viewedPackage.artifactName,viewedPackage.artifactVersion)"><i - class="fa"></i> Download</button> - - <button class="btn btn-sm btn-primary" (click)="goToDesignerMode()">Designer Mode</button> + class="fa fa-play-circle"></i> Deploy + </button> </div> </div> @@ -80,18 +122,18 @@ <!--Nav Tabs--> <div class="col"> <div class="nav nav-tabs " id="nav-tab" role="tablist"> - <a class="nav-item nav-link active" id="nav-metadata-tab" data-toggle="tab" - href="#nav-metadata" role="tab" aria-controls="nav-metadata" aria-selected="true" - autofocus #nameit (focusout)="saveMetaData()">METADATA</a> + <a class="nav-item nav-link active complete" id="nav-metadata-tab" data-toggle="tab" + href="#nav-metadata" role="tab" aria-controls="nav-metadata" aria-selected="true" + autofocus #nameit (focusout)="saveMetaData()">METADATA</a> <a class="nav-item nav-link" id="nav-template-tab" data-toggle="tab" href="#nav-template" - role="tab" aria-controls="nav-template" aria-selected="false">TEMPLATE & MAPPING</a> + role="tab" aria-controls="nav-template" aria-selected="false">TEMPLATE & MAPPING</a> <a class="nav-item nav-link" id="nav-scripts-tab" data-toggle="tab" href="#nav-scripts" - role="tab" aria-controls="nav-scripts" aria-selected="false">SCRIPTS</a> + role="tab" aria-controls="nav-scripts" aria-selected="false">SCRIPTS</a> <a class="nav-item nav-link" id="nav-imports-tab" data-toggle="tab" href="#nav-imports" - role="tab" aria-controls="nav-imports" aria-selected="false">IMPORTS</a> + role="tab" aria-controls="nav-imports" aria-selected="false">DEFINITIONS</a> <a class="nav-item nav-link" id="nav-authentication-tab" data-toggle="tab" - href="#nav-authentication" role="tab" aria-controls="nav-authentication" - aria-selected="false">EXTERNAL SYSTEM AUTHENTICATION PROPERTIES</a> + href="#nav-authentication" role="tab" aria-controls="nav-authentication" + aria-selected="false">EXTERNAL SYSTEM AUTHENTICATION PROPERTIES</a> </div> </div> @@ -100,24 +142,24 @@ <div class="col"> <div class="tab-content" id="nav-tabContent"> <div class="tab-pane fade show active" id="nav-metadata" role="tabpanel" - aria-labelledby="nav-metadata-tab"> + aria-labelledby="nav-metadata-tab"> <app-metadata-tab></app-metadata-tab> </div> <div class="tab-pane fade" id="nav-template" role="tabpanel" - aria-labelledby="nav-template-tab"> + aria-labelledby="nav-template-tab"> <app-template-mapping></app-template-mapping> </div> <div class="tab-pane fade" id="nav-scripts" role="tabpanel" - aria-labelledby="nav-scripts-tab"> + aria-labelledby="nav-scripts-tab"> <app-scripts-tab></app-scripts-tab> </div> <div class="tab-pane fade" id="nav-imports" role="tabpanel" - aria-labelledby="nav-imports-tab"> + aria-labelledby="nav-imports-tab"> <app-imports-tab></app-imports-tab> </div> <div class="tab-pane fade" id="nav-authentication" role="tabpanel" - aria-labelledby="nav-authentication-tab"> + aria-labelledby="nav-authentication-tab"> <div class="card creat-card"> <div class="editor-container"> <app-dsl-definitions-tab></app-dsl-definitions-tab> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css index 37a6f9235..04f410c5f 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css @@ -4,12 +4,21 @@ body{ background-size: 6px 6px !important; } +/*Icons*/ +.icon-info{ + margin-left: 3px; +} +.icon-info::before{ + color: #fff; +} /*Header*/ header{ + position: relative; height: 60px; background-color: #1B3E6F; box-shadow: 0 4px 10px rgba(238, 240, 245, 1.0); + z-index: 200000000 !important; } .logo{ float: left; @@ -43,9 +52,13 @@ header{ padding: 4px 10px; background: #F4F9FE; border-radius: 10px; - color: #C3CDDB; + color: #1B3E6F; font-size: 10px; } +.designer-breadcrumb .fa-angle-right::before { + color: #fff; + line-height: 38px; +} .sidebar-container{ height: calc(100vh - 60px) !important; } @@ -68,7 +81,7 @@ header{ .btn-topology-action, .btn-topology-action:hover{ margin: 0 6px; - padding: 6px 10px; + padding: 4px 8px; color: #fff; border-radius: 50%; border: solid .5px #fff; @@ -97,13 +110,15 @@ header{ .topology-actions .dropdown-text::after{ right: 15px; top: 13px; - border-width: 6px 6px 0 6px; + border-style: solid !important; + border-width: 5px 5px 0 5px !important; border-color: #fff transparent transparent transparent; } .topology-actions .dropdown-toggle:focus ~ .dropdown-text::after{ top: 13px; - border-width: 0 6px 6px 6px; - border-color: transparent transparent #fff transparent + border-style: solid !important; + border-width: 0 5px 5px 5px !important; + border-color: transparent transparent #fff transparent; } .topology-actions .dropdown-content:hover, .topology-actions .dropdown-toggle:focus ~ .dropdown-content{ @@ -123,9 +138,35 @@ header{ background: #F4F9FE; text-decoration: none; } - - - +.package-info-btn{ + padding: 0 !important; +} +.package-info h3{ + font-size: 15px; + font-weight: bold; +} +.package-info h3 span{ + font-size: 11px; +} +.package-info .badge{ + margin-right: 6px; + padding: 4px 10px; + background: #E0E8F2; + border-radius: 12px; + color: #1B3E6F; + font-size: 11px; + font-weight: normal; +} +.creator-pic{ + border-radius: 50%; + width: 30px; + height: 30px; +} +.package-info p{ + margin-bottom: 0; + font-size: 11px; + line-height: 20px; +} @@ -179,7 +220,24 @@ button.rotate{ .rotate a:hover{ text-decoration: none; } - +#board-paper svg{ + top: 40px; + left: 30px; +} +.componentsList tspan{ + width:60px !important; + font: normal 13px sans-serif; + fill: #1B3E6F !important; + overflow-wrap: break-word; +} +#board-paper #name tspan{ + /* fill: green; */ + text-align: center; + +} +tspan#type{ + text-align: center; +} /*ACTIONS & COMPONENTS MENU*/ .input-search-controller{ height: 50px; @@ -252,6 +310,8 @@ p.compType-4{ color: #C3CDDB; } .controllerSidebar b{ + margin-left: 12px; + margin-bottom: 9px; font-size: 12px; color: #C3CDDB; } @@ -261,17 +321,17 @@ p.compType-4{ border-radius: 2px !important; font-size: 12px; font-weight: bold; + outline: 0 !important; } -.actionBtns .btn:first-child{ +.actionBtns .btn.insert-custom{ background: #1B3E6F; border: solid 1px #1B3E6F; color: #fff; } -.actionBtns .btn:last-child{ - padding-left: 34px !important; - background: url(src/assets/img/icon-import-blue.svg) 12px center #fff no-repeat; +.actionBtns .btn.import-action{ border: solid 1px #D0DFF1; color: #1B3E6F; + } .actionsList, .componentsList{ @@ -281,6 +341,7 @@ p.compType-4{ padding-bottom: 0; height: calc( 100vh - 218px)!important; overflow: scroll; + background: #F4F9FE !important; } .custom-control.custom-checkbox:hover, .custom-control-label:hover{ @@ -553,7 +614,7 @@ p.compType-4{ .source-button{ position: absolute; z-index: 9999999; - top: 69px; + top: 60px; left: 50%; } /*jointjs paper*/ diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html index 1a2219bab..6e072b18d 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html @@ -4,17 +4,61 @@ <div class="col pl-0"> <p class="logo mb-0"></p> <nav aria-label="breadcrumb"> - <ol class="breadcrumb mb-0"> + <ol class="breadcrumb designer-breadcrumb mb-0"> <li class="breadcrumb-item"> <a href="#">CBA Packages</a> </li> + <i class="fa fa-angle-right ml-2 mr-2"></i> <li class="breadcrumb-item"> <a href="#">Package Name</a> + <button type="button" class="btn package-info-btn" data-toggle="modal" + data-target="#exampleModalLong"> + <i class="icon-info" aria-hidden="true"></i> + </button> </li> + <i class="fa fa-angle-right ml-2 mr-2"></i> <li class="breadcrumb-item active" aria-current="page"> - <p class="mb-0">Topology View</p> + <p class="mb-0">Designer Mode</p> </li> </ol> + <div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog" + aria-labelledby="exampleModalLongTitle" aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalLongTitle">Package Details</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <img src="assets/img/icon-close.svg" /> + </button> + </div> + <div class="modal-body"> + <div class="row package-info"> + <div class="col-12"> + <h3>Test Package + <span class="package-version">Version 1.0.2</span></h3> + </div> + <div class="col-12 mb-3"> + <span class="badge badge-primary">test</span> + <span class="badge badge-primary">vDNS-CDS</span> + <span class="badge badge-primary">SCALE-OUT</span> + <span class="badge badge-primary">MARCO</span> + </div> + <div class="col-2"> + <img src="/assets/img/img-user3.jpg" class="creator-pic"> + </div> + <div class="col-10 pl-0"> + <p><b>Author information:</b></p> + <p>Abdelmuhaimen Seaudi</p> + <p>abdelmuhaimen.seaudi@orange.com</p> + </div> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + </div> + </div> + </div> + </div> </nav> </div> <div class="col pr-0 text-right"> @@ -22,15 +66,15 @@ <li> <div class="btn-group" role="group" aria-label="Basic example"> <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" - data-tooltip="Preview"> + data-tooltip="Preview"> <i class="fa fa-eye"></i> </a> <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" - data-tooltip="Download"> + data-tooltip="Download"> <i class="fa fa-download"></i> </a> <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" - data-tooltip="Share"> + data-tooltip="Share"> <i class="fa fa-share-square"></i> </a> </div> @@ -58,24 +102,53 @@ <div class="source-button editBar"> <div class="btn-group viewBtns" role="group"> <button type="button" class="btn btn-secondary topologySource active">Designer</button> - <button [routerLink]="['/designer/source']" type="button" class="btn btn-secondary topologyView">Scripting</button> + <button [routerLink]="['/designer/source']" type="button" + class="btn btn-secondary topologyView">Scripting</button> </div> </div> <ng-sidebar-container class="sidebar-container"> <!-- Controller SideBar --> <ng-sidebar [(opened)]="controllerSideBar" [sidebarClass]="'demo-sidebar controllerSidebar container-fluid'" - [mode]="'push'" - #sidebarLeft> - <div class="row"> - - <h1 class="col-12">Actions</h1> - <div class="col-12 text-center p-0"> - <div class="btn-group actionBtns" role="group"> - <button (click)="insertCustomActionIntoBoard()" type="button" class="btn">Insert Custom</button> - <!-- <button type="button" class="btn">Import Action</button> --> + [mode]="'push'" #sidebarLeft> + + <nav class="row"> + <!--Nav Tabs--> + <div class="col-12"> + <div class="nav nav-tabs " id="nav-tab" role="tablist"> + <a class="nav-item nav-link active col-6" id="nav-action-tab" data-toggle="tab" + href="#nav-action" role="tab" aria-controls="nav-action" aria-selected="false" + autofocus #nameit >Actions</a> + <a class="nav-item nav-link col-6" id="nav-function-tab" data-toggle="tab" + href="#nav-function" role="tab" aria-controls="nav-function" aria-selected="false">Functions</a> </div> </div> - <!-- <div class="col-12 actionsList"> + </nav> + + + <div class="row mt-2"> + <div class="col"> + <div class="tab-content" id="nav-tabContent"> + <div class="tab-pane fade show active" id="nav-action" role="tabpanel" + aria-labelledby="nav-action-tab"> + <div class="btn-group actionBtns col-8" role="group"> + <button (click)="insertCustomActionIntoBoard()" type="button" class="btn insert-custom"> + Insert Custom + </button> + <!-- <button type="button" class="btn import-action"><i class="icon-import-blue" aria-hidden="true"></i>Import Action</button> --> + </div> + </div> + <div class="tab-pane fade" id="nav-function" role="tabpanel" + aria-labelledby="nav-function-tab"> + <div class="col-12 text-center p-0"> + <b>Drag and drop function to Action’s box</b> + <div id="palette-paper" class="col-12 componentsList"> </div> + </div> + </div> + </div> + </div> + </div> + + <!-- <div class="col-12 actionsList"> <b>Select from other packages:</b> <div class="actions-scroll"> <div class="custom-control custom-checkbox"> @@ -109,22 +182,18 @@ </div> </div> --> - <h1 class="col-12">Functions</h1> - <b>Drag and drop function to Action’s box</b> - <div id="palette-paper" class="col-12 componentsList"> - </div> - </div> + </ng-sidebar> <!-- Page content --> - + <div ng-sidebar-content id="board-paper"> <button class="rotate" (click)="_toggleSidebar1()"> - <span> - Controller - <i class="fa fa-angle-double-left"></i> - </span> + <span> + Controller + <i class="fa fa-angle-double-left"></i> + </span> </button> - + <!-- Canvas --> <div class="editBar text-center"> <div class="btn-group mr-2" role="group" aria-label="First group"> @@ -180,8 +249,7 @@ </div> <!-- Attribute SideBar --> <ng-sidebar [(opened)]="attributesSideBar" [sidebarClass]="'demo-sidebar attributesSideBar '" [mode]="'push'" - [position]="'right'" - #sidebarRight> + [position]="'right'" #sidebarRight> <div class="container-fluid0"> <div class="row m-0"> <div class="col-2 pr-0"> @@ -203,8 +271,7 @@ <div class="card-header row" id="headingOne"> <h2 class="col-10 mb-0"> <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseOne" aria-expanded="true" - aria-controls="collapseOne"> + data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> Steps </button> </h2> @@ -214,7 +281,7 @@ </div> <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" - data-parent="#accordionExample"> + data-parent="#accordionExample"> <div class="card-body"> <div class="row"> <div class="col-9"> @@ -234,7 +301,7 @@ <div class="form-group"> <label for="exampleFormControlTextarea1">Description</label> <textarea class="form-control" id="exampleFormControlTextarea1" - rows="3"></textarea> + rows="3"></textarea> </div> <div class="form-group"> <label for="exampleInputEmail1">Target</label> @@ -248,8 +315,7 @@ <div class="card-header row" id="headingTwo"> <h2 class="col-10 mb-0"> <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseTwo" aria-expanded="true" - aria-controls="collapseTwo"> + data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo"> Inputs </button> </h2> @@ -258,7 +324,7 @@ </div> </div> <div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo" - data-parent="#accordionExample"> + data-parent="#accordionExample"> <div class="card-body"> <div class="row"> <div class="col-9"> @@ -278,7 +344,7 @@ <div class="form-group"> <label for="exampleFormControlTextarea1">Description</label> <textarea class="form-control" id="exampleFormControlTextarea1" - rows="3"></textarea> + rows="3"></textarea> </div> <div class="form-group"> <label for="exampleInputEmail1">Target</label> @@ -292,8 +358,8 @@ <div class="card-header row" id="headingThree"> <h2 class="col-10 mb-0"> <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseThree" aria-expanded="true" - aria-controls="collapseThree"> + data-target="#collapseThree" aria-expanded="true" + aria-controls="collapseThree"> Outputs </button> </h2> @@ -302,7 +368,7 @@ </div> </div> <div id="collapseThree" class="collapse show" aria-labelledby="headingThree" - data-parent="#accordionExample"> + data-parent="#accordionExample"> <div class="card-body"> <div class="row"> <div class="col-9"> @@ -322,7 +388,7 @@ <div class="form-group"> <label for="exampleFormControlTextarea1">Description</label> <textarea class="form-control" id="exampleFormControlTextarea1" - rows="3"></textarea> + rows="3"></textarea> </div> <div class="form-group"> <label for="exampleInputEmail1">Target</label> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/board.function.element.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/board.function.element.ts index 42813075c..72019bfa0 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/board.function.element.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/board.function.element.ts @@ -28,9 +28,9 @@ const FunctionElement = joint.shapes.standard.Rectangle.define('board.FunctionEl <g id="func-board-element-conponent" transform="translate(30.000000, 70.000000)"> <g id="execute" transform="translate(304.000000, 0.000000)"> <g id="Group" transform="translate(7.000000, 0.000000)"> - <rect id="func-board-element-rectangle" fill="#1B3E6F" x="0" y="0" width="230" height="130" rx="2"></rect> - <g id="Group-4" transform="translate(36.000000, 25.000000)" fill="#FFFFFF"> - <g id="database0-copy" transform="translate(61.000000, 0.000000)" fill-rule="nonzero"> + <rect id="func-board-element-rectangle" fill="#1B3E6F" x="15" y="0" width="330" height="84" rx="2"></rect> + <g id="Group-4" transform="translate(20.000000, 20.000000)" fill="#FFFFFF"> + <g id="database0-copy" transform="translate(15.000000, 0.000000)" fill-rule="nonzero"> <path d="M35.544,6.00705882 C34.7265882, 2.97882353 28.6425882,0 18,0 C7.35741176, 0 1.27270588,2.97882353 0.456,6.00705882 C0.396705882, @@ -302,11 +302,10 @@ const FunctionElement = joint.shapes.standard.Rectangle.define('board.FunctionEl </g> <text id="func-board-element-text" font-family="HelveticaNeue-Bold, Helvetica Neue" - font-size="14" + font-size="13" font-weight="bold" line-spacing="18"> - <tspan id="label" x="52.554" y="59">execute</tspan> - <tspan x="105.446" y="59" font-family="HelveticaNeue, Helvetica Neue" font-weight="normal"></tspan> - <tspan id="type" x="0.094" y="77" + <tspan id="label" x="64" y="18">execute</tspan> + <tspan id="type" x="64" y="40" font-family="HelveticaNeue, Helvetica Neue" font-size="12" font-weight="normal"></tspan> </text> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/palette.function.element.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/palette.function.element.ts index 896ecaa88..48a680982 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/palette.function.element.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/palette.function.element.ts @@ -34,7 +34,7 @@ const FunctionElement = joint.shapes.standard.Rectangle.define('palette.Function }, { markup: `<defs> - <rect id="pallete-function-rect" x="0" y="0" width="280" height="40" rx="2"></rect> + <rect id="pallete-function-rect" x="0" y="0" width="290" height="40" rx="2"></rect> <filter x="-3.6%" y="-20.0%" width="107.1%" height="150.0%" filterUnits="objectBoundingBox" id="filter-2"> <feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="3" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> @@ -53,7 +53,7 @@ const FunctionElement = joint.shapes.standard.Rectangle.define('palette.Function <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#pallete-function-rect"></use> <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#pallete-function-rect"></use> </g> - <g id="drag-menu" transform="translate(20.000000, 15.000000)" fill="#C3CDDB" fill-rule="nonzero"> + <g id="drag-menu" transform="translate(15.000000, 15.000000)" fill="#C3CDDB" fill-rule="nonzero"> <g id="left"> <circle id="1" cx="0.8" cy="0.8" r="1"></circle> <circle id="2" cx="0.8" cy="3.8" r="1"></circle> @@ -67,7 +67,7 @@ const FunctionElement = joint.shapes.standard.Rectangle.define('palette.Function <circle id="4" cx="0.8" cy="9.8" r="1"></circle> </g> </g> - <g id="txt" transform="translate(35.000000, 10.000000)" fill="#1B3E6F"> + <g id="txt" transform="translate(30.000000, 10.000000)" fill="#1B3E6F"> <g id="browser" fill-rule="nonzero"> <path d="M21.0000051,0.39034364 C20.9994786, 0.29701568 20.9615913,0.207858845 20.8946802, @@ -254,7 +254,7 @@ const FunctionElement = joint.shapes.standard.Rectangle.define('palette.Function id="Shape"></path> </g> <text id="function-type" font-family="ArialMT, Arial" font-size="14" font-weight="normal" line-spacing="20"> - <tspan id="label" x="32" y="13"></tspan> + <tspan id="label" x="30" y="13"></tspan> </text> </g> </g> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/source-view/source-view.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/source-view/source-view.component.css index 01ae599a4..75274ba33 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/source-view/source-view.component.css +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/source-view/source-view.component.css @@ -49,6 +49,9 @@ header{ color: #C3CDDB; font-size: 10px; } +.designer-breadcrumb .fa-angle-right::before{ + color: #fff; +} .sidebar-container{ height: calc(100vh - 60px) !important; } @@ -255,6 +258,7 @@ p.compType-4{ color: #C3CDDB; } .controllerSidebar b{ + margin-left: 12px; font-size: 12px; color: #C3CDDB; } @@ -272,9 +276,9 @@ p.compType-4{ } .actionBtns .btn:last-child{ padding-left: 34px !important; - background: url(src/assets/img/icon-import-blue.svg) 12px center #fff no-repeat; border: solid 1px #D0DFF1; color: #1B3E6F; + outline: 0 !important; } .actionsList, .componentsList{ diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts index e1efc3c22..00dcc5dab 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts @@ -1,8 +1,8 @@ -import { PackageCreationModes } from './PackageCreationModes'; -import { CBAPackage, Scripts } from '../mapping-models/CBAPacakge.model'; -import { FilesContent } from '../mapping-models/metadata/MetaDataTab.model'; -import { Import, Metadata, VlbDefinition } from '../mapping-models/definitions/VlbDefinition'; -import { PackageCreationUtils } from '../package-creation.utils'; +import {PackageCreationModes} from './PackageCreationModes'; +import {CBAPackage, Scripts} from '../mapping-models/CBAPacakge.model'; +import {FilesContent} from '../mapping-models/metadata/MetaDataTab.model'; +import {Import, Metadata, VlbDefinition} from '../mapping-models/definitions/VlbDefinition'; +import {PackageCreationUtils} from '../package-creation.utils'; export class DesignerCreationMode extends PackageCreationModes { @@ -41,7 +41,7 @@ export class DesignerCreationMode extends PackageCreationModes { FilesContent.putData(key, valueOfFile); }); - const filenameEntry = 'Definitions/blueprint.json'; + const filenameEntry = 'Definitions/' + cbaPackage.metaData.name + '.json'; const vlbDefinition: VlbDefinition = new VlbDefinition(); const metadata: Metadata = new Metadata(); @@ -68,7 +68,7 @@ export class DesignerCreationMode extends PackageCreationModes { vlbDefinition.metadata = metadata; const files: Import[] = []; cbaPackage.definitions.imports.forEach((valueOfFile, key) => { - files.push({ file: key }); + files.push({file: key}); }); console.log(vlbDefinition); vlbDefinition.imports = files; diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts index 8ccf0c39e..5b8db6b6d 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts @@ -11,7 +11,7 @@ export abstract class PackageCreationModes { public static setEntryPoint(metaDataTab: MetaDataTabModel) { if (metaDataTab.mode.startsWith(ModeType.Designer)) { - metaDataTab.entryFileName = 'Definitions/blueprint.json'; + metaDataTab.entryFileName = 'Definitions/' + metaDataTab.name + '.json'; } else { // TODO Not implemented metaDataTab.entryFileName = ''; diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/dsl-definitions-tab/dsl-definitions-tab.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/dsl-definitions-tab/dsl-definitions-tab.component.html index a67d12bcf..2c0400a63 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/dsl-definitions-tab/dsl-definitions-tab.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/dsl-definitions-tab/dsl-definitions-tab.component.html @@ -1,3 +1,8 @@ +<ul class="defintionsNote"> + <li><b>To add new property: </b></li> + <li>1. Use Copy and paste option or</li> + <li>2. Write them manually </li> +</ul> <ace-editor [(text)]="dslDefinition.content" [mode]="'javascript'" [autoUpdateContent]="true" [durationBeforeCallback]="1000" (textChanged)="textChanged($event)" [theme]="'tomorrow_night_bright'" #editor style="height:300px;"> </ace-editor> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.html index d80ed16b2..ac02c50e2 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.html @@ -1,20 +1,20 @@ <div class="import-container-all"> <div class="import-container"> <div class="import-container-input"> - <input placeholder="Enter file URL" type="input" class="ng-pristine ng-valid ng-touched"> - <a class="enter-link" href="#"><i class="icon-enter"></i></a> + <input placeholder="Enter file URL then ENTER" type="input" class="ng-pristine ng-valid ng-touched"> + <a class="enter-link" href="#"><i class="icon-enter-link"></i></a> </div> <span class="import-container-span">Or you can also <a href="#" data-toggle="modal" - data-target="#importModal">Import File</a></span> + (click)="resetTheUploadedFiles()" data-target="#importModal"><b>Import File</b></a></span> </div> <div class="accordion"> - <div class="card creat-card"> + <!-- <div class="card creat-card"> <div class="single-line"> <label class="label-name">File</label> </div> - </div> + </div> --> <div id="accordion" *ngFor="let file of definitionFiles | keyvalue; let mapIndex = index"> <!-- <div class="card"> <div class="card-header" [id]="file.key"> @@ -23,7 +23,7 @@ aria-expanded="true" aria-controls="collapseOne"> <i class="icon-file-code"></i> Definitions/{{file.key}} </button> - <a class="accordion-delete" href="#"><i class="icon-delete"></i></a> + <a class="accordion-delete" href="#"><i class="icon-delete-sm"></i></a> </h5> </div> @@ -36,20 +36,46 @@ <div class="card"> <div class="card-header" [id]="'head-'+mapIndex"> <h5 class="mb-0 d-flex justify-content-between"> - <button class="btn btn-link collapsed" data-toggle="collapse" - [attr.data-target]="'#id-'+mapIndex" aria-expanded="false" - [attr.aria-controls]="'id-'+mapIndex"> + <button class="btn btn-link " data-toggle="collapse" + aria-expanded="false" + (click)="changeDivShow(mapIndex)" > <i class="icon-file-code"></i> {{file.key}} </button> - <a class="accordion-delete" (click)="removeFile(mapIndex)"><i class="icon-delete"></i></a> + + <a data-toggle="modal" data-target="#exampleModal" class="accordion-delete"><i + class="icon-delete-sm"></i></a> + + <!-- <a class="accordion-delete" (click)="removeFile(mapIndex)"><i class="icon-delete-sm"></i></a> --> + <!-- Delete Modal --> + <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" + aria-labelledby="exampleModalLabel" aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalLabel">Delete File</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <p>Are you sure you want to delete file <span>artifact_types.json</span>?</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" + data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary">Delete</button> + </div> + </div> + </div> + </div> </h5> </div> <div [id]="'id-'+mapIndex" class="collapse" [attr.aria-labelledby]="'head-'+mapIndex" data-parent="#accordion"> <div class="card-body"> - <ace-editor [(text)]="file.value" (textChange)="textChanges($event,file.key)" [mode]="'json'" [autoUpdateContent]="true" - [durationBeforeCallback]="1000" [theme]="'tomorrow_night_bright'" #editor - style="height:300px;"> + <ace-editor [(text)]="file.value" (textChange)="textChanges($event,file.key)" [mode]="'json'" + [autoUpdateContent]="true" [durationBeforeCallback]="1000" [theme]="'tomorrow_night_bright'" + #editor style="height:300px;"> </ace-editor> </div> </div> @@ -89,7 +115,8 @@ <div class="modal-header"> <h5 class="modal-title" id="importModalLabel">Import File</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> - <span aria-hidden="true">×</span> + <!-- <span aria-hidden="true">×</span> --> + <img src="assets/img/icon-close.svg" /> </button> </div> <div class="modal-body"> @@ -110,11 +137,13 @@ <div class="folder-upload-type">Allowed file type: json</div> </ng-template> </ngx-file-drop> - <div class="upload-table" *ngFor="let item of uploadedFiles; let i=index"> + <div class="upload-table"> <table class="table"> <thead> - <tr> - <th>Name : {{ item.name }}</th> + <tr *ngFor="let item of uploadedFiles; let i=index"> + <th width="40"><img src="assets/img/icon-file-code.svg" /></th> + <th>{{ item.name }}</th> + <th width="40" class="text-right"><img src="assets/img/icon-remove-file.svg" /></th> </tr> </thead> </table> @@ -130,4 +159,4 @@ </div> </div> </div> -</div> +</div>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.ts index dc0cf7f3b..35c0918de 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/imports-tab/imports-tab.component.ts @@ -1,7 +1,7 @@ -import { Component, OnInit } from '@angular/core'; -import { FileSystemFileEntry, NgxFileDropEntry } from 'ngx-file-drop'; -import { PackageCreationStore } from '../package-creation.store'; -import { PackageCreationUtils } from '../package-creation.utils'; +import {Component, OnInit} from '@angular/core'; +import {FileSystemFileEntry, NgxFileDropEntry} from 'ngx-file-drop'; +import {PackageCreationStore} from '../package-creation.store'; +import {PackageCreationUtils} from '../package-creation.utils'; @Component({ @@ -76,4 +76,14 @@ export class ImportsTabComponent implements OnInit { textChanges(code: any, key: string) { this.packageCreationStore.addDefinition(key, code); } + + changeDivShow(mapIndex: number) { + const divElement = document.getElementById('id-' + mapIndex) as HTMLElement; + if (divElement.getAttribute('class').includes('show')) { + divElement.setAttribute('class', 'collapse'); + } else { + divElement.setAttribute('class', 'collapse show'); + } + console.log(divElement.getAttribute('class')); + } } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.html index 89724be79..6622f6700 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.html @@ -1,20 +1,23 @@ <div class="card creat-card"> - <div class="single-line"> + <div class="single-line-model"> <label class="label-name">Mode</label> - <label name="trst" *ngFor="let mode of modes; let i = index"> - <input class="form-check-input" [(ngModel)]="modeType" type="radio" name="radioMode" id="radioMode" - [value]="mode.name"> + <div class="label-input"> + <label name="trst" *ngFor="let mode of modes; let i = index" class="pl-0"> + <input class="form-check-input" [(ngModel)]="modeType" type="radio" name="radioMode" id="radioMode" + [value]="mode.name"> - <span> - <i [className]="mode.style" aria-hidden="true" [id]="mode.name"></i> - {{mode.name}} - </span> - </label> + <span> + <i [className]="mode.style" aria-hidden="true" [id]="mode.name"></i> + {{mode.name}} + </span> + </label> + </div> </div> <div class="single-line"> <label class="label-name">Dictionary Library Instance</label> <div class="label-input"> <select class="form-control" id="exampleFormControlSelect1"> + <option>Select Library Instance</option> <option>Library Instance 1</option> <option>Library Instance 2</option> <option>Library Instance 3</option> @@ -30,7 +33,7 @@ <label class="label-name">Name <span>*</span></label> <div class="label-input"> <input type="input" [readOnly]="!packageNameAndVersionEnables" [(ngModel)]="metaDataTab.name" - placeholder="Topology name.vLB.CDS"> + placeholder="Package name"> </div> <!--<div class="model-note-container error-message"> Package name already exists with this version. Please enter a different name or enter different version @@ -54,31 +57,32 @@ </div> <div class="single-line-model"> - <label class="label-name">tags</label> + <label class="label-name">Tags</label> <div class="label-input"> <input type="input" (keyup.enter)="addTag($event)" [(ngModel)]="metaDataTab.tags" placeholder="Ex., vDNS-CDS"> - </div> - <div class="model-note-container tag-notes">Seprate tags with comma or space</div> + <div class="model-note-container tag-notes">Use ENTER to add tag</div> <div class="model-note-container tages-container"> - <span *ngFor="let tag of tags" class="single-tage">{{tag}} <i (click)="removeTag(tag)" - class="fa fa-times-circle"></i></span> + <span *ngFor="let tag of tags" class="single-tage">{{tag}} + <i (click)="removeTag(tag)" class="fa fa-times-circle"></i> + </span> </div> </div> </div> <div id="container"> <div id="target"> <div class="card creat-card"> - <div class="single-line"> - <h5 class="label-name"> - Custom key + <div class="single-line customKeyTitle"> + <h5 class="label-name w-100 "> + Custom key </h5> + <span>To add New Custom Key, fill the first key then <b>Press ENTER</b></span> </div> <div *ngFor="let map of customKeysMap | keyvalue; let i=index" class="single-custom-key"> <div class="single-line-custom-key"> - <label class="label-name"><span>{{i + 1}}-</span> Name</label> + <label class="label-name"><span>{{i + 1}}.</span> Name</label> <div class="label-input"> <input value="{{map.key}}" name="key" type="input" placeholder="Enter name"> </div> @@ -91,7 +95,7 @@ </div> <div class="single-line-custom-key-delete"> <button (click)="removeKey($event,map.key)" class="custom-key-delete"><i aria-hidden="true" - class="icon-delete"></i></button> + class="icon-delete-sm"></i></button> </div> </div> @@ -111,7 +115,7 @@ </div> </div> <!-- <div class="single-line-custom-key-delete"><button (click)="removeKey($event)" - class="custom-key-delete"><i aria-hidden="true" class="icon-delete"></i></button></div> --> + class="custom-key-delete"><i aria-hidden="true" class="icon-delete-sm"></i></button></div> --> </div> </div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts index 3a9b7b880..6018ad535 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts @@ -16,9 +16,9 @@ export class MetadataTabComponent implements OnInit { tags = new Set<string>(); customKeysMap = new Map(); modes: any[] = [ - { name: 'Designer Mode', style: 'mode-icon icon-designer-mode' }]; - /* {name: 'Scripting Mode', style: 'mode-icon icon-scripting-mode'}, - {name: 'Generic Script Mode', style: 'mode-icon icon-generic-script-mode'}];*/ + { name: 'Designer Mode', style: 'mode-icon icon-topologyView-active' }]; + /* {name: 'Scripting Mode', style: 'mode-icon icon-topologySource'}, + {name: 'Generic Script Mode', style: 'mode-icon icon-topologySource'}];*/ modeType = this.modes[0].name; private metaDataTab: MetaDataTabModel = new MetaDataTabModel(); private errorMessage: string; @@ -101,7 +101,7 @@ export class MetadataTabComponent implements OnInit { if (this.metaDataTab.name && this.metaDataTab.version) { this.packageCreationService.checkBluePrintNameAndVersion(this.metaDataTab.name, this.metaDataTab.version).then(element => { if (element) { - this.errorMessage = 'the package with name and version is exists'; + this.errorMessage = 'Package name already exists with this version. Use different name or different version number.'; } else { this.errorMessage = ' '; } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html index 67beca2a1..ee4368711 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html @@ -4,37 +4,49 @@ <div class="container-fluid main-container"> <header class="page-title"> <div class="row"> - <h2 class="col m-0"> + <h2 class="col m-0 pb-0"> <ul class="breadcrumb-header"> <li><a routerLink="/packages">CBA Packages</a></li> + <i class="fa fa-angle-right ml-2 mr-2"></i> <li>Package Name</li> </ul> </h2> - <div class="col d-flex justify-content-end header-button-save"> - <button class="float btn btn-sm btn-outline-secondary" (click)="goBackToDashBorad()">Discard - Changes</button> - <button class="float btn btn-sm btn-primary" (click)="saveBluePrint()">Save</button> + <div class="col"> + </div> </div> </header> - <div class="container-fluid body-container"> - <div class="container"> <div class="creat-action-container"> + <a href="#" class="action-button save" (click)="saveBluePrint()"> + <i class="icon-save-sm" aria-hidden="true"></i> + <span>Save</span> + </a> + <a href="#" class="action-button" (click)="goBackToDashBorad()"> + <i class="icon-discard-sm" aria-hidden="true"></i> + <span>Discard Changes</span> + </a> + + <hr> <a href="#" class="action-button"> - <i class="icon-clone" aria-hidden="true"></i> + <i class="icon-clone-sm" aria-hidden="true"></i> <span>Clone</span> </a> <a href="#" class="action-button"> - <i class="icon-archive" aria-hidden="true"></i> + <i class="icon-archive-sm" aria-hidden="true"></i> <span>Archive</span> </a> + <a href="#" class="action-button"> + <i class="icon-download" aria-hidden="true"></i> + <span>Download</span> + </a> + <a href="#" class="action-button delete"> - <i class="icon-delete" aria-hidden="true"></i> + <i class="icon-delete-sm" aria-hidden="true"></i> <span>Delete</span> </a> </div> @@ -52,7 +64,7 @@ <a class="nav-item nav-link" id="nav-scripts-tab" data-toggle="tab" href="#nav-scripts" role="tab" aria-controls="nav-scripts" aria-selected="false">SCRIPTS</a> <a class="nav-item nav-link" id="nav-imports-tab" data-toggle="tab" href="#nav-imports" - role="tab" aria-controls="nav-imports" aria-selected="false">IMPORTS</a> + role="tab" aria-controls="nav-imports" aria-selected="false">DEFINITIONS</a> <a class="nav-item nav-link" id="nav-authentication-tab" data-toggle="tab" href="#nav-authentication" role="tab" aria-controls="nav-authentication" aria-selected="false">EXTERNAL SYSTEM AUTHENTICATION PROPERTIES</a> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.html index 5dd68ed72..79c444061 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.html @@ -1,31 +1,57 @@ <div class="import-container-all"> <div class="import-container"> <div class="import-container-input"> - <input class="ng-pristine ng-valid ng-touched" placeholder="Enter file URL" type="input"> - <a class="enter-link" href="#"><i class="icon-enter"></i></a> + <input class="ng-pristine ng-valid ng-touched" placeholder="Enter file URL then ENTER" type="input"> + <a class="enter-link" href="#"><i class="icon-enter-link"></i></a> </div> <span class="import-container-span">Or you can also <a data-target="#scriptsModal" data-toggle="modal" - href="#">Import File</a></span> + (click)="resetTheUploadedFiles()" href="#"><b>Import File</b></a></span> </div> <div class="accordion"> - <div class="card creat-card"> + <!-- <div class="card creat-card"> <div class="single-line"> <label class="label-name">File</label> </div> - </div> + </div> --> <div *ngFor="let file of scriptsFiles | keyvalue; let mapIndex = index" id="accordion-script"> <div class="card"> <div [id]="'head-script-'+mapIndex" class="card-header"> <h5 class="mb-0 d-flex justify-content-between"> - <button [attr.aria-controls]="'id-script-'+mapIndex" [attr.data-target]="'#id-script-'+mapIndex" + <button (click)="changeDivShow(mapIndex)" aria-expanded="false" class="btn btn-link collapsed" data-toggle="collapse"> <i class="icon-file-code"></i> {{file.key}} </button> - <a (click)="removeFile(file.key,mapIndex)" class="accordion-delete"><i - class="icon-delete"></i></a> + <a data-toggle="modal" data-target="#exampleModal" class="accordion-delete"><i + class="icon-delete-sm"></i></a> + <!-- <a (click)="removeFile(file.key,mapIndex)" data-toggle="modal" data-target="#exampleModal" class="accordion-delete"><i + class="icon-delete-sm"></i></a> --> + <!-- Delete Modal --> + <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" + aria-labelledby="exampleModalLabel" aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalLabel">Delete Script</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <p>Are you sure you want to delete script file <span>ConfigDeploy.py</span>?</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" + data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary">Delete</button> + </div> + </div> + </div> + </div> + + </h5> </div> <div [attr.aria-labelledby]="'head-script-'+mapIndex" [id]="'id-script-'+mapIndex" class="collapse" @@ -51,7 +77,7 @@ <div class="modal-header"> <h5 class="modal-title" id="scriptsModalLabel">Import File</h5> <button aria-label="Close" class="close" data-dismiss="modal" type="button"> - <span aria-hidden="true">×</span> + <img src="assets/img/icon-close.svg" /> </button> </div> <div class="modal-body"> @@ -72,11 +98,13 @@ <div class="folder-upload-type">Allowed file type: Kotlin(kt), Python(py)</div> </ng-template> </ngx-file-drop> - <div *ngFor="let item of uploadedFiles; let i=index" class="upload-table"> + <div class="upload-table"> <table class="table"> <thead> - <tr> - <th>Name : {{ item.name }}</th> + <tr *ngFor="let item of uploadedFiles; let i=index"> + <th width="40"><img src="assets/img/icon-file-code.svg" /></th> + <th>{{ item.name }}</th> + <th width="40" class="text-right"><img src="assets/img/icon-remove-file.svg" /></th> </tr> </thead> </table> @@ -92,4 +120,4 @@ </div> </div> </div> -</div>
\ No newline at end of file +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.ts index 5387489a2..efe28e9a4 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/scripts-tab/scripts-tab.component.ts @@ -98,4 +98,13 @@ export class ScriptsTabComponent implements OnInit { textChanges(code: any, key: string) { this.packageCreationStore.addScripts(key, code); } + + changeDivShow(mapIndex: number) { + const divElement = document.getElementById('id-script-' + mapIndex) as HTMLElement; + if (divElement.getAttribute('class').includes('show')) { + divElement.setAttribute('class', 'collapse'); + } else { + divElement.setAttribute('class', 'collapse show'); + } + } } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.html index 8a43b010b..16c3101f2 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.html @@ -6,7 +6,7 @@ </label> <div class="label-input"> - <input type="input" [(ngModel)]="fileName" placeholder="Topology name.vLB.CDS"> + <input type="input" [(ngModel)]="fileName" placeholder="Template name"> </div> </div> </div> @@ -56,9 +56,9 @@ </div> <div class="create-template-import">Use the editor to add parameters or you can also <a href="#" data-toggle="modal" (click)="allowedExt=[getFileExtension()]" - data-target="#templateModal">Import - File</a></div> - <div class="editor-container"> + data-target="#templateModal"><b>Import + File</b></a></div> + <div class="editor-container mb-4"> <app-source-editor (textChange)="textChanges($event,templateInfo.fileName)" [(text)]="templateFileContent"></app-source-editor> </div> @@ -76,18 +76,18 @@ </div> <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion"> <div class="card-body"> - <h6 class="text-center">Select a source to load config parameters</h6> + <p class="text-center"><b>Select a source to load config parameters</b></p> <div class="text-center"> <a href="#" (click)="getMappingTableFromTemplate($event)" class="mapping-source-load"> - <i class="icon-current-template"></i> + <i class="icon-use-attributes"></i> <br /> <span>Use Current Template Instance</span> </a> <a href="#" (click)="allowedExt=['.csv']" data-toggle="modal" data-target="#templateModal" class="mapping-source-load"> - <i class="icon-Upload-attribute"></i> + <i class="icon-upload-attributes"></i> <br /> - <div>Upload attribute list</div> + <div>Upload Attributes List</div> <div class="source-load-note">(Should be comma delimited file)</div> </a> <!-- <a href="#" class="mapping-source-load"> @@ -119,8 +119,8 @@ <tbody> <tr *ngFor="let dict of resourceDictionaryRes"> <td> - <i *ngIf="dict.definition?.property?.required" class="fa fa-check-square mx-2"></i> - <i *ngIf="!dict.definition?.property?.required" class="fa fa-square mx-2"></i> + <img *ngIf="dict.definition?.property?.required" src="/assets/img/icon-required-yes.svg"> + <img *ngIf="!dict.definition?.property?.required" src="/assets/img/icon-required-no.svg"> </td> <td>{{ dict.name }}</td> <td>{{ dict.name }}</td> @@ -166,8 +166,8 @@ <tbody> <tr *ngFor="let dict of mappingRes"> <td> - <i *ngIf="dict.definition?.property?.required" class="fa fa-check-square mx-2"></i> - <i *ngIf="!dict.definition?.property?.required" class="fa fa-square mx-2"></i> + <img *ngIf="dict.definition?.property?.required" src="/assets/img/icon-required-yes.svg"> + <img *ngIf="!dict.definition?.property?.required" src="/assets/img/icon-required-no.svg"> </td> <td>{{ dict['name'] }}</td> <td>{{ dict['name'] }}</td> @@ -194,8 +194,8 @@ </div> <div class="template-mapping-action"> - <button class="btn btn-sm btn-outline-secondary">Cancel</button> - <button (click)="saveToStore()" class="btn btn-sm btn-primary">Finish</button> + <button class="btn btn-outline-secondary">Cancel</button> + <button (click)="saveToStore()" class="btn btn-primary">Submit</button> </div> </div> </div> @@ -208,11 +208,11 @@ <div class="modal-header"> <h5 class="modal-title" id="templateModalLabel">Import File</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> - <span aria-hidden="true">×</span> + <img src="assets/img/icon-close.svg" /> </button> </div> <div class="modal-body"> - <ngx-file-drop [accept]="allowedExt" dropZoneLabel="Drop files here" (onFileDrop)="dropped($event)" + <ngx-file-drop [multiple]="false" [accept]="allowedExt" dropZoneLabel="Drop files here" (onFileDrop)="dropped($event)" (onFileOver)="fileOver($event)" (onFileLeave)="fileLeave($event)"> <ng-template ngx-file-drop-content-tmp let-openFileSelector="openFileSelector"> <div class="folder-upload"> @@ -231,11 +231,13 @@ </div> </ng-template> </ngx-file-drop> - <div class="upload-table" *ngFor="let item of uploadedFiles; let i=index"> + <div class="upload-table"> <table class="table"> <thead> - <tr> - <th>Name : {{ item.name }}</th> + <tr *ngFor="let item of uploadedFiles; let i=index"> + <th width="40"><img src="assets/img/icon-file-code.svg" /></th> + <th>{{ item.name }}</th> + <th width="40" class="text-right"><img src="assets/img/icon-remove-file.svg" /></th> </tr> </thead> </table> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-listing/templ-mapp-listing.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-listing/templ-mapp-listing.component.html index ab97159b6..f5e683f28 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-listing/templ-mapp-listing.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-listing/templ-mapp-listing.component.html @@ -20,7 +20,7 @@ <div class="card-body max-height-list"> <div class="row"> <!-- <div class="col-4" style="color:white" *ngFor="let file of templates.files | keyvalue; let mapIndex = index">--> - <div class="col-4" style="color:white" *ngFor="let file of getKeys(templateAndMappingMap)"> + <div class="col-4" *ngFor="let file of getKeys(templateAndMappingMap)"> <a (click)="setSourceCodeEditor(file)" class="template-mapping-list active">{{file}} <span *ngIf="getValue(file).isMapping">Mapping</span> <span *ngIf="getValue(file).isTemplate">Template</span> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html index e5ebc315a..07c192d2c 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html @@ -1,6 +1,6 @@ <div class="dropdown packagesFilter w-100"> <input class="dropdown-toggle" type="text"> - <div class="dropdown-text">{{checkBoxTages.substr(0,checkBoxTages.length-1)}}</div> + <div class="dropdown-text">Filter By Tags {{checkBoxTages.substr(0,checkBoxTages.length-1)}}</div> <ul class="dropdown-content w-100"> <li> <div class="form-group"> @@ -13,6 +13,6 @@ <label class="custom-control-label" for={{tag}}>{{tag}}</label> </div> </li> + <li class="reset-filter"><a href="">Reset filter</a></li> </ul> </div> - diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html index 9322ee783..91c7f5b96 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html @@ -1,103 +1,123 @@ <div class="row packages-card"> - <div class="col-lg-3 col-md-6"> + <div class="col-lg-3 col-md-6 d-flex"> <!--Add Package Card--> <div class="card addPaackage-card"> <div class="card-body text-center"> - <img src="/assets/img/icon-addPackage.svg"> + <img src="/assets/img/icon-addPackage.svg" width="40%"> </div> <div class="card-footer row"> - <div class="col"> + <div class="col text-center"> <a routerLink="/packages/createPackage" role="button" aria-pressed="true" - class="btn-create-package float">Create + class="btn-create-package float"><i class="icon-create-white" aria-hidden="true"></i>Create + Package </a> - </div> - <div class="col"> - <a href="#" role="button" aria-pressed="true" class="btn-import-package float">Import + <br /> + <a href="#" role="button" aria-pressed="true" class="btn-import-package float mb-3"><i + class="icon-import-blue" aria-hidden="true"></i>Import Package </a> </div> </div> </div> </div> - <div class="col-lg-3 col-md-6" *ngFor="let bluePrint of viewedPackages"> - + <div class="col-lg-3 col-md-6 d-flex" *ngFor="let bluePrint of viewedPackages"> <!--Card 1--> - <div> - <div class="card"> - <div class="card-body"> - <div class="row"> - <div class="col-9 pr-0"> - <a class="card-title" [routerLink]="['/packages/package', bluePrint.id]" - (click)="testDispatch(bluePrint)"> - <img class="icon-deployed" src="/assets/img/icon-deploy.svg"> - {{bluePrint.artifactName}} - </a> - - </div> - <div class="col-3"> - - <div class="dropdown"> - <input class="dropdown-toggle" type="text"> - <div class="dropdown-text"> - <img src="/assets/img/icon-menuDots.svg" title="Actions"> - </div> - <ul class="dropdown-content"> - <li class="action-clone"> - <a href="#">Clone</a> - </li> - <li class="action-archive"> - <a href="#">Archive</a> - </li> - <li class="action-delete"> - <a href="#">Delete</a> - </li> - </ul> - </div> + <div class="card"> + <div class="card-body"> + <div class="row"> + <div class="col-10 pr-0"> + <a class="card-title" [routerLink]="['/packages/package', bluePrint.id]" + (click)="testDispatch(bluePrint)"> + <!-- <img class="icon-deployed" src="/assets/img/icon-deploy.svg"> --> + <p class="packageName" tooltip="{{bluePrint.artifactName}}" placement="bottom"> + {{bluePrint.artifactName}}</p> + <span class="package-version">V 1.0.2</span> + </a> - </div> </div> - <div class="row"> - <div class="col"> - <p class="mb-0">Last modified {{ bluePrint.createdDate | date:'short' }} - </p> - <p>By {{bluePrint.updatedBy}}</p> - <ul class="package-contributers"> - <li> - <button type="button" class="border-fade" data-toggle="tooltip" - data-placement="bottom" title="User name"> - <img src="/assets/img/img-user1.jpeg"> - </button> + <div class="col-2"> + <div class="dropdown"> + <input class="dropdown-toggle" type="text"> + <div class="dropdown-text"> + <!-- <img src="/assets/img/icon-menuDots.svg" title="Actions"> --> + <i class="icon-menuDots" aria-hidden="true"></i> + </div> + <ul class="dropdown-content"> + <li class="action-clone"> + <a href="#"> + <i class="icon-clone-sm" aria-hidden="true"></i> + Clone + </a> </li> - <li> - <button type="button" data-toggle="tooltip" data-placement="bottom" - title="User name"> - <img src="/assets/img/img-user2.jpg"> - </button> + <li class="action-archive"> + <a href="#"> + <i class="icon-archive-sm" aria-hidden="true"></i> + Archive + </a> </li> - <li> - <button type="button" data-toggle="tooltip" data-placement="bottom" - title="User name"> - <img src="/assets/img/img-user3.jpg"> - </button> + <li class="action-archive"> + <a href="#"> + <i class="icon-download" aria-hidden="true"></i> + Download + </a> </li> - <li> - <a href="">5 contributors</a> + <li class="action-delete"> + <a href="#"> + <i class="icon-delete-sm" aria-hidden="true"></i> + Delete + </a> </li> </ul> </div> + </div> - <div class="card-footer"> - <div class="row"> - <div class="col"> - <button type="button" class="btn btn-card-topology">Topology View + </div> + <div class="row"> + <div class="col"> + <p class="mb-0 mt-1">Last modified {{ bluePrint.createdDate | date:'short' }} + </p> + <p class="mb-2">By {{bluePrint.updatedBy}}</p> + <p class="package-desc" [delay]="300" + tooltip="DESCRIPTION: + The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from de Finibus Bonorum et Malorum by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham." + placement="auto">Description text quisquam est dolorem, velitThe standard chunk of Lorem + Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and + 1.10.33 from de Finibus Bonorum et</p> + <ul class="package-contributers"> + <li> + <button type="button" class="border-fade" data-toggle="tooltip" data-placement="bottom" + title="User name"> + <img src="/assets/img/img-user1.jpeg"> </button> - </div> - <div class="col"> - <button type="button" class="btn btn-card-config">Configuration</button> - </div> + </li> + <li> + <button type="button" data-toggle="tooltip" data-placement="bottom" title="User name"> + <img src="/assets/img/img-user2.jpg"> + </button> + </li> + <li> + <button type="button" data-toggle="tooltip" data-placement="bottom" title="User name"> + <img src="/assets/img/img-user3.jpg"> + </button> + </li> + <li> + <a href="">5 contributors</a> + </li> + </ul> + </div> + </div> + <div class="card-footer"> + <div class="row"> + <div class="col"> + <button type="button" class="btn btn-card-topology"><i class="icon-btn-card-topology" + aria-hidden="true"></i>Designer Mode + </button> + </div> + <div class="col"> + <button type="button" (click)="view(bluePrint.id)" class="btn btn-card-config"><i + class="icon-btn-card-config" aria-hidden="true"></i>Configuration</button> </div> </div> </div> - </div> </div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts index 049801227..b7bc05ff9 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts @@ -1,6 +1,7 @@ -import {Component, OnInit} from '@angular/core'; -import {BlueprintModel} from '../../model/BluePrint.model'; -import {PackagesStore} from '../../packages.store'; +import { Component, OnInit } from '@angular/core'; +import { BlueprintModel } from '../../model/BluePrint.model'; +import { PackagesStore } from '../../packages.store'; +import { Router } from '@angular/router'; @Component({ selector: 'app-packages-list', @@ -12,7 +13,7 @@ export class PackageListComponent implements OnInit { viewedPackages: BlueprintModel[] = []; - constructor(private packagesStore: PackagesStore) { + constructor(private packagesStore: PackagesStore, private router: Router) { console.log('PackageListComponent'); this.packagesStore.state$.subscribe(state => { console.log(state); @@ -26,6 +27,9 @@ export class PackageListComponent implements OnInit { this.packagesStore.getAll(); } + view(id) { + this.router.navigate(['/packages/package', id]); + } testDispatch(bluePrint: BlueprintModel) { console.log(bluePrint.id); } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html index b5245f757..86db08110 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html @@ -2,6 +2,5 @@ <div class="col package-paginator pr-0"> <ngb-pagination [collectionSize]="totalCount" [(page)]="pageNumber" [pageSize]="pageSize" class="float-right" (pageChange)="getPageFromService($event)" - ></ngb-pagination> </div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.html index 9eb45f1be..ff937fa72 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.html @@ -13,7 +13,6 @@ <li *ngFor="let sortType of sortTypes"> <a (click)="sortPackages($event)" name={{sortType}}>{{sortType}}</a> </li> - </ul> </div> </div> @@ -23,10 +22,9 @@ <app-packages-list></app-packages-list> </div> - <div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">...</div> - <div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">...</div> - <div class="tab-pane fade" id="nav-contact1" role="tabpanel" aria-labelledby="nav-contact1-tab">... - </div> + <div class="tab-pane fade text-center" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">No Deployed Package is available</div> + <div class="tab-pane fade text-center" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">...</div> + <div class="tab-pane fade text-center" id="nav-contact1" role="tabpanel" aria-labelledby="nav-contact1-tab">No Archived Package is available</div> </div> </div> </div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.ts index b63f8879f..0c16292c0 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/sort-packages/sort-packages.component.ts @@ -29,4 +29,5 @@ export class SortPackagesComponent implements OnInit { enum SortByToServerValue { Recent = 'DATE', Name = 'NAME', + Version = 'VERSION', } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary-api.service.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary-api.service.spec.ts new file mode 100644 index 000000000..0bf40e43c --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary-api.service.spec.ts @@ -0,0 +1,32 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { TestBed } from '@angular/core/testing'; + +import { DictionaryApiService } from './dictionary-api.service'; + +describe('DictionaryApiService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: DictionaryApiService = TestBed.get(DictionaryApiService); + expect(service).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary-api.service.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary-api.service.ts new file mode 100644 index 000000000..c253842d1 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary-api.service.ts @@ -0,0 +1,48 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { Injectable } from '@angular/core'; +import { DictionaryPage } from './model/dictionary.model'; +import { ApiService } from 'src/app/common/core/services/api.service'; +import { ResourceDictionaryURLs } from 'src/app/common/constants/app-constants'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class DictionaryApiService { + + constructor(private api: ApiService) { } + + getPagedDictionary(pageNumber: number, pageSize: number, sortBy: string) { + return this.api.get(ResourceDictionaryURLs.getPagedDictionary, { + offset: pageNumber, + limit: pageSize, + sort: sortBy + }); + } + getPagedDictionaryByKeyWord(keyWord: string, pageNumber: number, pageSize: number, sortBy: string) { + return this.api.get(ResourceDictionaryURLs.getMetaDatePageable + '/' + keyWord, { + offset: pageNumber, + limit: pageSize, + sort: sortBy + }); + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary.store.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary.store.ts new file mode 100644 index 000000000..a932327cf --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/dictionary.store.ts @@ -0,0 +1,161 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { Injectable } from '@angular/core'; +import { Store } from '../../../common/core/stores/Store'; +import { Observable, of } from 'rxjs'; +import { DictionaryDashboardState } from './model/dictionary-dashboard.state'; +import { DictionaryPage } from './model/dictionary.model'; +import { DictionaryApiService } from './dictionary-api.service'; + +@Injectable({ + providedIn: 'root' +}) +export class DictionaryStore extends Store<DictionaryDashboardState> { + // TDOD fixed for now as there is no requirement to change it from UI + public pageSize = 5; + private dictionaryContent: DictionaryPage = new DictionaryPage(); + + constructor(private dictionaryServiceList: DictionaryApiService) { + super(new DictionaryDashboardState()); + } + + public search(command: string) { + if (command) { + this.searchPagedDictionary(command, 0, this.pageSize); + } else { + this.getPagedDictionary(0, this.pageSize); + } + } + + public getAll() { + console.log('getting all packages...'); + this.getPagedDictionary(0, this.pageSize); + } + + public getPage(pageNumber: number, pageSize: number) { + if (this.isCommandExist()) { + this.searchPagedDictionary(this.state.command, pageNumber, pageSize); + } else { + this.getPagedDictionary(pageNumber, pageSize); + } + } + + public sortPagedDictionary(sortBy: string) { + if (this.isCommandExist()) { + this.searchPagedDictionary(this.state.command, this.state.currentPage, this.pageSize, sortBy); + } else { + this.getPagedDictionary(this.state.currentPage, this.pageSize, sortBy); + } +} + + public filterByTags(tags: string[]) { + console.log(this.state.currentPage); + this.getPagedDictionaryByTags(this.state.command, this.state.currentPage, + this.pageSize, this.state.sortBy, tags); + + } + + protected getPagedDictionary(pageNumber: number, pageSize: number, sortBy: string = this.state.sortBy) { + + this.dictionaryServiceList.getPagedDictionary(pageNumber, pageSize, sortBy) + .subscribe((pages: DictionaryPage) => { + console.log(pages); + this.setState({ + ...this.state, + page: pages, + filteredPackages: pages, + command: '', + totalPackages: pages.totalElements, + currentPage: pageNumber, + // this param is set only in get all as it represents the total number of pacakges in the server + totalDictionariesWithoutSearchorFilters: pages.totalElements, + tags: [], + sortBy + }); + }); + } + + private searchPagedDictionary(keyWord: string, pageNumber: number, pageSize: number, sortBy: string = this.state.sortBy) { + this.dictionaryServiceList.getPagedDictionaryByKeyWord(keyWord, pageNumber, pageSize, sortBy) + .subscribe((pages: DictionaryPage) => { + console.log(pages); + this.setState({ + ...this.state, + page: pages, + filteredPackages: pages, + command: keyWord, + totalPackages: pages.totalElements, + currentPage: pageNumber, + tags: [], + sortBy + }); + }); + } + + private isCommandExist() { + return this.state.command; + } + + private getPagedDictionaryByTags(keyWord: string, currentPage1: number, pageSize: number, sortBy1: string, tagsSearchable: string[]) { + this.getPagedDictionaryByKeyWordFilteredByTags(tagsSearchable) + .subscribe((pages: DictionaryPage) => { + this.setState({ + ...this.state, + page: this.state.page, + filteredPackages: pages, + command: keyWord, + tags: tagsSearchable, + currentPage: currentPage1, + sortBy: sortBy1, + totalPackages: this.state.page.totalElements, + }); + }); + } + + private getPagedDictionaryByKeyWordFilteredByTags(tagsSearchable: string[]): Observable<any> { + this.dictionaryContent.content = []; + if (tagsSearchable && tagsSearchable.length !== 0 && !tagsSearchable.includes('All')) { + tagsSearchable.forEach(tag => { + if (tag) { + this.state.page.content.forEach(dictionaryModel => { + if (tag.endsWith(',')) { + tag = tag.replace(',', ''); + } + dictionaryModel.tags.split(',').forEach(dictionaryModelTag => { + if (dictionaryModelTag === tag) { + this.dictionaryContent.content.push(dictionaryModel); + } + }); + }); + } else { + this.getPagedDictionary(this.state.currentPage, this.pageSize); + return of(this.state.page); + } + }); + this.dictionaryContent.content = this.dictionaryContent.content.filter((value, index, self) => self.indexOf(value) === index); + console.log('the lenght is ' + this.dictionaryContent.content.length); + return of(this.dictionaryContent); + } else { + this.getPagedDictionary(this.state.currentPage, this.pageSize); + return of(this.state.page); + } + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/definition.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/definition.model.ts new file mode 100644 index 000000000..96d188a54 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/definition.model.ts @@ -0,0 +1,30 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { Sources } from './sources.model'; + +export class Definition { + tag: string; + name: string; + property: string; + updatedBy: string; + sources: Sources[]; + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/dictionary-dashboard.state.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/dictionary-dashboard.state.ts new file mode 100644 index 000000000..d0a0be151 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/dictionary-dashboard.state.ts @@ -0,0 +1,33 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { DictionaryPage } from './dictionary.model'; + +export class DictionaryDashboardState { + + page: DictionaryPage; + filteredPackages: DictionaryPage; + command: string; + currentPage = 0; + totalPackages: number; + tags: string[]; + sortBy = 'DATE'; + totalDictionariesWithoutSearchorFilters: number; +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/dictionary.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/dictionary.model.ts new file mode 100644 index 000000000..0f54f4ad2 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/dictionary.model.ts @@ -0,0 +1,36 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { Page } from 'src/app/common/model/page'; + +export class DictionaryModel { + + public name: string; + public tags: string; + public dataType: string; + public description: string; + public entrySchema: string; + public updatedBy: string; + public createdDate: string; + public definition: object; +} + +export class DictionaryPage extends Page<DictionaryModel> { +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/metaData.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/metaData.model.ts new file mode 100644 index 000000000..e4b9be75f --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/metaData.model.ts @@ -0,0 +1,29 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/ + +export class MetaData { + public name: string; + public tags: string; + public dataType: string; + public description: string; + public entrySchema: string; + public updatedBy: string; + public createdDate: string; +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/sources.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/sources.model.ts new file mode 100644 index 000000000..4074e5138 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/model/sources.model.ts @@ -0,0 +1,24 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/ + +export class Sources { + sources: []; + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.html new file mode 100644 index 000000000..fc08ebe22 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.html @@ -0,0 +1,30 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/ --> + +<header class="page-title"> + <div class="row"> + <h2 class="col m-0">Resource Dictionary + <span id="numberOfPackages">({{numberOfDD}} DD)</span> + </h2> + <div class="col"> + </div> + </div> +</header> + diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.spec.ts new file mode 100644 index 000000000..46888ef9e --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { DictionaryHeaderComponent } from './dictionary-header.component'; + +describe('DictionaryHeaderComponent', () => { + let component: DictionaryHeaderComponent; + let fixture: ComponentFixture<DictionaryHeaderComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DictionaryHeaderComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DictionaryHeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.ts new file mode 100644 index 000000000..364c71f95 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-header/dictionary-header.component.ts @@ -0,0 +1,42 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; +import { DictionaryStore } from '../../dictionary.store'; + +@Component({ + selector: 'app-dictionary-header', + templateUrl: './dictionary-header.component.html', + styleUrls: ['./dictionary-header.component.css'] +}) +export class DictionaryHeaderComponent implements OnInit { + + numberOfDD: number; + + constructor(private dictionaryStore: DictionaryStore) { + this.dictionaryStore.state$ + .subscribe(state => { + this.numberOfDD = state.totalDictionariesWithoutSearchorFilters; + }); + } + ngOnInit() { + } + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.html new file mode 100644 index 000000000..1cedeeb09 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.html @@ -0,0 +1,90 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 class="row packages-card"> + <div class="col-lg-3 col-md-6 d-flex"> + <!--Add Package Card--> + <div class="card addPaackage-card"> + <div class="card-body text-center"> + <img src="/assets/img/icon-addPackage.svg" width="40%"> + </div> + <div class="card-footer row"> + <div class="col text-center"> + <a routerLink="/resource-dictionary/createDictionary" role="button" aria-pressed="true" + class="btn-create-package float"><i class="icon-create-white" aria-hidden="true"></i>Create Package + </a> + <br/> + <a href="#" role="button" aria-pressed="true" class="btn-import-package float mb-3"><i class="icon-import-blue" aria-hidden="true"></i>Import Package + </a> + </div> + </div> + </div> + </div> + <div class="col-lg-3 col-md-6 d-flex" *ngFor="let dictionary of viewedDictionary"> + <!--Card 1--> + <div> + <div class="card"> + <div class="card-body"> + <div class="row"> + <div class="col-9 pr-0"> + <a class="card-title" [routerLink]="['/dictionary/dictionaryByName', dictionary.name]" + (click)="testDispatch(dictionary)"> + <!-- <img class="icon-deployed" src="/assets/img/icon-deploy.svg"> --> + {{dictionary.name}} + </a> + </div> + <div class="col-3"> + + <div class="dropdown"> + <input class="dropdown-toggle" type="text"> + <div class="dropdown-text"> + <!-- <img src="/assets/img/icon-menuDots.svg" title="Actions"> --> + <i class="icon-menuDots" aria-hidden="true"></i> + </div> + <ul class="dropdown-content"> + <li class="action-clone"> + <a href="#"> + <i class="icon-clone-sm" aria-hidden="true"></i> + Clone + </a> + </li> + <li class="action-delete"> + <a href="#"> + <i class="icon-delete-sm" aria-hidden="true"></i> + Delete + </a> + </li> + </ul> + </div> + + </div> + </div> + <div class="row"> + <div class="col"> + <p class="mb-0">Last modified {{ dictionary.createdDate | date:'short' }} + </p> + <p class="mb-2">By {{dictionary.updatedBy}}</p> + </div> + </div> + </div> + </div> + </div> + </div> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.spec.ts new file mode 100644 index 000000000..18b5f2b41 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { DictionaryListComponent } from './dictionary-list.component'; + +describe('DictionaryListComponent', () => { + let component: DictionaryListComponent; + let fixture: ComponentFixture<DictionaryListComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DictionaryListComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DictionaryListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.ts new file mode 100644 index 000000000..7c4c991f7 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-list/dictionary-list.component.ts @@ -0,0 +1,51 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; +import { DictionaryModel } from '../../model/dictionary.model'; +import { DictionaryStore } from '../../dictionary.store'; + +@Component({ + selector: 'app-dictionary-list', + templateUrl: './dictionary-list.component.html', + styleUrls: ['./dictionary-list.component.css'] +}) +export class DictionaryListComponent implements OnInit { + viewedDictionary: DictionaryModel[] = []; + + constructor(private dictionaryStore: DictionaryStore) { + console.log('DictionaryListComponent'); + this.dictionaryStore.state$.subscribe(state => { + console.log(state); + if (state.filteredPackages) { + this.viewedDictionary = state.filteredPackages.content; + } + }); + } + + ngOnInit() { + this.dictionaryStore.getAll(); + } + + testDispatch(dictionary: DictionaryModel) { + console.log(dictionary.name); + } + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.html new file mode 100644 index 000000000..8909ef431 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.html @@ -0,0 +1,25 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 class="col package-paginator pr-0"> + <ngb-pagination [collectionSize]="totalCount" [(page)]="pageNumber" [pageSize]="pageSize" class="float-right" + (pageChange)="getPageFromService($event)"> + </ngb-pagination> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.spec.ts new file mode 100644 index 000000000..e9a95ffa4 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { DictionaryPaginationComponent } from './dictionary-pagination.component'; + +describe('DictionaryPaginationComponent', () => { + let component: DictionaryPaginationComponent; + let fixture: ComponentFixture<DictionaryPaginationComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DictionaryPaginationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DictionaryPaginationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.ts new file mode 100644 index 000000000..1cd4e2ea2 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component.ts @@ -0,0 +1,60 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; +import { DictionaryStore } from '../../dictionary.store'; + +@Component({ + selector: 'app-dictionary-pagination', + templateUrl: './dictionary-pagination.component.html', + styleUrls: ['./dictionary-pagination.component.css'] +}) +export class DictionaryPaginationComponent implements OnInit { + + pageNumber: number; + totalCount: number; + pageSize: number; + previousPage: number; + + constructor(private dictionaryStore: DictionaryStore) { + this.pageSize = dictionaryStore.pageSize; + + this.dictionaryStore.state$ + .subscribe(state => { + this.pageNumber = state.currentPage; + this.totalCount = state.totalPackages; + }); + } + + ngOnInit() { + } + + public getPageFromService(page) { + console.log('getPageFromService', page); + if (isNaN(page)) { + page = 1; + console.log('page change to first...', page); + } + if (this.previousPage !== page) { + this.dictionaryStore.getPage(page - 1, this.dictionaryStore.pageSize); + this.previousPage = page; + } + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.html new file mode 100644 index 000000000..f8f378486 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.html @@ -0,0 +1,38 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 class="dropdown packagesFilter w-100"> + <input class="dropdown-toggle" type="text"> + <div class="dropdown-text">{{checkBoxTages.substr(0,checkBoxTages.length-1)}}</div> + <ul class="dropdown-content w-100"> + <li> + <div class="form-group"> + <input type="text" (input)="reloadChanges($event)" class="form-control" placeholder="Search By Tag" autofocus> + </div> + </li> + <li *ngFor="let tag of viewedTags"> + <div class="custom-control custom-checkbox"> + <input type="checkbox" (click)="reloadDictionary($event)" class="custom-control-input" id={{tag}}> + <label class="custom-control-label" for={{tag}}>{{tag}}</label> + </div> + </li> + <li class="reset-filter"><a href="">Reset filter</a></li> + </ul> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.spec.ts new file mode 100644 index 000000000..f83470f25 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { FilterbyTagsComponent } from './filterby-tags.component'; + +describe('FilterbyTagsComponent', () => { + let component: FilterbyTagsComponent; + let fixture: ComponentFixture<FilterbyTagsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FilterbyTagsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FilterbyTagsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.ts new file mode 100644 index 000000000..bdf6bd1ea --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/filterby-tags/filterby-tags.component.ts @@ -0,0 +1,100 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; +import { DictionaryModel, DictionaryPage } from '../../model/dictionary.model'; +import { DictionaryStore } from '../../dictionary.store'; + +@Component({ + selector: 'app-filterby-tags', + templateUrl: './filterby-tags.component.html', + styleUrls: ['./filterby-tags.component.css'] +}) +export class FilterbyTagsComponent implements OnInit { + page: DictionaryPage; + tags: string[] = []; + viewedTags: string[] = []; + searchTag = ''; + viewedDictionary: DictionaryModel[] = []; + private checkBoxTages = ''; + currentPage = 0; + + constructor(private dictionaryStore: DictionaryStore) { + this.dictionaryStore.state$.subscribe(state => { + console.log(state); + if (state.page) { + this.viewedDictionary = state.page.content; + this.tags = []; + if (state.currentPage !== this.currentPage) { + this.checkBoxTages = ''; + this.currentPage = state.currentPage; + } + this.viewedDictionary.forEach(element => { + element.tags.split(',').forEach(tag => { + this.tags.push(tag.trim()); + }); + this.tags.push('All'); + this.tags = this.tags.filter((value, index, self) => self.indexOf(value) === index); + this.assignTags(); + }); + } + }); + } + + ngOnInit() { + + } + + reloadChanges(event: any) { + this.searchTag = event.target.value; + this.filterItem(this.searchTag); + } + + private assignTags() { + this.viewedTags = this.tags; + } + + private filterItem(value) { + if (!value) { + this.assignTags(); + } + this.viewedTags = this.tags.filter( + item => item.toLowerCase().indexOf(value.toLowerCase()) > -1 + ); + } + + reloadDictionary(event: any) { + if (!event.target.checked) { + this.checkBoxTages = this.checkBoxTages.replace(event.target.id + ',', '') + .replace(event.target.id, ''); + } else { + this.checkBoxTages += event.target.id.trim() + ','; + } + const tagsSelected = this.checkBoxTages.split(',').filter(item => { + if (item) { + return true; + } + }).map((item) => { + return item.trim(); + }); + this.dictionaryStore.filterByTags(tagsSelected); + } + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.html new file mode 100644 index 000000000..1d435dbd8 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.html @@ -0,0 +1,59 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/ --> + +<app-header> +</app-header> +<div class="new-wrapper"> + <div class="container-fluid main-container"> + <app-dictionary-header></app-dictionary-header> + <div class="container-fluid body-container"> + <nav class="row"> + <!--Nav Tabs--> + <div class="col pr-0"> + <div class="nav nav-tabs " id="nav-tab" role="tablist"> + <a class="nav-item nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" + role="tab" aria-controls="nav-home" + aria-selected="true">All</a> + <a class="nav-item nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" + role="tab" aria-controls="nav-profile" + aria-selected="false">ATT</a> + <a class="nav-item nav-link" id="nav-contact-tab" data-toggle="tab" href="#nav-contact" + role="tab" aria-controls="nav-contact" + aria-selected="false">OPEN CONFIG</a> + </div> + </div> + <!--Nav Search & Filter--> + <div class="col search-filter-col"> + <div class="row"> + <div class="col-7"> + <app-search-dictionary></app-search-dictionary> + </div> + <div class="col-5 pl-2"> + <app-filterby-tags class="w-100"></app-filterby-tags> + </div> + + </div> + </div> + </nav> + <app-sort-dictionary></app-sort-dictionary> + </div> + </div> +</div> + diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.spec.ts new file mode 100644 index 000000000..bb821f34b --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { ResourceDictionaryDashboardComponent } from './resource-dictionary-dashboard.component'; + +describe('ResourceDictionaryDashboardComponent', () => { + let component: ResourceDictionaryDashboardComponent; + let fixture: ComponentFixture<ResourceDictionaryDashboardComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ResourceDictionaryDashboardComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ResourceDictionaryDashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.ts new file mode 100644 index 000000000..8a64b9215 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/resource-dictionary-dashboard.component.ts @@ -0,0 +1,36 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; + +@Component({ + selector: 'app-resource-dictionary-dashboard', + templateUrl: './resource-dictionary-dashboard.component.html', + styleUrls: ['./resource-dictionary-dashboard.component.css'] +}) +export class ResourceDictionaryDashboardComponent implements OnInit { + + constructor() { } + + ngOnInit() { + console.log('ResourceDictionaryDashboardComponent'); + } + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.html new file mode 100644 index 000000000..80f980b05 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.html @@ -0,0 +1,24 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 class="searchBox"> + <input class="searchInput" [ngClass]="{'searchBox-expanded': searchQuery}" (input)="searchDictionary($event)" type="text" name="" placeholder="Search Dictionary"> + <button class="searchButton" href="#"></button> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.spec.ts new file mode 100644 index 000000000..70964048b --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { SearchDictionaryComponent } from './search-dictionary.component'; + +describe('SearchDictionaryComponent', () => { + let component: SearchDictionaryComponent; + let fixture: ComponentFixture<SearchDictionaryComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchDictionaryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchDictionaryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.ts new file mode 100644 index 000000000..76e40cf7d --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/search-dictionary/search-dictionary.component.ts @@ -0,0 +1,42 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; +import { DictionaryStore } from '../../dictionary.store'; + +@Component({ + selector: 'app-search-dictionary', + templateUrl: './search-dictionary.component.html', + styleUrls: ['./search-dictionary.component.css'] +}) +export class SearchDictionaryComponent implements OnInit { + private searchQuery = ''; + constructor(private dictionaryStore: DictionaryStore) { + } + + ngOnInit() { + } + searchDictionary(event: any) { + this.searchQuery = event.target.value; + this.searchQuery = this.searchQuery.trim(); + this.dictionaryStore.search(this.searchQuery); + } + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.css new file mode 100644 index 000000000..f263c0086 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.css @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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========================================================= +*/
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.html new file mode 100644 index 000000000..cc55f6cab --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.html @@ -0,0 +1,52 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 class="row mt-4"> + <div class="col"> + <div class="tab-content" id="nav-tabContent"> + <div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab"> + <div class="row"> + <!--Dictionary Sort--> + <div class="col sort-packages"> + Sort by: + <div class="dropdown"> + <input class="dropdown-toggle" type="text"> + <div class="dropdown-text">{{selected}}</div> + <ul class="dropdown-content"> + <li *ngFor="let sortType of sortTypes"> + <a (click)="sortDictionary($event)" name={{sortType}}>{{sortType}}</a> + </li> + + </ul> + </div> + </div> + <!--Dictionary Paginator--> + <app-dictionary-pagination></app-dictionary-pagination> + </div> + <app-dictionary-list></app-dictionary-list> + + </div> + <div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">...</div> + <div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">...</div> + </div> + </div> +</div> + + diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.spec.ts new file mode 100644 index 000000000..54b103823 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { SortDictionaryComponent } from './sort-dictionary.component'; + +describe('SortDictionaryComponent', () => { + let component: SortDictionaryComponent; + let fixture: ComponentFixture<SortDictionaryComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SortDictionaryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SortDictionaryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.ts new file mode 100644 index 000000000..61c334a6b --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component.ts @@ -0,0 +1,54 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 } from '@angular/core'; +import { DictionaryStore } from '../../dictionary.store'; + +@Component({ + selector: 'app-sort-dictionary', + templateUrl: './sort-dictionary.component.html', + styleUrls: ['./sort-dictionary.component.css'] +}) +export class SortDictionaryComponent implements OnInit { + sortTypes: string[]; + selected: string; + + constructor(private dictionaryStore: DictionaryStore) { + this.sortTypes = Object.keys(SortByToServerValue); + this.selected = 'Recent'; + } + + ngOnInit() { + } + + sortDictionary(event: any) { + const key = event.target.name; + console.log(key); + this.selected = key; + this.dictionaryStore.sortPagedDictionary(SortByToServerValue[key]); + } + +} + +enum SortByToServerValue { + Recent = 'DATE', + Name = 'NAME', + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-routing.module.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-routing.module.ts new file mode 100644 index 000000000..eb29c4c87 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary-routing.module.ts @@ -0,0 +1,36 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { ResourceDictionaryDashboardComponent } from './resource-dictionary-dashboard/resource-dictionary-dashboard.component'; + +const routes: Routes = [ + { + path: '', + component: ResourceDictionaryDashboardComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ResourceDictionaryRoutingModule { } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary.module.ts b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary.module.ts new file mode 100644 index 000000000..5bd6710f8 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/resource-dictionary/resource-dictionary.module.ts @@ -0,0 +1,62 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2020 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 { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'; +import { SidebarModule } from 'ng-sidebar'; +import { FormsModule } from '@angular/forms'; +import { NgxFileDropModule } from 'ngx-file-drop'; +import { AceEditorModule } from 'ng2-ace-editor'; +import { DataTablesModule } from 'angular-datatables'; + +import { ResourceDictionaryRoutingModule } from './resource-dictionary-routing.module'; +import { ResourceDictionaryDashboardComponent } from './resource-dictionary-dashboard/resource-dictionary-dashboard.component'; +import { DictionaryHeaderComponent } from './resource-dictionary-dashboard/dictionary-header/dictionary-header.component'; +import { SearchDictionaryComponent } from './resource-dictionary-dashboard/search-dictionary/search-dictionary.component'; +import { FilterbyTagsComponent } from './resource-dictionary-dashboard/filterby-tags/filterby-tags.component'; +import { SortDictionaryComponent } from './resource-dictionary-dashboard/sort-dictionary/sort-dictionary.component'; +import { DictionaryPaginationComponent } from './resource-dictionary-dashboard/dictionary-pagination/dictionary-pagination.component'; +import { SharedModulesModule } from '../../shared-modules/shared-modules.module'; +import { DictionaryListComponent } from './resource-dictionary-dashboard/dictionary-list/dictionary-list.component'; + +@NgModule({ + declarations: [ + ResourceDictionaryDashboardComponent, + DictionaryHeaderComponent, + SearchDictionaryComponent, + FilterbyTagsComponent, + SortDictionaryComponent, + DictionaryPaginationComponent, + DictionaryListComponent, + ], + imports: [ + CommonModule, + ResourceDictionaryRoutingModule, + NgbPaginationModule, + SharedModulesModule, + SidebarModule.forRoot(), + FormsModule, + NgxFileDropModule, + AceEditorModule, + DataTablesModule, + ] +}) +export class ResourceDictionaryModule { } diff --git a/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.html b/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.html index 502e098d3..bfccac7a0 100644 --- a/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.html +++ b/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.html @@ -8,14 +8,15 @@ <a routerLink="/packages">Packages</a> <span class="icon"> <!-- <i class="fa fa-dashboard"></i> --> - <i class="icon-package"></i> + <i class="icon-nav-packages"></i> </span> </li> - <li class="menu-hasdropdown"> - <a >Data Dictionary</a> + <li> + <a routerLink="/resource-dictionary">Resource Dictionary</a> <span class="icon"> - <i class="icon-dictionary"></i> + <i class="icon-nav-dictionary"></i> </span> + </li> <!-- <label title="toggle menu" for="settings"> <span class="downarrow"> <i class="fa fa-caret-down"></i> @@ -69,4 +70,4 @@ </ul> </nav> -</div> +</div>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.ts b/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.ts index 3ee4d0f65..38e368526 100644 --- a/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.ts +++ b/cds-ui/designer-client/src/app/modules/shared-modules/header/header.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; @Component({ selector: 'app-header', @@ -7,9 +8,12 @@ import { Component, OnInit } from '@angular/core'; }) export class HeaderComponent implements OnInit { - constructor() { } + constructor(private router: Router) { } ngOnInit() { } + // redirect() { + // this.router.navigate(['/packages']); + // } } diff --git a/cds-ui/designer-client/src/app/modules/shared-modules/shared-modules.module.ts b/cds-ui/designer-client/src/app/modules/shared-modules/shared-modules.module.ts index 6b6d39689..7663fb8dc 100644 --- a/cds-ui/designer-client/src/app/modules/shared-modules/shared-modules.module.ts +++ b/cds-ui/designer-client/src/app/modules/shared-modules/shared-modules.module.ts @@ -1,13 +1,16 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HeaderComponent } from './header/header.component'; - - +import { RouterModule } from '@angular/router'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; @NgModule({ declarations: [HeaderComponent], imports: [ - CommonModule - ], exports : [HeaderComponent] + CommonModule, + RouterModule, + TooltipModule.forRoot(), + ], + exports : [HeaderComponent, TooltipModule, ] }) export class SharedModulesModule { } diff --git a/cds-ui/designer-client/src/assets/css/style1.css b/cds-ui/designer-client/src/assets/css/style1.css deleted file mode 100644 index e69de29bb..000000000 --- a/cds-ui/designer-client/src/assets/css/style1.css +++ /dev/null diff --git a/cds-ui/designer-client/src/assets/css/style2.css b/cds-ui/designer-client/src/assets/css/style2.css deleted file mode 100644 index df65e6753..000000000 --- a/cds-ui/designer-client/src/assets/css/style2.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - background: black -}
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.eot b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.eot Binary files differindex b21dc0253..3f1e99995 100755 --- a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.eot +++ b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.eot diff --git a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.svg b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.svg index af56e61c0..456e5d20d 100755 --- a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.svg +++ b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.svg @@ -7,22 +7,80 @@ <font-face units-per-em="1024" ascent="960" descent="-64" /> <missing-glyph horiz-adv-x="1024" /> <glyph unicode=" " horiz-adv-x="0" d="" /> -<glyph unicode="" glyph-name="generic-script-mode" d="M972.8 960h-921.6c-28.228 0-51.2-22.972-51.2-51.2v-85.334h1024v85.334c0 28.228-22.972 51.2-51.2 51.2zM85.334 857.6c-9.42 0-17.066 7.628-17.066 17.066s7.646 17.066 17.066 17.066c9.42 0 17.066-7.628 17.066-17.066s-7.646-17.066-17.066-17.066zM153.6 857.6c-9.42 0-17.066 7.628-17.066 17.066s7.646 17.066 17.066 17.066c9.42 0 17.066-7.628 17.066-17.066s-7.646-17.066-17.066-17.066zM221.866 857.6c-9.42 0-17.066 7.628-17.066 17.066s7.646 17.066 17.066 17.066c9.42 0 17.066-7.628 17.066-17.066s-7.644-17.066-17.066-17.066zM1024 789.333v-802.134c0-28.228-22.972-51.2-51.2-51.2v0h-921.6c-28.228 0-51.2 22.972-51.2 51.2v0 802.134h1024zM938.667 704h-853.333v-682.667h853.333v682.667zM211.98 523.269c2.331-2.331 5.39-3.502 8.45-3.502s6.12 1.165 8.456 3.502c4.668 4.668 4.668 12.239 0 16.907l-29.027 29.027 29.027 29.021c4.668 4.674 4.668 12.239 0 16.907s-12.239 4.668-16.907 0l-37.477-37.477c-2.243-2.243-3.502-5.284-3.502-8.45 0-3.172 1.259-6.213 3.502-8.456l37.477-37.477zM330.606 569.203l-29.027-29.027c-4.668-4.668-4.668-12.239 0.006-16.907 2.331-2.331 5.39-3.502 8.45-3.502s6.12 1.172 8.45 3.502l37.484 37.484c4.668 4.668 4.668 12.239 0 16.9l-37.484 37.484c-4.668 4.668-12.233 4.668-16.9 0-4.674-4.674-4.674-12.239 0-16.907l29.021-29.027zM247.413 520.595c1.433-0.561 2.916-0.829 4.368-0.829 4.773 0 9.279 2.879 11.13 7.584l29.445 74.961c2.418 6.144-0.611 13.080-6.755 15.498-6.138 2.412-13.080-0.611-15.492-6.755l-29.451-74.961c-2.412-6.144 0.611-13.087 6.755-15.498zM189.72 449.635h80.532c6.599 0 11.952 5.353 11.952 11.959 0 6.599-5.353 11.952-11.952 11.952h-80.532c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.347-11.959 11.952-11.959zM455.733 473.546h-141.584c-6.599 0-11.952-5.353-11.952-11.952 0-6.606 5.353-11.959 11.952-11.959h141.584c6.606 0 11.959 5.353 11.959 11.959 0 6.599-5.353 11.952-11.959 11.952zM189.72 399.214h34.306c6.599 0 11.952 5.353 11.952 11.959 0 6.599-5.353 11.952-11.952 11.952h-34.306c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.347-11.959 11.952-11.959zM411.999 423.125c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.347-11.959 11.952-11.959h20.889c6.606 0 11.959 5.353 11.959 11.959 0 6.599-5.353 11.952-11.959 11.952h-20.889zM380.535 411.173c0 6.599-5.353 11.952-11.952 11.952h-102.611c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.347-11.959 11.952-11.959h102.611c6.599 0 11.952 5.353 11.952 11.959zM458.842 411.173c0-6.606 5.353-11.959 11.952-11.959h39.129c6.606 0 11.959 5.353 11.959 11.959 0 6.599-5.353 11.952-11.959 11.952h-39.129c-6.599 0-11.952-5.353-11.952-11.952zM393.74 559.612h41.273c6.606 0 11.959 5.353 11.959 11.959 0 6.599-5.353 11.952-11.959 11.952h-41.273c-6.606 0-11.959-5.353-11.959-11.952 0-6.606 5.353-11.959 11.959-11.959zM481.239 559.612h251.829c6.606 0 11.952 5.353 11.952 11.959 0 6.599-5.347 11.952-11.952 11.952h-251.829c-6.606 0-11.959-5.353-11.959-11.952 0-6.606 5.353-11.959 11.959-11.959zM694.818 530.927h-102.013c-6.599 0-11.952-5.353-11.952-11.959 0-6.599 5.353-11.952 11.952-11.952h102.013c6.599 0 11.952 5.353 11.952 11.952 0 6.606-5.353 11.959-11.952 11.959zM554.555 530.927h-35.066c-6.606 0-11.952-5.353-11.952-11.959 0-6.599 5.347-11.952 11.952-11.952h35.066c6.606 0 11.952 5.353 11.952 11.952 0 6.606-5.347 11.959-11.952 11.959zM393.74 507.016h85.904c6.599 0 11.952 5.353 11.952 11.952 0 6.606-5.353 11.959-11.952 11.959h-85.904c-6.606 0-11.959-5.353-11.959-11.959 0-6.599 5.353-11.952 11.959-11.952zM368.732 373.128h-80.526c-6.606 0-11.959-5.353-11.959-11.952s5.353-11.952 11.959-11.952h80.526c6.599 0 11.952 5.353 11.952 11.952s-5.353 11.952-11.952 11.952zM251.588 373.128h-61.868c-6.606 0-11.952-5.353-11.952-11.952s5.347-11.952 11.952-11.952h61.868c6.606 0 11.952 5.353 11.952 11.952s-5.347 11.952-11.952 11.952zM514.71 373.128h-105.197c-6.606 0-11.952-5.353-11.952-11.952s5.347-11.952 11.952-11.952h105.197c6.599 0 11.952 5.353 11.952 11.952s-5.353 11.952-11.952 11.952v0zM656.973 434.535h-57.525c-6.599 0-11.952-5.353-11.952-11.952 0-6.606 5.353-11.959 11.952-11.959h57.525c6.606 0 11.952 5.353 11.952 11.959 0 6.599-5.347 11.952-11.952 11.952v0zM756.793 410.624h81.205c6.606 0 11.959 5.353 11.959 11.959 0 6.599-5.353 11.952-11.959 11.952h-81.205c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.353-11.959 11.952-11.959zM716.187 434.535h-18.608c-6.606 0-11.959-5.353-11.959-11.952 0-6.606 5.353-11.959 11.959-11.959h18.608c6.606 0 11.952 5.353 11.952 11.959 0 6.599-5.347 11.952-11.952 11.952zM599.448 280.357h57.525c6.606 0 11.952 5.347 11.952 11.952 0 6.599-5.347 11.952-11.952 11.952h-57.525c-6.599 0-11.952-5.353-11.952-11.952 0-6.606 5.353-11.952 11.952-11.952v0zM756.793 280.357h81.205c6.606 0 11.959 5.347 11.959 11.952 0 6.599-5.353 11.952-11.959 11.952h-81.205c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.353-11.952 11.952-11.952zM697.579 280.357h18.608c6.606 0 11.959 5.347 11.959 11.952 0 6.599-5.353 11.952-11.959 11.952h-18.608c-6.606 0-11.952-5.353-11.952-11.952 0-6.606 5.347-11.952 11.952-11.952zM656.973 173.988h-57.525c-6.599 0-11.952-5.353-11.952-11.952s5.353-11.952 11.952-11.952h57.525c6.606 0 11.952 5.353 11.952 11.952s-5.347 11.952-11.952 11.952v0zM837.998 173.988h-81.205c-6.606 0-11.952-5.353-11.952-11.952s5.347-11.952 11.952-11.952h81.205c6.606 0 11.959 5.353 11.959 11.952s-5.353 11.952-11.959 11.952v0zM716.187 173.988h-18.608c-6.606 0-11.959-5.353-11.959-11.952s5.353-11.952 11.959-11.952h18.608c6.606 0 11.952 5.353 11.952 11.952s-5.347 11.952-11.952 11.952z" /> -<glyph unicode="" glyph-name="clone" horiz-adv-x="830" d="M205.943 684.214c16.494 0 29.864 13.274 29.864 29.652v202.771h249.198c16.494 0 29.871-13.274 29.871-29.659v-136.986h-81.325c-8.034 0-15.633-3.229-21.148-8.698l-234.083-232.43c-5.253-5.209-8.761-12.739-8.761-20.953v-367.34h-137.965c-16.502 0-29.871 13.282-29.871 29.659v533.986h204.219zM176.072 874.7v-131.175h-132.112zM463.4 487.909v202.771h249.176c16.502 0 29.871-13.282 29.871-29.659v-690.013c0-16.385-13.369-29.659-29.871-29.659h-453.41c-16.494 0-29.871 13.274-29.871 29.659v487.242h204.242c16.487 0 29.864 13.267 29.864 29.659zM403.665 517.568h-132.112l132.112 131.153zM685.427 892.834v67.166l-90.194-89.555 90.194-89.555v67.166c49.734 0 90.194-40.174 90.194-89.555v-44.777h45.097v44.777c0 74.072-60.693 134.332-135.292 134.332z" /> -<glyph unicode="" glyph-name="delete" d="M170.667 49.778c0-62.578 51.2-113.778 113.778-113.778h455.111c62.578 0 113.778 51.2 113.778 113.778v682.667h-682.667v-682.667zM910.222 903.111h-199.111l-56.889 56.889h-284.444l-56.889-56.889h-199.111v-113.778h796.444v113.778z" /> -<glyph unicode="" glyph-name="designer-mode" d="M1024 793.672c0 71.312-58.064 129.328-129.434 129.328h-765.132c-71.37 0-129.434-58.016-129.434-129.328v-530.574c0-32.88 12.344-62.934 32.646-85.778-19.814-14.932-32.646-38.648-32.646-65.302 0-76.654 62.414-139.018 139.132-139.018h745.734c76.718 0 139.132 62.364 139.132 139.018 0 26.654-12.832 50.37-32.646 65.302 20.304 22.844 32.648 52.898 32.648 85.778zM60 793.672c0 38.228 31.148 69.328 69.434 69.328h765.132c38.286 0 69.434-31.1 69.434-69.328v-530.574c0-38.228-31.148-69.328-69.434-69.328h-203.372c-27.154 0-49.246-22.084-49.246-49.226 0-8.080-6.596-14.654-14.702-14.654h-230.492c-8.106 0-14.702 6.574-14.702 14.654 0 27.142-22.092 49.226-49.246 49.226h-203.372c-38.286 0-69.434 31.1-69.434 69.328zM884.868 33h-745.736c-43.634 0-79.132 35.448-79.132 79.018 0 11.994 9.784 21.752 21.806 21.752h241.022c5.242-36.078 36.396-63.878 73.926-63.878h230.492c37.53 0 68.684 27.802 73.926 63.878h241.022c12.024 0 21.806-9.758 21.806-21.752 0-43.57-35.498-79.018-79.132-79.018zM597.9 290.358c2.062-8.968 8.128-16.494 16.456-20.416 4.050-1.908 8.416-2.86 12.782-2.86 4.608 0 9.21 1.060 13.438 3.178l95.882 48.032c6.012 3.012 10.838 7.956 13.704 14.040l152.756 324.352c22.62 48.028 1.948 105.504-46.082 128.124h0.002c-23.268 10.958-49.408 12.2-73.606 3.496-24.202-8.704-43.562-26.31-54.52-49.576l-152.758-324.352c-2.866-6.084-3.604-12.954-2.096-19.508zM803.536 731.846c9.118 3.278 18.97 2.812 27.734-1.318h0.002c18.096-8.524 25.886-30.18 17.364-48.278l-14.16-30.064-65.642 30.916 14.16 30.064c4.128 8.766 11.422 15.4 20.542 18.68zM743.268 628.82l65.644-30.914-108.612-230.616-52.482-26.292-13.16 57.208zM161.846 267.084h290.574c16.568 0 30 13.432 30 30v234.358c0 16.568-13.432 30-30 30h-290.574c-16.568 0-30-13.432-30-30v-234.358c0-16.568 13.432-30 30-30zM191.846 501.442h230.574v-174.358h-230.574zM161.846 730.892h371.668c16.568 0 30 13.432 30 30s-13.432 30-30 30h-371.668c-16.568 0-30-13.432-30-30s13.432-30 30-30zM161.846 630.892h281.668c16.568 0 30 13.432 30 30s-13.432 30-30 30h-281.668c-16.568 0-30-13.432-30-30s13.432-30 30-30z" /> -<glyph unicode="" glyph-name="scripting-mode" d="M407.383 250.611c-0.418 2.89-1.966 5.494-4.302 7.243l-118.568 88.668 118.568 88.668c2.337 1.749 3.884 4.353 4.302 7.243 0.415 2.89-0.33 5.825-2.082 8.168l-18.836 25.185c-3.645 4.869-10.539 5.866-15.408 2.22l-164.036-122.669c-2.777-2.076-4.416-5.343-4.416-8.816s1.639-6.74 4.416-8.816l164.036-122.669c1.975-1.481 4.29-2.192 6.583-2.192 3.353 0 6.664 1.522 8.825 4.412l18.836 25.185c1.749 2.343 2.497 5.277 2.082 8.168zM816.975 355.338l-164.030 122.669c-4.869 3.642-11.762 2.645-15.404-2.22l-18.836-25.185c-1.749-2.34-2.497-5.277-2.082-8.168 0.418-2.887 1.963-5.494 4.302-7.243l118.565-88.668-118.565-88.668c-2.34-1.749-3.884-4.356-4.302-7.243-0.415-2.89 0.33-5.828 2.082-8.168l18.836-25.185c2.164-2.89 5.472-4.412 8.825-4.412 2.293 0 4.604 0.714 6.583 2.192l164.030 122.669c2.777 2.076 4.416 5.343 4.416 8.816s-1.642 6.74-4.419 8.816zM617.258 543.483l-28.969 12.25c-2.686 1.139-5.718 1.157-8.426 0.063-2.705-1.098-4.865-3.224-6.001-5.913l-172.977-409.119c-2.368-5.598 0.252-12.058 5.853-14.426l28.969-12.25c1.368-0.582 2.827-0.868 4.287-0.868 1.406 0 2.812 0.27 4.139 0.808 2.705 1.098 4.862 3.224 6.001 5.913l172.977 409.119c2.365 5.598-0.255 12.055-5.853 14.423zM968.962 933.384h-913.924c-30.346 0-55.038-24.692-55.038-55.038v-860.691c0-30.346 24.692-55.038 55.038-55.038h913.924c30.346 0 55.038 24.692 55.038 55.038v860.691c0 30.35-24.692 55.038-55.038 55.038zM860.058 848.993c25.145 0 45.603-20.458 45.603-45.603s-20.458-45.603-45.603-45.603c-25.145 0-45.603 20.458-45.603 45.603s20.458 45.603 45.603 45.603zM705.414 848.993c25.145 0 45.603-20.458 45.603-45.603s-20.458-45.603-45.603-45.603c-25.145 0-45.603 20.458-45.603 45.603s20.458 45.603 45.603 45.603zM139.637 826.977h183.985c13.027 0 23.588-10.558 23.588-23.588s-10.561-23.588-23.588-23.588h-183.985c-13.027 0-23.588 10.558-23.588 23.588s10.561 23.588 23.588 23.588zM936.58 57.984c0-3.956-3.221-7.18-7.183-7.18h-834.794c-3.96 0-7.183 3.224-7.183 7.18v592.746h849.161v-592.746z" /> -<glyph unicode="" glyph-name="archive" d="M945.238 644.924h-866.463c-10.674 0-19.905-3.895-27.697-11.691-7.796-7.792-11.691-17.024-11.691-27.691v-590.772c0-10.665 3.895-19.901 11.691-27.691 7.792-7.796 17.024-11.7 27.697-11.7h866.463c10.667 0 19.893 3.904 27.691 11.7 7.79 7.788 11.685 17.024 11.685 27.691v590.772c0 10.674-3.88 19.897-11.685 27.691-7.79 7.796-17.024 11.691-27.691 11.691zM618.454 459.694c-7.788-7.794-17.024-11.691-27.691-11.691h-157.539c-10.661 0-19.893 3.899-27.691 11.691-7.792 7.796-11.691 17.024-11.691 27.697 0 10.665 3.899 19.897 11.691 27.691 7.796 7.796 17.028 11.695 27.691 11.695h157.554c10.659 0 19.888-3.899 27.691-11.695 7.79-7.792 11.685-17.024 11.685-27.691 0-10.672-3.904-19.901-11.7-27.697zM1012.32 908.927c-7.798 7.796-17.024 11.691-27.693 11.691h-945.242c-10.665 0-19.897-3.895-27.691-11.691-7.794-7.792-11.693-17.024-11.693-27.691v-157.539c0-10.665 3.899-19.893 11.695-27.691 7.794-7.796 17.024-11.691 27.691-11.691h945.227c10.665 0 19.901 3.895 27.706 11.691 7.788 7.796 11.682 17.024 11.682 27.691v157.539c0 10.674-3.895 19.899-11.682 27.691z" /> -<glyph unicode="" glyph-name="enter" d="M677.571 437.241h-644.248c-18.395 0-33.323 14.929-33.323 33.323s14.929 33.323 33.323 33.323h644.248c18.395 0 33.323-14.929 33.323-33.323s-14.929-33.323-33.323-33.323zM499.849 259.519c-8.534 0-17.060 3.238-23.552 9.771-13.017 13.017-13.017 34.121 0 47.146l154.177 154.169-154.177 154.177c-13.017 13.017-13.017 34.129 0 47.146 13.025 13.017 34.129 13.017 47.146 0l177.722-177.73c13.017-13.017 13.017-34.121 0-47.137l-177.722-177.722c-6.533-6.582-15.059-9.82-23.593-9.82v0zM533.173-18.18c-202.21 0-380.728 121.651-454.884 309.957-6.753 17.060 1.684 36.431 18.793 43.184 17.060 6.663 36.48-1.643 43.232-18.842 64.027-162.573 218.245-267.652 392.859-267.652 232.726 0 422.098 189.372 422.098 422.098s-189.372 422.098-422.098 422.098c-174.614 0-328.832-105.079-392.859-267.652-6.801-17.199-26.172-25.505-43.232-18.842-17.109 6.753-25.546 26.123-18.793 43.184 74.156 188.306 252.675 309.957 454.884 309.957 269.475 0 488.744-219.27 488.744-488.744s-219.27-488.744-488.744-488.744z" /> -<glyph unicode="" glyph-name="file-code" horiz-adv-x="768" d="M512 960h-512v-1024h768v768l-256 256zM448 640h256v-640h-640v896h384v-256zM512 704v192l192-192h-192zM268.8 128h-44.8l-128 160 128 160h44.8l-128-160zM499.2 128h44.8l128 160-128 160h-44.8l128-160zM300.8 64h38.4l134.4 448h-51.2z" /> -<glyph unicode="" glyph-name="drag-menu" horiz-adv-x="372" d="M169.256 845.363c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM169.256 591.728c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM169.256 338.091c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM169.256 84.455c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM372.165 845.363c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM372.165 591.728c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM372.165 338.091c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546zM372.165 84.455c0-46.693-37.852-84.546-84.546-84.546s-84.546 37.852-84.546 84.546c0 46.693 37.852 84.546 84.546 84.546s84.546-37.852 84.546-84.546z" /> -<glyph unicode="" glyph-name="mapping" horiz-adv-x="1698" d="M439.686 447.811c0 118.806-96.658 215.464-215.464 215.464s-215.464-96.658-215.464-215.464c0-118.806 96.658-215.464 215.464-215.464s215.464 96.658 215.464 215.464zM224.222 293.908c-84.863 0-153.903 69.040-153.903 153.903s69.040 153.903 153.903 153.903c84.863 0 153.903-69.040 153.903-153.903s-69.040-153.903-153.903-153.903zM612.057 878.739c16.965 0 30.781 13.815 30.781 30.781 0 16.989-13.815 30.781-30.781 30.781s-30.781-13.791-30.781-30.781c0-16.965 13.815-30.781 30.781-30.781zM488.935 940.3h-169.293c-8.092 0-16.040-3.294-21.763-9.018s-9.018-13.671-9.018-21.763v-147.747c0-16.965 13.815-30.781 30.781-30.781s30.781 13.815 30.781 30.781v116.966h138.513c16.965 0 30.781 13.815 30.781 30.781s-13.815 30.781-30.781 30.781zM612.057 16.883c-16.965 0-30.781-13.815-30.781-30.781s13.815-30.781 30.781-30.781c16.965 0 30.781 13.815 30.781 30.781s-13.815 30.781-30.781 30.781zM488.935 16.883h-138.513v116.966c0 16.965-13.815 30.781-30.781 30.781s-30.781-13.815-30.781-30.781v-147.747c0-8.092 3.294-16.040 9.018-21.763s13.671-9.018 21.763-9.018h169.293c16.965 0 30.781 13.815 30.781 30.781s-13.815 30.781-30.781 30.781zM1129.404 550.103c-13.736 14.479-36.54 15.296-51.275 1.83l-117.198-111.703-49.442 51.275c-13.736 14.479-36.54 15.293-51.275 1.83-14.185-14.861-14.185-38.244 0-53.105l75.078-76.911c6.498-7.276 15.885-11.3 25.636-10.988 9.66 0.137 18.875 4.087 25.636 10.988l142.834 135.509c14.16 12.99 15.107 35.001 2.114 49.158-0.666 0.74-1.37 1.444-2.107 2.117zM1654.962 471.362h-421.178c-20.228 0-36.624-16.397-36.624-36.624s16.397-36.624 36.624-36.624h421.178c20.228 0 36.624 16.397 36.624 36.624s-16.397 36.624-36.624 36.624zM1129.404 843.097c-13.736 14.479-36.54 15.296-51.275 1.83l-117.198-111.703-49.442 51.275c-13.736 14.479-36.54 15.296-51.275 1.83-14.185-14.861-14.185-38.244 0-53.105l75.078-76.911c6.498-7.276 15.885-11.3 25.636-10.988 9.66 0.137 18.875 4.087 25.636 10.988l142.834 135.509c14.16 12.99 15.107 35.001 2.114 49.158-0.666 0.74-1.37 1.444-2.107 2.117zM1654.962 764.356h-421.178c-20.228 0-36.624-16.397-36.624-36.624s16.397-36.624 36.624-36.624h421.178c20.228 0 36.624 16.397 36.624 36.624s-16.397 36.624-36.624 36.624zM1129.404 257.112c-13.736 14.479-36.54 15.293-51.275 1.83l-117.198-111.703-49.442 51.275c-13.736 14.479-36.54 15.293-51.275 1.83-14.185-14.861-14.185-38.244 0-53.105l75.078-76.911c6.498-7.276 15.885-11.3 25.636-10.988 9.66 0.137 18.875 4.087 25.636 10.988l142.834 135.509c14.16 12.99 15.107 35.001 2.114 49.158-0.666 0.736-1.37 1.441-2.107 2.117zM1654.962 178.368h-421.178c-20.228 0-36.624-16.397-36.624-36.624s16.397-36.624 36.624-36.624h421.178c20.228 0 36.624 16.397 36.624 36.624s-16.397 36.624-36.624 36.624z" /> -<glyph unicode="" glyph-name="template-mapping" horiz-adv-x="1843" d="M872 448c0-66.273-53.727-120-120-120s-120 53.727-120 120c0 66.273 53.727 120 120 120s120-53.727 120-120zM892 448c0 77.195-62.805 140-140 140s-140-62.805-140-140c0-77.195 62.805-140 140-140s140 62.805 140 140zM752 348c-55.141 0-100 44.859-100 100s44.859 100 100 100c55.141 0 100-44.859 100-100s-44.859-100-100-100zM252 960h-232c-11.047 0-20-8.953-20-20v-232c0-11.047 8.953-20 20-20h232c11.047 0 20 8.953 20 20v232c0 11.047-8.953 20-20 20zM232 728h-192v192h192v-192zM252 208h-232c-11.047 0-20-8.953-20-20v-232c0-11.047 8.953-20 20-20h232c11.047 0 20 8.953 20 20v232c0 11.047-8.953 20-20 20zM232-24h-192v192h192v-192zM252 584h-232c-11.047 0-20-8.953-20-20v-232c0-11.047 8.953-20 20-20h232c11.047 0 20 8.953 20 20v232c0 11.047-8.953 20-20 20zM232 352h-192v192h192v-192zM332 428h140l-32-24c-8.836-6.625-10.625-19.164-4-28 3.93-5.234 9.938-8 16.016-8 4.18 0 8.383 1.305 11.984 4l80 60c0.102 0.070 8 6 8 16 0 6.172-3.039 12.305-8 16l-80 60c-8.836 6.633-21.375 4.836-28-4s-4.836-21.375 4-28l32-24h-140c-11.047 0-20-8.953-20-20s8.953-20 20-20zM332 804h169.711l140-140h-49.711c-11.047 0-20-8.953-20-20s8.953-20 20-20h100c12.82 0 22.789 13.312 19.203 25.602l-28 96c-3.094 10.602-14.203 16.703-24.805 13.602-10.602-3.094-16.688-14.195-13.594-24.805l6.961-23.875-127.625 127.625c-3.75 3.742-8.836 5.852-14.141 5.852h-178c-11.047 0-20-8.953-20-20s8.953-20 20-20zM692 268h-100c-11.047 0-20-8.953-20-20s8.953-20 20-20h49.711l-140-140h-169.711c-11.047 0-20-8.953-20-20s8.953-20 20-20h178c5.305 0 10.391 2.109 14.141 5.859l127.625 127.625-6.969-23.883c-3.094-10.609 3-21.711 13.602-24.797 1.875-0.547 3.758-0.813 5.609-0.813 8.664 0 16.641 5.68 19.195 14.406 0 0 27.867 95.562 28 96 3.578 12.297-6.437 25.602-19.203 25.602v0zM1004 728c11.023 0 20 8.977 20 20 0 11.039-8.977 20-20 20s-20-8.961-20-20c0-11.023 8.977-20 20-20zM924 768h-110c-5.258 0-10.422-2.141-14.141-5.859s-5.859-8.883-5.859-14.141v-96c0-11.023 8.977-20 20-20s20 8.977 20 20v76h90c11.023 0 20 8.977 20 20s-8.977 20-20 20zM1004 168c-11.023 0-20-8.977-20-20s8.977-20 20-20c11.023 0 20 8.977 20 20s-8.977 20-20 20zM924 168h-90v76c0 11.023-8.977 20-20 20s-20-8.977-20-20v-96c0-5.258 2.141-10.422 5.859-14.141s8.883-5.859 14.141-5.859h110c11.023 0 20 8.977 20 20s-8.977 20-20 20zM1387.759 524.215c-11.101 11.702-29.53 12.362-41.439 1.479l-94.715-90.273-39.957 41.439c-11.101 11.702-29.53 12.359-41.439 1.479-11.464-12.010-11.464-30.907 0-42.917l60.675-62.157c5.252-5.881 12.838-9.132 20.718-8.88 7.807 0.11 15.254 3.303 20.718 8.88l115.433 109.513c11.444 10.498 12.209 28.287 1.708 39.728-0.538 0.598-1.108 1.167-1.702 1.711zM1812.494 460.58h-340.379c-16.347 0-29.598-13.251-29.598-29.598s13.251-29.598 29.598-29.598h340.379c16.347 0 29.598 13.251 29.598 29.598s-13.251 29.598-29.598 29.598zM1387.759 761.001c-11.101 11.702-29.53 12.362-41.439 1.479l-94.715-90.273-39.957 41.439c-11.101 11.702-29.53 12.362-41.439 1.479-11.464-12.010-11.464-30.907 0-42.917l60.675-62.157c5.252-5.881 12.838-9.132 20.718-8.88 7.807 0.11 15.254 3.303 20.718 8.88l115.433 109.513c11.444 10.498 12.209 28.287 1.708 39.728-0.538 0.598-1.108 1.167-1.702 1.711zM1812.494 697.366h-340.379c-16.347 0-29.598-13.251-29.598-29.598s13.251-29.598 29.598-29.598h340.379c16.347 0 29.598 13.251 29.598 29.598s-13.251 29.598-29.598 29.598zM1387.759 287.432c-11.101 11.702-29.53 12.359-41.439 1.479l-94.715-90.273-39.957 41.439c-11.101 11.702-29.53 12.359-41.439 1.479-11.464-12.010-11.464-30.907 0-42.917l60.675-62.157c5.252-5.881 12.838-9.132 20.718-8.88 7.807 0.11 15.254 3.303 20.718 8.88l115.433 109.513c11.444 10.498 12.209 28.287 1.708 39.728-0.538 0.595-1.108 1.164-1.702 1.711zM1812.494 223.794h-340.379c-16.347 0-29.598-13.251-29.598-29.598s13.251-29.598 29.598-29.598h340.379c16.347 0 29.598 13.251 29.598 29.598s-13.251 29.598-29.598 29.598z" /> -<glyph unicode="" glyph-name="template" horiz-adv-x="1109" d="M253.953 960h-233.798c-11.133 0-20.155-9.023-20.155-20.155v-233.798c0-11.133 9.023-20.155 20.155-20.155h233.798c11.133 0 20.155 9.023 20.155 20.155v233.798c0 11.133-9.023 20.155-20.155 20.155zM233.798 726.202h-193.488v193.488h193.488v-193.488zM1054.115 856.806h-518.829c-24.917 0-45.116-13.354-45.116-29.828s20.198-29.828 45.116-29.828h518.829c24.917 0 45.116 13.354 45.116 29.828s-20.198 29.828-45.116 29.828zM253.953 573.023h-233.798c-11.133 0-20.155-9.023-20.155-20.155v-233.798c0-11.133 9.023-20.155 20.155-20.155h233.798c11.133 0 20.155 9.023 20.155 20.155v233.798c0 11.133-9.023 20.155-20.155 20.155zM233.798 339.225h-193.488v193.488h193.488v-193.488zM1054.115 469.829h-518.829c-24.917 0-45.116-13.354-45.116-29.828s20.198-29.828 45.116-29.828h518.829c24.917 0 45.116 13.354 45.116 29.828s-20.198 29.828-45.116 29.828zM253.953 211.845h-233.798c-11.133 0-20.155-9.023-20.155-20.155v-233.798c0-11.133 9.023-20.155 20.155-20.155h233.798c11.133 0 20.155 9.023 20.155 20.155v233.798c0 11.133-9.023 20.155-20.155 20.155zM233.798-21.953h-193.488v193.488h193.488v-193.488zM1054.115 108.651h-518.829c-24.917 0-45.116-13.354-45.116-29.828s20.198-29.828 45.116-29.828h518.829c24.917 0 45.116 13.354 45.116 29.828s-20.198 29.828-45.116 29.828z" /> -<glyph unicode="" glyph-name="Upload-attribute" horiz-adv-x="931" d="M529.597 725.461h108.895l-167.074 177.515v-117.847c0-32.818 25.36-59.668 58.177-59.668zM347.605 280.926h-193.925c-10.441 0-17.901 7.458-17.901 17.901s7.458 17.901 17.901 17.901h205.857c11.932 28.342 26.851 53.702 44.752 77.569h-250.609c-10.441 0-17.901 7.458-17.901 17.901s7.458 17.901 17.901 17.901h284.918c53.702 47.735 125.304 77.569 202.875 77.569 7.458 0 13.427 0 22.376-1.492v183.482h-134.254c-52.21 0-93.98 41.769-93.98 93.98v146.189h-343.098c-44.752 0-79.061-35.8-79.061-80.553v-681.72c0-44.752 35.8-79.061 79.061-79.061h268.511c-14.918 35.8-23.868 76.078-23.868 117.847 1.492 25.36 4.475 50.719 10.441 74.586zM153.682 543.471h226.743c10.441 0 17.901-7.458 17.901-17.901s-7.458-17.901-17.901-17.901h-226.743c-10.441 0-17.901 7.458-17.901 17.901 0 8.95 7.458 17.901 17.901 17.901zM641.475 471.868c-147.681 0-267.019-119.337-267.019-267.019s119.337-267.019 267.019-267.019c147.681 0 267.019 119.337 267.019 267.019s-120.83 267.019-267.019 267.019zM783.19 200.374c-2.983-2.983-7.458-4.475-11.932-4.475s-8.95 1.492-13.427 5.967l-98.454 107.403v-255.085c0-10.441-7.458-17.901-17.901-17.901s-17.901 7.458-17.901 17.901v255.085l-99.946-107.403c-5.967-7.458-17.901-7.458-25.36-1.492s-7.458 17.901-1.492 25.36l131.272 140.223c2.983 2.983 7.458 5.967 13.427 5.967 4.475 0 8.95-1.492 13.427-5.967l131.272-140.223c5.967-7.458 4.475-17.901-2.983-25.36z" /> -<glyph unicode="" glyph-name="import-cds" horiz-adv-x="1271" d="M373.922 551.955c-4.153 0-7.839-2.815-8.912-6.821l-187.326-467.415v-16.35c0-11.999-0.773-16.35 9.241-16.35h731.938c18.904 0 35.549 12.744 40.064 29.648l167.225 460.935c0 0 0 10.222 0 16.35h-752.23zM353.172 584.661h674.859v102.495c0 24.645-20.053 44.677-44.677 44.677h-404.776l-81.76 114.466h-307.158c-24.624 0-44.677-20.053-44.677-44.677v-683.478l168.143 436.897c4.494 16.876 21.147 29.619 40.044 29.619z" /> -<glyph unicode="" glyph-name="current-template" horiz-adv-x="1327" d="M522.495 853.894l13.749-77.003h653.568v-718.647h-1052.314v795.65h384.991zM625.163 468.903h-77.003v-205.329h77.003v205.329zM471.169 545.894h-77.003v-282.332h77.003v282.332zM779.157 571.561h-77.003v-307.992h77.003v307.992zM933.15 520.231h-77.003v-256.665h77.003v256.665z" /> -<glyph unicode="" glyph-name="package" horiz-adv-x="1205" d="M1154.309 638.745h-70.074v125.852c0 30.258-24.616 54.854-54.854 54.854h-497.001l-100.392 140.549h-377.133c-30.238 0-54.854-24.616-54.854-54.854v-877.166h0.12c-0.1-11.304 3.413-22.367 10.481-31.624 9.838-12.85 24.737-20.199 40.9-20.199h898.691c23.211 0 43.651 15.641 49.192 36.402l205.322 562.959v3.554c0 34.575-21.203 59.673-50.397 59.673zM40.157 905.146c0 8.112 6.606 14.697 14.697 14.697h356.452l100.392-140.549h517.662c8.112 0 14.697-6.586 14.697-14.697v-125.852h-788.44c-2.891 0-5.763-0.241-8.553-0.723-19.536-3.273-35.78-17.528-40.619-35.659l-166.29-453.512v756.294zM961.134 24.686c-1.325-4.919-5.843-8.373-10.943-8.373h-898.691c-4.879 0-7.73 2.791-8.995 4.457-1.265 1.646-3.213 5.14-2.47 8.192l204.619 561.252c1.325 4.919 5.843 8.373 10.943 8.373h898.711c7.63 0 9.577-10.963 10.079-16.444l-203.254-557.458zM743.632 478.118c-21.744 0-39.427-17.683-39.427-39.427 0-6.801 1.728-13.201 4.771-18.793l-64.588-64.588c-8.904 6.933-20.048 11.099-32.179 11.099s-23.275-4.166-32.185-11.092l-50.394 50.394c2.313 3.91 3.726 8.404 3.726 13.267 0 14.496-11.789 26.284-26.284 26.284s-26.284-11.789-26.284-26.284c0-14.496 11.789-26.284 26.284-26.284 4.863 0 9.357 1.413 13.267 3.726l50.394-50.394c-6.926-8.91-11.092-20.055-11.092-32.185s4.166-23.275 11.092-32.179l-83.217-83.223c-7.005 6.354-16.264 10.264-26.442 10.264-21.744 0-39.427-17.683-39.427-39.427s17.683-39.427 39.427-39.427c21.744 0 39.427 17.683 39.427 39.427 0 6.801-1.728 13.201-4.771 18.793l84.301 84.301c7.268-5.651 16.034-9.436 25.614-10.639v-66.763c-18.616-3.141-32.856-19.332-32.856-38.835 0-21.744 17.683-39.427 39.427-39.427s39.427 17.683 39.427 39.427c0 19.497-14.24 35.688-32.856 38.835v66.763c9.581 1.203 18.347 4.987 25.614 10.639l50.394-50.394c-2.32-3.916-3.732-8.411-3.732-13.274 0-14.496 11.789-26.284 26.284-26.284s26.284 11.789 26.284 26.284c0 14.496-11.789 26.284-26.284 26.284-4.863 0-9.357-1.413-13.267-3.726l-50.394 50.394c6.926 8.91 11.092 20.055 11.092 32.185s-4.166 23.275-11.092 32.179l63.51 63.51c6.998-6.354 16.257-10.264 26.436-10.264 21.744 0 39.427 17.683 39.427 39.427s-17.683 39.427-39.427 39.427z" /> -<glyph unicode="" glyph-name="dictionary" d="M991.457 533.163c-13.803 0-24.993-11.19-24.993-24.993v-203.273c0-13.803 11.19-24.993 24.993-24.993s24.993 11.19 24.993 24.993v203.273c-0.003 13.803-11.193 24.993-24.993 24.993v0zM960.173 959.5h-856.973c-56.907 0-103.2-34.087-103.2-75.984v-835.988c0-48.869 54-88.628 120.377-88.628h799.807c13.6 0 25.733 5.969 30.91 15.209 5.203 9.287 2.297 19.877-7.403 26.98-16.927 12.389-26.247 28.882-26.247 46.439 0 20.432 12.837 39.437 34.62 51.827h8.11c31.030 0 56.277 18.586 56.277 41.435v194.1c0 10.163-11.19 18.402-24.993 18.402s-24.993-8.239-24.993-18.402v-194.1c0-2.555-2.82-4.631-6.29-4.631h-839.797c-25.133 0-50.023-5.925-70.39-16.77v764.128c0 21.602 23.87 39.18 53.213 39.18h856.973c3.47 0 6.29-2.076 6.29-4.631v-144.885c0-10.163 11.19-18.402 24.993-18.402s24.993 8.239 24.993 18.402v144.885c0 22.847-25.247 41.435-56.277 41.435v0zM886.563 99.357c-12.343-15.459-19.107-33.27-19.107-51.829 0-18.522 6.64-36.286 19.090-51.827h-766.17c-38.813 0-70.39 23.249-70.39 51.827s31.577 51.827 70.39 51.827l766.187 0.002zM348.708 760.797c-53.594 0-97.198-43.604-97.198-97.198v-217.009c0-53.594 43.604-97.198 97.198-97.198h319.034c53.594 0 97.198 43.604 97.198 97.198v217.009c0 53.594-43.604 97.198-97.198 97.198h-319.034zM723.265 663.599v-217.009c0-30.617-24.909-55.523-55.523-55.523h-319.034c-30.617 0-55.526 24.909-55.526 55.523v217.009c0 30.617 24.909 55.526 55.526 55.526h319.034c30.617 0 55.523-24.909 55.523-55.526v0zM627.88 590.463c-6.871 0-9.357 1.746-14.802 5.569-7.384 5.184-17.496 12.282-36.054 12.282s-28.67-7.1-36.054-12.282c-5.445-3.823-7.931-5.569-14.802-5.569s-9.357 1.746-14.802 5.569c-7.384 5.184-17.498 12.282-36.054 12.282s-28.668-7.1-36.049-12.284c-5.445-3.823-7.931-5.569-14.8-5.569s-9.354 1.744-14.797 5.569c-7.384 5.184-17.496 12.284-36.052 12.284-10.213 0-18.492-8.279-18.492-18.492s8.279-18.492 18.492-18.492c6.869 0 9.354-1.744 14.797-5.569 7.384-5.184 17.496-12.284 36.052-12.284s28.668 7.1 36.052 12.284c5.443 3.823 7.929 5.569 14.797 5.569 6.871 0 9.357-1.746 14.805-5.569 7.384-5.184 17.498-12.282 36.054-12.282s28.668 7.1 36.054 12.282c5.445 3.823 7.931 5.569 14.805 5.569s9.357-1.746 14.802-5.569c7.384-5.184 17.496-12.282 36.054-12.282 10.213 0 18.492 8.279 18.492 18.492s-8.284 18.492-18.497 18.492v0zM497.633 493.266c-5.575 0-7.592 1.417-12.010 4.518-5.991 4.206-14.195 9.965-29.253 9.965s-23.262-5.761-29.253-9.965c-4.418-3.102-6.435-4.518-12.010-4.518s-7.592 1.417-12.012 4.518c-5.991 4.206-14.197 9.965-29.253 9.965-8.286 0-15.004-6.717-15.004-15.004s6.717-15.004 15.004-15.004c5.575 0 7.592-1.417 12.010-4.518 5.991-4.206 14.197-9.965 29.253-9.965s23.26 5.761 29.253 9.965c4.418 3.102 6.435 4.518 12.012 4.518 5.575 0 7.592-1.417 12.010-4.518 5.991-4.206 14.197-9.965 29.253-9.965 8.286 0 15.004 6.717 15.004 15.004s-6.717 15.004-15.004 15.004z" /> -<glyph unicode="" glyph-name="deploy" d="M890.522 252.945l-95.505-137.216-67.396 55.313c-7.27 5.99-18.039 4.898-24.013-2.355-5.99-7.287-4.932-18.057 2.372-24.013l81.681-67.055c3.072-2.526 6.895-3.891 10.82-3.891 0.768 0 1.553 0.051 2.338 0.171 4.71 0.649 8.943 3.243 11.674 7.151l106.052 152.388c5.376 7.731 3.482 18.364-4.267 23.757-7.748 5.461-18.364 3.516-23.757-4.25zM802.133 379.733c-122.334 0-221.867-99.533-221.867-221.867s99.533-221.867 221.867-221.867c122.334 0 221.867 99.533 221.867 221.867s-99.533 221.867-221.867 221.867zM802.133-29.867c-103.509 0-187.733 84.224-187.733 187.733s84.224 187.733 187.733 187.733c103.509 0 187.733-84.224 187.733-187.733s-84.224-187.733-187.733-187.733zM945.357 960h-866.714c-43.366 0-78.643-35.277-78.643-78.643v-201.097c0-16.623 5.359-31.898 14.251-44.527h995.482c8.909 12.629 14.268 27.904 14.268 44.51v201.114c0 43.366-35.277 78.643-78.643 78.643zM179.2 704c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM580.267 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM614.4 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM648.533 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM682.667 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM716.8 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM750.933 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM785.067 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM819.2 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM853.333 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM887.467 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM529.067 157.867c0 42.871 10.206 83.319 27.904 119.467h-542.72c-8.892-12.629-14.251-27.904-14.251-44.51v-201.097c0-43.383 35.277-78.66 78.643-78.66h543.471c-56.9 50.091-93.047 123.221-93.047 204.8zM179.2 55.467c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM14.251 601.6c-8.892-12.629-14.251-27.904-14.251-44.51v-201.097c0-16.623 5.359-31.898 14.251-44.527h562.278c49.22 72.055 131.959 119.467 225.587 119.467 87.433 0 165.205-41.472 215.211-105.609 4.147 9.421 6.656 19.695 6.656 30.652v201.114c0 16.623-5.359 31.881-14.251 44.51h-995.482zM179.2 379.733c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM580.267 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM648.533 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM716.8 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM785.067 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM853.333 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067z" /> +<glyph unicode="" glyph-name="icon-use-attributes" horiz-adv-x="1317" d="M503.303 834.341l-16.724 93.659h-468.293v-967.805h1280v874.146h-794.983zM611.456 459.707v-249.756h-93.659v249.756h93.659zM424.139 553.366v-343.415h-93.659v343.415h93.659zM798.774 209.951h-93.659v374.634h93.659v-374.634zM986.091 209.951h-93.659v312.195h93.659v-312.195z" /> +<glyph unicode="" glyph-name="icon-upload-attributes" horiz-adv-x="922" d="M529.527 737.239h109.614l-167.773 176.492v-118.106c0-31.992 25.947-58.386 58.159-58.386zM347.671 292.095h-194.394c-9.841 0-17.894 8.045-17.894 17.894 0 9.841 8.053 17.894 17.894 17.894h206.25c11.402 29.076 26.614 53.689 45.409 78.295h-251.659c-9.841 0-17.894 8.045-17.894 17.894 0 9.841 8.053 17.894 17.894 17.894h285.659c53.682 46.977 124.818 76.947 202.439 76.947 7.379 0 13.424-0.667 22.371-1.341v183.879h-134.22c-51.894 0-93.947 42.5-93.947 94.174v145.174h-343.144c-44.295 0-79.636-36.235-79.636-80.75v-682.712c0-44.515 35.341-79.856 79.636-79.856h269.545c-15.432 35.788-23.932 76.053-23.932 118.106-0.227 26.394 3.356 51.902 9.621 76.508zM153.277 553.815h226.606c9.841 0 17.894-8.053 17.894-17.902 0-9.841-8.053-17.894-17.894-17.894h-226.606c-9.841 0-17.894 8.053-17.894 17.894 0 9.848 8.053 17.902 17.894 17.902zM641.148 482.452c-147.409 0-267.311-119.894-267.311-267.311 0-147.409 119.902-267.311 267.311-267.311 147.417 0 267.318 119.902 267.318 267.311 0 147.417-119.902 267.311-267.318 267.311zM784.095 211.118c-3.356-3.136-7.833-4.705-12.083-4.705-4.697 0-9.394 2.015-12.977 5.598l-99.765 107.371v-255.455c0-9.848-8.053-17.902-17.894-17.902s-17.894 8.053-17.894 17.902v255.674l-100.212-107.371c-6.712-7.159-18.348-7.606-25.508-0.894-7.152 6.712-7.606 18.121-0.894 25.28l131.083 140.705c3.356 3.576 8.053 5.591 13.197 5.591 5.152 0 9.621-2.015 13.205-5.591l131.083-140.705c6.265-7.386 5.811-18.795-1.341-25.5z" /> +<glyph unicode="" glyph-name="icon-enter-link" d="M677.571 421.241h-644.248c-18.395 0-33.323 14.929-33.323 33.323s14.929 33.323 33.323 33.323h644.248c18.395 0 33.323-14.929 33.323-33.323s-14.929-33.323-33.323-33.323zM499.849 243.519c-8.534 0-17.060 3.238-23.552 9.771-13.017 13.017-13.017 34.121 0 47.146l154.177 154.169-154.177 154.177c-13.017 13.017-13.017 34.129 0 47.146 13.025 13.017 34.129 13.017 47.146 0l177.722-177.73c13.017-13.017 13.017-34.121 0-47.137l-177.722-177.722c-6.533-6.582-15.059-9.82-23.593-9.82v0zM533.173-34.18c-202.21 0-380.728 121.651-454.884 309.957-6.753 17.060 1.684 36.431 18.793 43.184 17.060 6.663 36.48-1.643 43.232-18.842 64.027-162.573 218.245-267.652 392.859-267.652 232.726 0 422.098 189.372 422.098 422.098s-189.372 422.098-422.098 422.098c-174.614 0-328.832-105.079-392.859-267.652-6.801-17.199-26.172-25.505-43.232-18.842-17.109 6.753-25.546 26.123-18.793 43.184 74.156 188.306 252.675 309.957 454.884 309.957 269.475 0 488.744-219.27 488.744-488.744s-219.27-488.744-488.744-488.744z" /> +<glyph unicode="" glyph-name="icon-add" d="M512 960c-282.785 0-512-229.215-512-512s229.215-512 512-512c282.785 0 512 229.249 512 512s-229.215 512-512 512zM512 0c-247.425 0-448 200.575-448 448s200.575 448 448 448c247.425 0 448-200.575 448-448s-200.575-448-448-448zM704 480h-160v160c0 17.664-14.336 32-32 32s-32-14.336-32-32v-160h-160c-17.664 0-32-14.336-32-32s14.336-32 32-32h160v-160c0-17.664 14.336-32 32-32s32 14.336 32 32v160h160c17.664 0 32 14.336 32 32s-14.336 32-32 32z" /> +<glyph unicode="" glyph-name="icon-archive-sm" d="M943.405 684.258h-864.783c-10.653 0-19.867-3.887-27.644-11.668-7.781-7.777-11.668-16.991-11.668-27.637v-589.626c0-10.644 3.887-19.863 11.668-27.637 7.777-7.781 16.991-11.677 27.644-11.677h864.783c10.647 0 19.854 3.896 27.637 11.677 7.775 7.773 11.662 16.991 11.662 27.637v589.626c0 10.653-3.872 19.858-11.662 27.637-7.775 7.781-16.991 11.668-27.637 11.668zM617.255 499.387c-7.773-7.779-16.991-11.668-27.637-11.668h-157.233c-10.64 0-19.854 3.892-27.637 11.668-7.777 7.781-11.668 16.991-11.668 27.644 0 10.644 3.892 19.858 11.668 27.637 7.781 7.781 16.995 11.673 27.637 11.673h157.249c10.638 0 19.85-3.892 27.637-11.673 7.775-7.777 11.662-16.991 11.662-27.637 0-10.651-3.896-19.863-11.677-27.644zM1010.357 947.749c-7.783 7.781-16.991 11.668-27.639 11.668h-943.409c-10.644 0-19.858-3.887-27.637-11.668-7.779-7.777-11.671-16.991-11.671-27.637v-157.233c0-10.644 3.892-19.854 11.673-27.637 7.779-7.781 16.991-11.668 27.637-11.668h943.394c10.644 0 19.863 3.887 27.652 11.668 7.773 7.781 11.66 16.991 11.66 27.637v157.233c0 10.653-3.887 19.86-11.66 27.637z" /> +<glyph unicode="" glyph-name="icon-btn-card-config" d="M971.283 561.778h-95.801c-15.398 0-28.084 8.476-33.982 22.699s-2.901 29.203 7.964 40.088l67.736 67.717c9.956 9.956 15.436 23.211 15.436 37.281 0 14.089-5.48 27.326-15.436 37.3l-86.338 86.338c-19.911 19.911-54.632 19.949-74.581 0l-67.717-67.717c-10.885-10.866-25.903-13.9-40.088-7.983-14.222 5.897-22.699 18.584-22.699 33.982v95.801c0 29.070-23.647 52.717-52.717 52.717h-122.121c-29.070 0-52.717-23.647-52.717-52.717v-95.801c0-15.398-8.476-28.084-22.699-33.982-14.184-5.935-29.203-2.882-40.088 7.983l-67.717 67.717c-19.949 19.949-54.67 19.911-74.581 0l-86.338-86.338c-9.956-9.956-15.436-23.211-15.436-37.3 0-14.071 5.48-27.307 15.436-37.281l67.736-67.717c10.866-10.885 13.843-25.865 7.964-40.088s-18.584-22.699-33.982-22.699h-95.801c-29.070 0-52.717-23.647-52.717-52.717v-122.103c0-29.089 23.647-52.736 52.717-52.736h95.801c15.398 0 28.084-8.476 33.982-22.699s2.901-29.203-7.964-40.088l-67.736-67.717c-9.956-9.956-15.436-23.211-15.436-37.281 0-14.089 5.48-27.326 15.436-37.3l86.338-86.338c19.93-19.93 54.632-19.968 74.581 0l67.717 67.736c10.885 10.866 25.847 13.862 40.088 7.964 14.222-5.897 22.699-18.584 22.699-33.982v-95.801c0-29.070 23.647-52.717 52.717-52.717h122.103c29.070 0 52.717 23.647 52.717 52.717v95.801c0 15.398 8.476 28.084 22.699 33.982 14.241 5.916 29.203 2.901 40.088-7.964l67.717-67.736c19.949-19.949 54.67-19.911 74.581 0l86.338 86.338c9.956 9.956 15.436 23.211 15.436 37.3 0 14.071-5.48 27.307-15.436 37.281l-67.736 67.717c-10.866 10.885-13.843 25.865-7.964 40.088s18.603 22.699 34.001 22.699h95.801c29.070 0 52.717 23.647 52.717 52.717v122.121c0 29.070-23.647 52.717-52.717 52.717zM986.074 386.939c0-8.154-6.637-14.791-14.791-14.791h-95.801c-30.796 0-57.249-17.673-69.025-46.118-11.795-28.444-5.594-59.657 16.194-81.427l67.736-67.717c5.784-5.784 5.784-15.17 0-20.935l-86.338-86.338c-5.765-5.765-15.151-5.803-20.935 0l-67.717 67.736c-21.788 21.788-52.983 27.951-81.427 16.194-28.444-11.776-46.118-38.229-46.118-69.025v-95.801c0-8.154-6.637-14.791-14.791-14.791h-122.121c-8.154 0-14.791 6.637-14.791 14.791v95.801c0 30.796-17.673 57.249-46.118 69.025-9.538 3.963-19.361 5.897-29.070 5.897-19.228 0-37.869-7.585-52.357-22.073l-67.717-67.736c-5.803-5.803-15.189-5.765-20.935 0l-86.338 86.338c-5.784 5.784-5.784 15.17 0 20.935l67.736 67.717c21.769 21.769 27.989 52.983 16.194 81.427-11.776 28.425-38.229 46.099-69.025 46.099h-95.801c-8.154 0-14.791 6.637-14.791 14.791v122.121c0 8.154 6.637 14.791 14.791 14.791h95.801c30.796 0 57.249 17.673 69.025 46.118 11.795 28.444 5.594 59.657-16.194 81.427l-67.736 67.717c-5.784 5.784-5.784 15.17 0 20.935l86.338 86.338c5.765 5.784 15.151 5.784 20.935 0l67.717-67.717c21.751-21.751 52.945-27.989 81.427-16.194 28.444 11.757 46.118 38.21 46.118 69.006v95.801c0 8.154 6.637 14.791 14.791 14.791h122.103c8.173 0 14.81-6.637 14.81-14.791v-95.801c0-30.796 17.673-57.249 46.118-69.025 28.482-11.795 59.657-5.575 81.427 16.194l67.717 67.717c5.803 5.784 15.189 5.784 20.935 0l86.338-86.338c5.784-5.784 5.784-15.17 0-20.935l-67.736-67.717c-21.769-21.769-27.989-52.983-16.194-81.427 11.776-28.444 38.229-46.118 69.025-46.118h95.801c8.154 0.019 14.791-6.618 14.791-14.772v-122.121zM512 618.667c-94.113 0-170.667-76.553-170.667-170.667s76.553-170.667 170.667-170.667c94.113 0 170.667 76.553 170.667 170.667s-76.553 170.667-170.667 170.667zM512 315.259c-73.178 0-132.741 59.563-132.741 132.741s59.563 132.741 132.741 132.741c73.178 0 132.741-59.563 132.741-132.741s-59.563-132.741-132.741-132.741z" /> +<glyph unicode="" glyph-name="icon-btn-card-topology" d="M944 960h-864c-44.16-0.052-79.948-35.84-80-80v-864c0.052-44.16 35.84-79.948 80-80h864c44.16 0.052 79.948 35.84 80 80v864c-0.052 44.16-35.84 79.948-80 80zM992 16c0-26.51-21.49-48-48-48h-864c-26.51 0-48 21.49-48 48v864c0 26.51 21.49 48 48 48h864c26.51 0 48-21.49 48-48v-864zM112 880c-0.442 0.010-0.884 0.010-1.326 0-17.306-0.366-31.040-14.694-30.674-32v-64h32v64h80v32h-80zM848 800h-672c-8.836 0-16-7.164-16-16v-192c0-8.836 7.164-16 16-16h672c8.836 0 16 7.164 16 16v192c0 8.836-7.164 16-16 16zM832 608h-640v160h640v-160zM432 528h-256c-8.836 0-16-7.164-16-16v-256c0-8.836 7.164-16 16-16h256c8.836 0 16 7.164 16 16v256c0 8.836-7.164 16-16 16zM192 272v201.376l201.376-201.376h-201.376zM416 294.63l-201.37 201.37h201.37v-201.37zM848 528h-352c-8.836 0-16-11.462-16-25.6v-153.6c0-14.138 7.164-25.6 16-25.6h352c8.836 0 16 11.462 16 25.6v153.6c0 14.138-7.164 25.6-16 25.6zM832 374.4h-320v102.4h320v-102.4zM480 352h384v-78.769h-384v78.769zM480 272h384v-78.769h-384v78.769zM288 192h576v-78.769h-576v78.769zM160 112h576v-78.769h-576v78.769zM160 192h78.769v-78.769h-78.769v78.769zM224 192h78.769v-78.769h-78.769v78.769z" /> +<glyph unicode="" glyph-name="icon-clone-sm" horiz-adv-x="796" d="M197.666 693.407c15.831 0 28.663 12.832 28.663 28.663v196.012h239.183c15.831 0 28.671-12.832 28.671-28.671v-132.42h-78.057c-7.711 0-15.004-3.122-20.298-8.408l-224.675-224.682c-5.042-5.035-8.408-12.314-8.408-20.255v-355.096h-132.42c-15.839 0-28.671 12.839-28.671 28.671v516.186h196.012zM168.996 877.543v-126.802h-126.802zM444.776 503.645v196.012h239.162c15.839 0 28.671-12.839 28.671-28.671v-667.013c0-15.839-12.832-28.671-28.671-28.671h-435.188c-15.831 0-28.671 12.832-28.671 28.671v471.001h196.033c15.824 0 28.663 12.825 28.663 28.671zM387.442 532.316h-126.802l126.802 126.781zM657.88 895.073v64.927l-86.57-86.57 86.57-86.57v64.927c47.735 0 86.57-38.835 86.57-86.57v-43.285h43.285v43.285c0 71.603-58.254 129.854-129.854 129.854z" /> +<glyph unicode="" glyph-name="icon-close" d="M602.197 448.32l402.432 402.432c25.003 24.981 25.003 65.515 0 90.496-25.003 25.003-65.493 25.003-90.496 0l-402.432-402.432-402.453 402.432c-25.003 25.003-65.493 25.003-90.496 0-25.003-24.981-25.003-65.515 0-90.496l402.453-402.432-402.453-402.432c-25.003-24.981-25.003-65.515 0-90.496 12.501-12.48 28.885-18.731 45.248-18.731s32.747 6.251 45.248 18.752l402.453 402.432 402.432-402.432c12.501-12.501 28.885-18.752 45.248-18.752s32.747 6.251 45.248 18.752c25.003 24.981 25.003 65.515 0 90.496l-402.432 402.411z" /> +<glyph unicode="" glyph-name="icon-comType1" d="M1024 940.966c-0.026 4.551-1.873 8.898-5.136 12.076-3.271 3.169-7.669 4.89-12.22 4.785h-989.288c-4.551 0.113-8.958-1.616-12.22-4.785s-5.119-7.525-5.136-12.076v-817.72c-0.051-9.712 7.644-17.712 17.356-18.034h237.907l8.322-18.678c2.975-6.703 9.864-10.788 17.178-10.178l34.856 2.644c13.034-16.186 28.153-30.576 44.966-42.788l-1.025-34.763c-0.212-7.356 4.237-14.051 11.102-16.695l74.042-28.585c6.839-2.636 14.602-0.695 19.39 4.864l22.602 26.195c20.653-1.924 41.449-1.39 61.975 1.61l24.195-25.237c5.042-5.254 12.814-6.805 19.483-3.89l72.746 31.831c6.737 2.949 10.89 9.831 10.347 17.169l-2.559 34.856c16.203 13.034 30.61 28.161 42.831 44.983l34.788-1.025c7.305-0.39 14.042 3.949 16.703 10.763l2.805 6.924h236.636c9.712 0.331 17.407 8.322 17.356 18.034v633.729c0 0.059 0 0.11 0 0.169s0 0.11 0 0.169v183.653zM989.288 923.11v-149.695h-954.576v149.695h954.576zM707.356 123.525c-5.983 0.195-11.644-2.729-14.949-7.72-12.915-19.39-29.102-36.39-47.839-50.237-4.788-3.534-7.424-9.288-6.992-15.22l2.347-31.915-50.39-22.042-22.127 23.076c-4.034 4.212-9.915 6.11-15.653 5.059-23.093-4.229-46.703-4.839-69.983-1.805-5.788 0.754-11.568-1.458-15.373-5.873l-20.593-23.864-51.178 19.737 0.941 31.898c0.178 5.975-2.746 11.627-7.72 14.949-19.39 12.915-36.39 29.102-50.237 47.839-3.542 4.78-9.288 7.415-15.22 6.983l-31.924-2.339-6.864 15.686c-0.449 1.686-1.153 3.305-2.093 4.788l-13.085 29.915 23.076 22.127c4.212 4.034 6.11 9.915 5.059 15.644-4.229 23.093-4.839 46.703-1.805 69.983 0.746 5.788-1.458 11.568-5.873 15.381l-23.864 20.593 19.737 51.178 31.898-0.941c5.983-0.195 11.644 2.729 14.949 7.72 12.915 19.398 29.102 36.398 47.839 50.237 4.788 3.542 7.424 9.288 6.992 15.229l-2.347 31.915 50.39 22.042 22.136-23.076c4.034-4.212 9.915-6.11 15.644-5.059 23.102 4.229 46.712 4.839 69.992 1.805 5.788-0.746 11.568 1.458 15.381 5.873l20.593 23.864 51.178-19.737-0.941-31.89c-0.178-5.983 2.737-11.636 7.72-14.958 19.39-12.907 36.39-29.102 50.229-47.839 3.542-4.78 9.288-7.415 15.22-6.983l31.915 2.347 22.051-50.39-23.085-22.127c-4.203-4.034-6.102-9.915-5.059-15.644 4.229-23.093 4.839-46.703 1.814-69.983-0.754-5.788 1.449-11.568 5.873-15.381l23.864-20.593-19.754-51.178-31.89 0.924zM783.407 139.924l12.364 32.407c2.636 6.89 0.703 14.695-4.856 19.559l-26.195 22.686c1.932 20.661 1.398 41.483-1.602 62.017l25.237 24.22c5.246 5.042 6.797 12.822 3.881 19.492l-31.822 72.746c-2.949 6.746-9.831 10.898-17.169 10.356l-34.864-2.559c-13.025 16.203-28.136 30.61-44.949 42.839l1.025 34.788c0.212 7.356-4.237 14.051-11.102 16.703l-74.042 28.576c-6.839 2.636-14.602 0.695-19.39-4.856l-22.61-26.212c-20.653 1.932-41.458 1.398-61.983-1.602l-24.195 25.246c-5.034 5.254-12.814 6.805-19.483 3.89l-72.746-31.822c-6.737-2.949-10.89-9.839-10.347-17.178l2.559-34.856c-16.203-13.034-30.602-28.161-42.831-44.975l-34.788 1.017c-7.364 0.237-14.068-4.212-16.703-11.093l-28.568-74.042c-2.636-6.839-0.695-14.602 4.856-19.39l26.203-22.61c-1.932-20.644-1.398-41.449 1.602-61.966l-25.229-24.203c-5.263-5.169-6.805-13.042-3.89-19.822l8.305-19.356h-205.364v598.78h954.576v-598.78h-205.881zM224.127 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.737-24.424-52.737-54.458s23.661-54.466 52.737-54.466zM224.127 868.525c9.941 0 18.025-8.864 18.025-19.746s-8.085-19.754-18.025-19.754c-9.932 0-18.025 8.856-18.025 19.746s8.093 19.754 18.025 19.754zM339.093 794.305c29.068 0 52.729 24.432 52.729 54.466s-23.644 54.458-52.729 54.458c-29.085 0-52.72-24.424-52.72-54.458s23.644-54.466 52.72-54.466zM339.093 868.525c9.932 0 18.017-8.864 18.017-19.746s-8.085-19.754-18.017-19.754c-9.941 0-18.008 8.856-18.008 19.746s8.076 19.754 18.008 19.754zM109.161 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.729-24.432-52.729-54.458s23.653-54.466 52.729-54.466zM109.161 868.525c9.932 0 18.025-8.864 18.025-19.746s-8.093-19.754-18.025-19.754c-9.932 0-18.017 8.864-18.017 19.754 0 10.898 8.085 19.746 18.017 19.746zM512 406.958c-92.22 0-166.983-74.763-166.983-166.992 0-92.22 74.763-166.983 166.983-166.983s166.983 74.763 166.983 166.983c-0.102 92.186-74.805 166.881-166.983 166.992zM512 107.695c-73.051 0-132.271 59.22-132.271 132.271 0 73.059 59.22 132.28 132.271 132.28s132.271-59.22 132.271-132.28c-0.076-73.017-59.254-132.186-132.271-132.271zM512 323.381c-46.068 0-83.415-37.347-83.415-83.415 0-46.059 37.347-83.407 83.415-83.407s83.407 37.339 83.407 83.407c-0.051 46.042-37.364 83.356-83.407 83.415v0zM512 191.271c-26.898 0-48.703 21.805-48.703 48.695 0 26.898 21.805 48.703 48.703 48.703s48.695-21.805 48.695-48.703c-0.025-26.881-21.814-48.661-48.695-48.695v0z" /> +<glyph unicode="" glyph-name="icon-comType1-sm" d="M1024 940.966c-0.026 4.551-1.873 8.898-5.136 12.076-3.271 3.169-7.669 4.89-12.22 4.785h-989.288c-4.551 0.113-8.958-1.616-12.22-4.785s-5.119-7.525-5.136-12.076v-817.72c-0.051-9.712 7.644-17.712 17.356-18.034h237.907l8.322-18.678c2.975-6.703 9.864-10.788 17.178-10.178l34.856 2.644c13.034-16.186 28.153-30.576 44.966-42.788l-1.025-34.763c-0.212-7.356 4.237-14.051 11.102-16.695l74.042-28.585c6.839-2.636 14.602-0.695 19.39 4.864l22.602 26.195c20.653-1.924 41.449-1.39 61.975 1.61l24.195-25.237c5.042-5.254 12.814-6.805 19.483-3.89l72.746 31.831c6.737 2.949 10.89 9.831 10.347 17.169l-2.559 34.856c16.203 13.034 30.61 28.161 42.831 44.983l34.788-1.025c7.305-0.39 14.042 3.949 16.703 10.763l2.805 6.924h236.636c9.712 0.331 17.407 8.322 17.356 18.034v633.729c0 0.059 0 0.11 0 0.169s0 0.11 0 0.169v183.653zM989.288 923.11v-149.695h-954.576v149.695h954.576zM707.356 123.525c-5.983 0.195-11.644-2.729-14.949-7.72-12.915-19.39-29.102-36.39-47.839-50.237-4.788-3.534-7.424-9.288-6.992-15.22l2.347-31.915-50.39-22.042-22.127 23.076c-4.034 4.212-9.915 6.11-15.653 5.059-23.093-4.229-46.703-4.839-69.983-1.805-5.788 0.754-11.568-1.458-15.373-5.873l-20.593-23.864-51.178 19.737 0.941 31.898c0.178 5.975-2.746 11.627-7.72 14.949-19.39 12.915-36.39 29.102-50.237 47.839-3.542 4.78-9.288 7.415-15.22 6.983l-31.924-2.339-6.864 15.686c-0.449 1.686-1.153 3.305-2.093 4.788l-13.085 29.915 23.076 22.127c4.212 4.034 6.11 9.915 5.059 15.644-4.229 23.093-4.839 46.703-1.805 69.983 0.746 5.788-1.458 11.568-5.873 15.381l-23.864 20.593 19.737 51.178 31.898-0.941c5.983-0.195 11.644 2.729 14.949 7.72 12.915 19.398 29.102 36.398 47.839 50.237 4.788 3.542 7.424 9.288 6.992 15.229l-2.347 31.915 50.39 22.042 22.136-23.076c4.034-4.212 9.915-6.11 15.644-5.059 23.102 4.229 46.712 4.839 69.992 1.805 5.788-0.746 11.568 1.458 15.381 5.873l20.593 23.864 51.178-19.737-0.941-31.89c-0.178-5.983 2.737-11.636 7.72-14.958 19.39-12.907 36.39-29.102 50.229-47.839 3.542-4.78 9.288-7.415 15.22-6.983l31.915 2.347 22.051-50.39-23.085-22.127c-4.203-4.034-6.102-9.915-5.059-15.644 4.229-23.093 4.839-46.703 1.814-69.983-0.754-5.788 1.449-11.568 5.873-15.381l23.864-20.593-19.754-51.178-31.89 0.924zM783.407 139.924l12.364 32.407c2.636 6.89 0.703 14.695-4.856 19.559l-26.195 22.686c1.932 20.661 1.398 41.483-1.602 62.017l25.237 24.22c5.246 5.042 6.797 12.822 3.881 19.492l-31.822 72.746c-2.949 6.746-9.831 10.898-17.169 10.356l-34.864-2.559c-13.025 16.203-28.136 30.61-44.949 42.839l1.025 34.788c0.212 7.356-4.237 14.051-11.102 16.703l-74.042 28.576c-6.839 2.636-14.602 0.695-19.39-4.856l-22.61-26.212c-20.653 1.932-41.458 1.398-61.983-1.602l-24.195 25.246c-5.034 5.254-12.814 6.805-19.483 3.89l-72.746-31.822c-6.737-2.949-10.89-9.839-10.347-17.178l2.559-34.856c-16.203-13.034-30.602-28.161-42.831-44.975l-34.788 1.017c-7.364 0.237-14.068-4.212-16.703-11.093l-28.568-74.042c-2.636-6.839-0.695-14.602 4.856-19.39l26.203-22.61c-1.932-20.644-1.398-41.449 1.602-61.966l-25.229-24.203c-5.263-5.169-6.805-13.042-3.89-19.822l8.305-19.356h-205.364v598.78h954.576v-598.78h-205.881zM224.127 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.737-24.424-52.737-54.458s23.661-54.466 52.737-54.466zM224.127 868.525c9.941 0 18.025-8.864 18.025-19.746s-8.085-19.754-18.025-19.754c-9.932 0-18.025 8.856-18.025 19.746s8.093 19.754 18.025 19.754zM339.093 794.305c29.068 0 52.729 24.432 52.729 54.466s-23.644 54.458-52.729 54.458c-29.085 0-52.72-24.424-52.72-54.458s23.644-54.466 52.72-54.466zM339.093 868.525c9.932 0 18.017-8.864 18.017-19.746s-8.085-19.754-18.017-19.754c-9.941 0-18.008 8.856-18.008 19.746s8.076 19.754 18.008 19.754zM109.161 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.729-24.432-52.729-54.458s23.653-54.466 52.729-54.466zM109.161 868.525c9.932 0 18.025-8.864 18.025-19.746s-8.093-19.754-18.025-19.754c-9.932 0-18.017 8.864-18.017 19.754 0 10.898 8.085 19.746 18.017 19.746zM512 406.958c-92.22 0-166.983-74.763-166.983-166.992 0-92.22 74.763-166.983 166.983-166.983s166.983 74.763 166.983 166.983c-0.102 92.186-74.805 166.881-166.983 166.992zM512 107.695c-73.051 0-132.271 59.22-132.271 132.271 0 73.059 59.22 132.28 132.271 132.28s132.271-59.22 132.271-132.28c-0.076-73.017-59.254-132.186-132.271-132.271zM512 323.381c-46.068 0-83.415-37.347-83.415-83.415 0-46.059 37.347-83.407 83.415-83.407s83.407 37.339 83.407 83.407c-0.051 46.042-37.364 83.356-83.407 83.415v0zM512 191.271c-26.898 0-48.703 21.805-48.703 48.695 0 26.898 21.805 48.703 48.703 48.703s48.695-21.805 48.695-48.703c-0.025-26.881-21.814-48.661-48.695-48.695v0z" /> +<glyph unicode="" glyph-name="icon-comType2" horiz-adv-x="945" d="M933.258 802.276c-21.462 79.511-181.206 157.724-460.642 157.724s-439.199-78.213-460.642-157.724c-1.557-2.724-2.706-5.708-2.706-9.082v-685.756c0-3.002 0.797-5.838 2.168-8.359 21.889-90.724 217.718-158.447 461.18-158.447 242.906 0 438.42 67.445 461.032 157.835 1.483 2.65 2.317 5.708 2.317 8.97v685.756c0 3.373-1.149 6.357-2.706 9.082zM897.432 330.124c-0.519-2.243-1.242-4.467-2.15-6.728-0.741-1.835-1.65-3.67-2.65-5.505-1.242-2.28-2.632-4.559-4.281-6.839-1.223-1.724-2.613-3.429-4.059-5.134-2.057-2.428-4.244-4.856-6.728-7.265-1.501-1.464-3.151-2.91-4.819-4.374-3.040-2.65-6.209-5.282-9.749-7.895-1.52-1.131-3.151-2.224-4.763-3.336-4.189-2.891-8.563-5.764-13.363-8.581-1.26-0.76-2.613-1.483-3.929-2.224-5.523-3.114-11.287-6.209-17.515-9.211-0.797-0.389-1.631-0.76-2.446-1.131-6.95-3.281-14.216-6.505-21.981-9.619-0.222-0.093-0.445-0.167-0.667-0.259-42.091-16.81-95.932-30.952-158.669-40.219-0.315-0.037-0.63-0.074-0.945-0.13-12.195-1.798-24.706-3.392-37.55-4.8-2.094-0.222-4.3-0.371-6.413-0.593-11.213-1.168-22.556-2.243-34.232-3.095-5.338-0.389-10.935-0.575-16.365-0.908-8.785-0.519-17.478-1.094-26.485-1.409-14.716-0.463-29.728-0.76-45.056-0.76s-30.34 0.297-45.075 0.815c-9.007 0.315-17.7 0.908-26.485 1.409-5.43 0.315-11.028 0.519-16.365 0.908-11.676 0.853-23.019 1.928-34.232 3.095-2.113 0.222-4.318 0.371-6.413 0.593-12.844 1.409-25.354 3.021-37.55 4.8-0.315 0.037-0.63 0.074-0.945 0.13-62.737 9.267-116.578 23.408-158.669 40.219-0.222 0.074-0.445 0.167-0.667 0.259-7.766 3.114-15.050 6.339-21.981 9.619-0.797 0.389-1.65 0.76-2.446 1.131-6.227 3.002-11.991 6.079-17.515 9.211-1.297 0.741-2.669 1.464-3.929 2.224-4.8 2.817-9.174 5.69-13.363 8.581-1.594 1.112-3.243 2.206-4.763 3.336-3.54 2.613-6.709 5.245-9.749 7.895-1.65 1.446-3.318 2.891-4.819 4.374-2.484 2.409-4.671 4.819-6.728 7.265-1.446 1.705-2.836 3.41-4.059 5.134-1.631 2.28-3.021 4.559-4.281 6.839-1.001 1.835-1.89 3.67-2.65 5.505-0.908 2.243-1.631 4.485-2.15 6.728-0.686 2.947-1.446 5.949-1.446 8.933 0 2.094 0.241 4.189 0.575 6.264 0.463 2.799 0.204 5.597-0.575 8.248v137.596c0.519-0.482 1.168-0.945 1.705-1.427 4.040-3.559 8.155-7.098 12.788-10.509 69.817-52.803 209.433-93.837 411.787-93.837 201.501 0 340.765 40.701 410.879 93.189 5.597 4.077 10.638 8.285 15.383 12.566l0.019 0.019v-137.596c-0.778-2.65-1.038-5.449-0.575-8.248 0.352-2.076 0.575-4.17 0.575-6.264 0-2.984-0.76-5.986-1.464-8.989zM898.896 713.628v-137.596c-0.778-2.65-1.038-5.449-0.575-8.248 0.352-2.076 0.575-4.17 0.575-6.264 0-2.984-0.76-5.986-1.464-8.989-0.519-2.243-1.242-4.467-2.15-6.728-0.741-1.835-1.65-3.67-2.65-5.505-1.242-2.28-2.632-4.559-4.281-6.839-1.223-1.724-2.613-3.429-4.059-5.134-2.057-2.428-4.244-4.856-6.728-7.265-1.501-1.464-3.151-2.91-4.819-4.374-3.040-2.65-6.209-5.282-9.749-7.895-1.52-1.131-3.151-2.224-4.763-3.336-4.189-2.891-8.563-5.764-13.363-8.581-1.26-0.76-2.613-1.483-3.929-2.224-5.523-3.114-11.287-6.209-17.515-9.211-0.797-0.389-1.631-0.76-2.446-1.131-6.95-3.281-14.216-6.505-21.981-9.619-0.222-0.093-0.445-0.167-0.667-0.259-42.091-16.81-95.932-30.952-158.669-40.219-0.315-0.037-0.63-0.074-0.945-0.13-12.195-1.798-24.706-3.392-37.55-4.8-2.094-0.222-4.3-0.371-6.413-0.593-11.213-1.168-22.556-2.243-34.232-3.095-5.338-0.389-10.935-0.575-16.365-0.908-8.785-0.519-17.478-1.094-26.485-1.409-14.716-0.463-29.728-0.76-45.056-0.76s-30.34 0.297-45.075 0.815c-9.007 0.315-17.7 0.908-26.485 1.409-5.43 0.315-11.028 0.519-16.365 0.908-11.676 0.853-23.019 1.928-34.232 3.095-2.113 0.222-4.318 0.371-6.413 0.593-12.844 1.409-25.354 3.021-37.55 4.8-0.315 0.037-0.63 0.074-0.945 0.13-62.737 9.267-116.578 23.408-158.669 40.219-0.222 0.074-0.445 0.167-0.667 0.259-7.766 3.114-15.050 6.339-21.981 9.619-0.797 0.389-1.65 0.76-2.446 1.131-6.227 3.002-11.991 6.079-17.515 9.211-1.297 0.741-2.669 1.464-3.929 2.224-4.8 2.817-9.174 5.69-13.363 8.581-1.594 1.112-3.243 2.206-4.763 3.336-3.54 2.613-6.709 5.245-9.749 7.895-1.65 1.446-3.318 2.891-4.819 4.374-2.484 2.409-4.671 4.819-6.728 7.265-1.446 1.705-2.836 3.41-4.059 5.134-1.631 2.28-3.021 4.559-4.281 6.839-1.001 1.835-1.89 3.67-2.65 5.505-0.908 2.243-1.631 4.485-2.15 6.728-0.686 2.947-1.446 5.949-1.446 8.933 0 2.094 0.241 4.189 0.575 6.264 0.463 2.799 0.204 5.597-0.575 8.248v137.596c2.224-2.020 4.763-4.003 7.173-6.005 1.334-1.112 2.576-2.224 3.985-3.336 5.56-4.374 11.565-8.692 18.071-12.9 1.353-0.871 2.873-1.724 4.281-2.595 5.449-3.392 11.213-6.709 17.274-9.971 2.243-1.205 4.485-2.391 6.802-3.577 6.765-3.447 13.863-6.802 21.333-10.045 1.223-0.537 2.335-1.094 3.577-1.612 8.692-3.688 17.922-7.21 27.523-10.62 2.65-0.945 5.43-1.835 8.155-2.762 7.636-2.576 15.531-5.041 23.705-7.432 2.947-0.853 5.838-1.742 8.859-2.558 10.842-3.002 22.037-5.857 33.787-8.489 1.612-0.371 3.355-0.667 4.986-1.019 10.36-2.261 21.11-4.355 32.156-6.32 3.744-0.667 7.543-1.297 11.361-1.928 10.509-1.724 21.333-3.299 32.434-4.745 2.854-0.371 5.579-0.797 8.47-1.149 13.789-1.668 28.060-3.095 42.721-4.318 3.614-0.297 7.377-0.519 11.046-0.778 11.732-0.853 23.723-1.557 35.993-2.113 4.467-0.204 8.915-0.408 13.474-0.575 15.976-0.537 32.249-0.927 49.115-0.927s33.139 0.389 49.115 0.927c4.541 0.167 8.989 0.371 13.474 0.575 12.269 0.556 24.261 1.26 35.993 2.113 3.67 0.278 7.414 0.482 11.046 0.778 14.66 1.205 28.931 2.65 42.721 4.318 2.891 0.352 5.616 0.778 8.47 1.149 11.102 1.446 21.907 3.021 32.434 4.745 3.818 0.63 7.617 1.26 11.361 1.928 11.046 1.965 21.796 4.059 32.156 6.32 1.631 0.352 3.373 0.667 4.986 1.019 11.751 2.632 22.945 5.505 33.787 8.489 3.021 0.834 5.912 1.705 8.859 2.558 8.173 2.391 16.069 4.856 23.705 7.432 2.724 0.927 5.505 1.816 8.155 2.762 9.601 3.41 18.849 6.932 27.523 10.62 1.242 0.519 2.354 1.075 3.577 1.612 7.469 3.262 14.568 6.598 21.333 10.045 2.317 1.186 4.578 2.372 6.802 3.577 6.061 3.243 11.825 6.561 17.274 9.971 1.409 0.871 2.928 1.724 4.281 2.595 6.505 4.207 12.51 8.507 18.071 12.9 1.39 1.112 2.632 2.224 3.985 3.336 2.409 2.002 4.949 3.985 7.173 6.005zM472.615 922.932c251.228 0 426.281-73.246 426.281-139.005s-175.053-139.005-426.281-139.005c-251.228 0-426.281 73.246-426.281 139.005s175.053 139.005 426.281 139.005zM898.896 112.943c-0.259-0.815-0.445-1.65-0.593-2.502-10.509-64.109-184.079-132.74-425.687-132.74s-415.179 68.631-425.687 132.74c-0.148 0.834-0.352 1.65-0.593 2.428v155.945c0.519-0.482 1.168-0.945 1.705-1.427 4.040-3.559 8.155-7.098 12.788-10.509 69.817-52.803 209.433-93.837 411.787-93.837 201.501 0 340.765 40.701 410.879 93.189 5.597 4.077 10.638 8.285 15.383 12.566l0.019 0.019v-155.87z" /> +<glyph unicode="" glyph-name="icon-comType2-sm" horiz-adv-x="926" d="M918.242 804.814c-21.117 78.231-178.291 155.186-453.231 155.186s-432.132-76.955-453.231-155.186c-1.532-2.681-2.662-5.617-2.662-8.936v-674.722c0-2.954 0.784-5.744 2.134-8.224 21.536-89.264 214.215-155.897 453.76-155.897 238.998 0 431.366 66.36 453.614 155.296 1.459 2.608 2.279 5.617 2.279 8.826v674.722c0 3.319-1.131 6.255-2.662 8.936zM882.993 340.259c-0.511-2.207-1.222-4.395-2.115-6.62-0.729-1.805-1.623-3.611-2.608-5.416-1.222-2.243-2.589-4.486-4.212-6.729-1.204-1.696-2.571-3.374-3.994-5.051-2.024-2.389-4.176-4.778-6.62-7.148-1.477-1.441-3.1-2.863-4.741-4.304-2.991-2.608-6.109-5.197-9.592-7.768-1.495-1.112-3.1-2.188-4.687-3.282-4.121-2.845-8.425-5.671-13.148-8.443-1.24-0.748-2.571-1.459-3.866-2.188-5.434-3.064-11.106-6.109-17.233-9.063-0.784-0.383-1.605-0.748-2.407-1.112-6.838-3.228-13.987-6.401-21.628-9.464-0.219-0.091-0.438-0.164-0.656-0.255-41.413-16.54-94.388-30.454-156.116-39.572-0.31-0.036-0.62-0.073-0.93-0.128-11.999-1.769-24.308-3.337-36.946-4.723-2.061-0.219-4.231-0.365-6.31-0.584-11.033-1.149-22.193-2.207-33.681-3.045-5.252-0.383-10.759-0.565-16.102-0.894-8.644-0.511-17.196-1.076-26.059-1.386-14.479-0.456-29.25-0.748-44.331-0.748s-29.852 0.292-44.349 0.802c-8.863 0.31-17.415 0.894-26.059 1.386-5.343 0.31-10.85 0.511-16.102 0.894-11.489 0.839-22.649 1.897-33.681 3.045-2.079 0.219-4.249 0.365-6.31 0.584-12.637 1.386-24.946 2.972-36.946 4.723-0.31 0.036-0.62 0.073-0.93 0.128-61.728 9.118-114.703 23.032-156.116 39.572-0.219 0.073-0.438 0.164-0.656 0.255-7.641 3.064-14.807 6.237-21.628 9.464-0.784 0.383-1.623 0.748-2.407 1.112-6.127 2.954-11.799 5.981-17.233 9.063-1.277 0.729-2.626 1.441-3.866 2.188-4.723 2.772-9.027 5.598-13.148 8.443-1.568 1.094-3.191 2.17-4.687 3.282-3.483 2.571-6.601 5.161-9.592 7.768-1.623 1.422-3.264 2.845-4.741 4.304-2.444 2.371-4.595 4.741-6.62 7.148-1.422 1.678-2.79 3.355-3.994 5.051-1.605 2.243-2.972 4.486-4.212 6.729-0.985 1.805-1.86 3.611-2.608 5.416-0.894 2.207-1.605 4.413-2.115 6.62-0.675 2.899-1.422 5.854-1.422 8.79 0 2.061 0.237 4.121 0.565 6.164 0.456 2.754 0.201 5.507-0.565 8.115v135.382c0.511-0.474 1.149-0.93 1.678-1.404 3.975-3.501 8.024-6.984 12.583-10.34 68.694-51.954 206.064-92.328 405.162-92.328 198.259 0 335.282 40.046 404.268 91.689 5.507 4.012 10.467 8.151 15.136 12.364l0.018 0.018v-135.382c-0.766-2.608-1.021-5.361-0.565-8.115 0.346-2.042 0.565-4.103 0.565-6.164 0-2.936-0.748-5.89-1.441-8.844zM884.433 717.592v-135.382c-0.766-2.608-1.021-5.361-0.565-8.115 0.346-2.042 0.565-4.103 0.565-6.164 0-2.936-0.748-5.89-1.441-8.844-0.511-2.207-1.222-4.395-2.115-6.62-0.729-1.805-1.623-3.611-2.608-5.416-1.222-2.243-2.589-4.486-4.212-6.729-1.204-1.696-2.571-3.374-3.994-5.051-2.024-2.389-4.176-4.778-6.62-7.148-1.477-1.441-3.1-2.863-4.741-4.304-2.991-2.608-6.109-5.197-9.592-7.768-1.495-1.112-3.1-2.188-4.687-3.282-4.121-2.845-8.425-5.671-13.148-8.443-1.24-0.748-2.571-1.459-3.866-2.188-5.434-3.064-11.106-6.109-17.233-9.063-0.784-0.383-1.605-0.748-2.407-1.112-6.838-3.228-13.987-6.401-21.628-9.464-0.219-0.091-0.438-0.164-0.656-0.255-41.413-16.54-94.388-30.454-156.116-39.572-0.31-0.036-0.62-0.073-0.93-0.128-11.999-1.769-24.308-3.337-36.946-4.723-2.061-0.219-4.231-0.365-6.31-0.584-11.033-1.149-22.193-2.207-33.681-3.045-5.252-0.383-10.759-0.565-16.102-0.894-8.644-0.511-17.196-1.076-26.059-1.386-14.479-0.456-29.25-0.748-44.331-0.748s-29.852 0.292-44.349 0.802c-8.863 0.31-17.415 0.894-26.059 1.386-5.343 0.31-10.85 0.511-16.102 0.894-11.489 0.839-22.649 1.897-33.681 3.045-2.079 0.219-4.249 0.365-6.31 0.584-12.637 1.386-24.946 2.972-36.946 4.723-0.31 0.036-0.62 0.073-0.93 0.128-61.728 9.118-114.703 23.032-156.116 39.572-0.219 0.073-0.438 0.164-0.656 0.255-7.641 3.064-14.807 6.237-21.628 9.464-0.784 0.383-1.623 0.748-2.407 1.112-6.127 2.954-11.799 5.981-17.233 9.063-1.277 0.729-2.626 1.441-3.866 2.188-4.723 2.772-9.027 5.598-13.148 8.443-1.568 1.094-3.191 2.17-4.687 3.282-3.483 2.571-6.601 5.161-9.592 7.768-1.623 1.422-3.264 2.845-4.741 4.304-2.444 2.371-4.595 4.741-6.62 7.148-1.422 1.678-2.79 3.355-3.994 5.051-1.605 2.243-2.972 4.486-4.212 6.729-0.985 1.805-1.86 3.611-2.608 5.416-0.894 2.207-1.605 4.413-2.115 6.62-0.675 2.899-1.422 5.854-1.422 8.79 0 2.061 0.237 4.121 0.565 6.164 0.456 2.754 0.201 5.507-0.565 8.115v135.382c2.188-1.988 4.687-3.939 7.057-5.908 1.313-1.094 2.535-2.188 3.921-3.282 5.471-4.304 11.379-8.553 17.78-12.692 1.331-0.857 2.827-1.696 4.212-2.553 5.361-3.337 11.033-6.601 16.996-9.811 2.207-1.185 4.413-2.352 6.693-3.519 6.656-3.392 13.64-6.693 20.989-9.884 1.204-0.529 2.298-1.076 3.519-1.587 8.553-3.629 17.634-7.094 27.080-10.449 2.608-0.93 5.343-1.805 8.024-2.717 7.513-2.535 15.282-4.96 23.324-7.313 2.899-0.839 5.744-1.714 8.717-2.517 10.668-2.954 21.682-5.762 33.244-8.352 1.587-0.365 3.301-0.656 4.905-1.003 10.194-2.225 20.771-4.285 31.639-6.218 3.684-0.656 7.422-1.277 11.179-1.897 10.34-1.696 20.989-3.246 31.913-4.668 2.808-0.365 5.489-0.784 8.334-1.131 13.567-1.641 27.609-3.045 42.033-4.249 3.556-0.292 7.258-0.511 10.868-0.766 11.543-0.839 23.342-1.532 35.414-2.079 4.395-0.201 8.771-0.401 13.257-0.565 15.719-0.529 31.73-0.912 48.325-0.912s32.605 0.383 48.325 0.912c4.468 0.164 8.844 0.365 13.257 0.565 12.072 0.547 23.871 1.24 35.414 2.079 3.611 0.274 7.294 0.474 10.869 0.766 14.424 1.185 28.466 2.608 42.033 4.249 2.845 0.346 5.525 0.766 8.334 1.131 10.923 1.422 21.555 2.972 31.913 4.668 3.757 0.62 7.495 1.24 11.179 1.897 10.869 1.933 21.445 3.994 31.639 6.218 1.605 0.346 3.319 0.656 4.905 1.003 11.561 2.589 22.576 5.416 33.244 8.352 2.972 0.821 5.817 1.678 8.717 2.517 8.042 2.352 15.81 4.778 23.324 7.313 2.681 0.912 5.416 1.787 8.024 2.717 9.446 3.355 18.546 6.82 27.080 10.449 1.222 0.511 2.316 1.058 3.519 1.587 7.349 3.209 14.333 6.492 20.989 9.884 2.279 1.167 4.504 2.334 6.693 3.519 5.963 3.191 11.634 6.455 16.996 9.811 1.386 0.857 2.881 1.696 4.212 2.553 6.401 4.14 12.309 8.37 17.78 12.692 1.368 1.094 2.589 2.188 3.921 3.282 2.371 1.969 4.869 3.921 7.057 5.908zM465.011 923.529c247.185 0 419.422-72.068 419.422-136.768s-172.237-136.768-419.422-136.768c-247.185 0-419.422 72.068-419.422 136.768s172.237 136.768 419.422 136.768zM884.433 126.572c-0.255-0.802-0.438-1.623-0.584-2.462-10.34-63.077-181.117-130.604-418.838-130.604s-408.499 67.527-418.838 130.604c-0.146 0.821-0.346 1.623-0.584 2.389v153.435c0.511-0.474 1.149-0.93 1.678-1.404 3.975-3.501 8.024-6.984 12.583-10.34 68.694-51.954 206.064-92.328 405.162-92.328 198.259 0 335.282 40.046 404.268 91.689 5.507 4.012 10.467 8.151 15.136 12.364l0.018 0.018v-153.363z" /> +<glyph unicode="" glyph-name="icon-comType3" horiz-adv-x="1053" d="M184.32 853.463c-43.552 0-78.994-35.442-78.994-78.994s35.442-78.994 78.994-78.994c43.552 0 78.994 35.442 78.994 78.994s-35.442 78.994-78.994 78.994zM184.32 730.583c-24.19 0-43.886 19.678-43.886 43.886s19.696 43.886 43.886 43.886c24.19 0 43.886-19.678 43.886-43.886s-19.696-43.886-43.886-43.886zM906.971 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM836.754 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM942.080 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM871.863 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM766.537 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM801.646 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM696.32 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM731.429 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM626.103 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM661.211 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM1053.257 671.056v206.842c0 44.605-36.285 80.89-80.89 80.89h-891.477c-44.605 0-80.89-36.285-80.89-80.89v-206.842c0-25.787 12.341-48.52 31.194-63.336-18.853-14.833-31.194-37.566-31.194-63.353v-206.842c0-44.605 36.285-80.89 80.89-80.89h891.477c44.605 0 80.89 36.285 80.89 80.89v206.842c0 25.787-12.341 48.52-31.194 63.336 18.853 14.833 31.194 37.566 31.194 63.353zM1018.149 544.367v-206.842c0-25.243-20.539-45.782-45.782-45.782h-891.477c-25.243-0.018-45.782 20.521-45.782 45.782v206.842c0 25.243 20.539 45.782 45.782 45.782h891.459c25.261 0 45.799-20.539 45.799-45.782zM80.89 625.257c-25.243 0-45.782 20.539-45.782 45.799v206.842c0 25.243 20.539 45.782 45.782 45.782h891.459c25.261 0 45.799-20.539 45.799-45.782v-206.842c0-25.243-20.539-45.782-45.782-45.782l-891.477-0.018zM184.32 361.943c43.552 0 78.994 35.442 78.994 78.994s-35.442 78.994-78.994 78.994c-43.552 0-78.994-35.425-78.994-78.994s35.442-78.994 78.994-78.994zM184.32 484.823c24.19 0 43.886-19.678 43.886-43.886s-19.696-43.886-43.886-43.886c-24.19 0-43.886 19.678-43.886 43.886s19.696 43.886 43.886 43.886zM552.486 74.299c4.020-2.265 7.706-5.056 10.989-8.268 3.423-3.353 7.864-5.021 12.288-5.021 4.547 0 9.093 1.773 12.534 5.266 6.794 6.934 6.671 18.028-0.246 24.822-5.459 5.354-11.586 9.953-18.239 13.745-8.479 4.757-19.152 1.843-23.926-6.618-4.775-8.426-1.826-19.134 6.6-23.926zM553.030-17.177c-3.95-2.317-8.198-4.073-12.622-5.266-9.356-2.528-14.904-12.148-12.393-21.522 2.124-7.829 9.198-12.99 16.94-12.99 1.51 0 3.037 0.193 4.582 0.597 7.408 2.001 14.535 4.968 21.153 8.83 8.373 4.88 11.217 15.641 6.337 24.014-4.88 8.391-15.623 11.2-23.997 6.337zM596.846 46.387c-9.69 0-17.554-8.268-17.554-17.958 0-4.634-0.597-9.198-1.773-13.605-2.51-9.356 3.072-18.976 12.428-21.486 1.51-0.404 3.037-0.597 4.529-0.597 7.759 0 14.851 5.179 16.957 13.025 1.966 7.338 2.967 14.974 2.967 22.645v0.825c0 9.708-7.864 17.151-17.554 17.151zM500.473-17.282c-3.985 2.282-7.654 5.073-10.901 8.303-6.881 6.846-17.976 6.776-24.822-0.070-6.846-6.881-6.811-17.993 0.070-24.822 5.442-5.407 11.568-10.076 18.221-13.885 2.756-1.58 5.74-2.317 8.707-2.317 6.091 0 12.007 3.177 15.255 8.83 4.792 8.409 1.878 19.134-6.53 23.962zM503.229 113.006c-7.373-2.019-14.465-5.038-21.065-8.918-8.356-4.915-11.147-15.676-6.232-24.032 3.283-5.547 9.146-8.654 15.149-8.654 3.019 0 6.091 0.772 8.882 2.422 3.967 2.335 8.198 4.125 12.622 5.354 9.339 2.563 14.833 12.235 12.253 21.574-2.598 9.339-12.253 14.798-21.609 12.253zM473.966 28.412c0 4.529 0.579 9.005 1.703 13.324 2.44 9.374-3.177 18.959-12.569 21.416-9.392 2.422-18.976-3.177-21.416-12.569-1.878-7.197-2.826-14.658-2.826-22.54l17.554-0.035h-17.554c0-9.708 7.847-17.344 17.554-17.344 9.708-0.018 17.554 8.040 17.554 17.747zM906.971 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM836.754 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM942.080 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM871.863 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM766.537 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM801.646 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM696.32 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM731.429 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM626.103 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM661.211 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM386.194 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM245.76 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM315.977 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM35.109 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM105.326 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM175.543 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM684.617 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM825.051 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM754.834 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM1035.703 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM895.269 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM965.486 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM544.183 151.292v17.554c0 9.708-7.864 17.554-17.554 17.554s-17.554-7.847-17.554-17.554v-17.554c0-9.708 7.864-17.554 17.554-17.554s17.554 7.847 17.554 17.554zM509.074 239.063v-17.554c0-9.708 7.864-17.554 17.554-17.554s17.554 7.847 17.554 17.554v17.554c0 9.708-7.864 17.554-17.554 17.554s-17.554-7.847-17.554-17.554z" /> +<glyph unicode="" glyph-name="icon-comType3-sm" d="M179.2 856.422c-42.342 0-76.8-34.458-76.8-76.8s34.458-76.8 76.8-76.8c42.342 0 76.8 34.458 76.8 76.8s-34.458 76.8-76.8 76.8zM179.2 736.956c-23.518 0-42.667 19.132-42.667 42.667s19.149 42.667 42.667 42.667c23.518 0 42.667-19.132 42.667-42.667s-19.149-42.667-42.667-42.667zM904.533 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM836.267 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM938.667 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM870.4 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM768 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM802.133 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM699.733 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM733.867 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM631.467 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM665.6 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM1024 679.083v201.097c0 43.366-35.277 78.643-78.643 78.643h-866.714c-43.366 0-78.643-35.277-78.643-78.643v-201.097c0-25.071 11.998-47.172 30.327-61.577-18.33-14.421-30.327-36.523-30.327-61.594v-201.097c0-43.366 35.277-78.643 78.643-78.643h866.714c43.366 0 78.643 35.277 78.643 78.643v201.097c0 25.071-11.998 47.172-30.327 61.577 18.33 14.421 30.327 36.523 30.327 61.594zM989.867 555.913v-201.097c0-24.542-19.968-44.51-44.51-44.51h-866.714c-24.542-0.017-44.51 19.951-44.51 44.51v201.097c0 24.542 19.968 44.51 44.51 44.51h866.697c24.559 0 44.527-19.968 44.527-44.51zM78.643 634.556c-24.542 0-44.51 19.968-44.51 44.527v201.097c0 24.542 19.968 44.51 44.51 44.51h866.697c24.559 0 44.527-19.968 44.527-44.51v-201.097c0-24.542-19.968-44.51-44.51-44.51l-866.714-0.017zM179.2 378.556c42.342 0 76.8 34.458 76.8 76.8s-34.458 76.8-76.8 76.8c-42.342 0-76.8-34.441-76.8-76.8s34.458-76.8 76.8-76.8zM179.2 498.022c23.518 0 42.667-19.132 42.667-42.667s-19.149-42.667-42.667-42.667c-23.518 0-42.667 19.132-42.667 42.667s19.149 42.667 42.667 42.667zM537.139 98.901c3.908-2.202 7.492-4.915 10.684-8.038 3.328-3.26 7.646-4.881 11.947-4.881 4.42 0 8.841 1.724 12.186 5.12 6.605 6.741 6.485 17.527-0.239 24.132-5.308 5.205-11.264 9.677-17.732 13.363-8.243 4.625-18.62 1.792-23.262-6.434-4.642-8.192-1.775-18.603 6.417-23.262zM537.668 9.967c-3.84-2.253-7.97-3.959-12.271-5.12-9.097-2.458-14.49-11.81-12.049-20.924 2.065-7.612 8.943-12.629 16.469-12.629 1.468 0 2.953 0.188 4.454 0.58 7.202 1.946 14.131 4.83 20.565 8.585 8.141 4.745 10.906 15.206 6.161 23.347-4.745 8.158-15.189 10.889-23.33 6.161zM580.267 71.765c-9.421 0-17.067-8.038-17.067-17.459 0-4.506-0.58-8.943-1.724-13.227-2.441-9.097 2.987-18.449 12.083-20.89 1.468-0.393 2.953-0.58 4.403-0.58 7.543 0 14.438 5.035 16.486 12.663 1.911 7.134 2.884 14.558 2.884 22.016v0.802c0 9.438-7.646 16.674-17.067 16.674zM486.571 9.865c-3.874 2.219-7.441 4.932-10.598 8.073-6.69 6.656-17.476 6.588-24.132-0.068-6.656-6.69-6.622-17.493 0.068-24.132 5.291-5.257 11.247-9.796 17.715-13.5 2.679-1.536 5.581-2.253 8.465-2.253 5.922 0 11.674 3.089 14.831 8.585 4.659 8.175 1.826 18.603-6.349 23.296zM489.25 136.533c-7.168-1.963-14.063-4.898-20.48-8.67-8.124-4.779-10.837-15.241-6.059-23.364 3.191-5.393 8.892-8.414 14.729-8.414 2.935 0 5.922 0.751 8.636 2.355 3.857 2.27 7.97 4.011 12.271 5.205 9.079 2.492 14.421 11.895 11.913 20.975-2.526 9.079-11.913 14.387-21.009 11.913zM460.8 54.289c0 4.403 0.563 8.755 1.655 12.954 2.372 9.114-3.089 18.432-12.22 20.821-9.131 2.355-18.449-3.089-20.821-12.22-1.826-6.997-2.748-14.251-2.748-21.914v-0.034c0-9.438 7.629-16.862 17.067-16.862 9.438-0.017 17.067 7.817 17.067 17.254zM904.533 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM836.267 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM938.667 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM870.4 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM768 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM802.133 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM699.733 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM733.867 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM631.467 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM665.6 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM375.467 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM238.933 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM307.2 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM34.133 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM102.4 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM170.667 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM665.6 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM802.133 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM733.867 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM1006.933 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM870.4 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM938.667 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM529.067 173.756v17.067c0 9.438-7.646 17.067-17.067 17.067s-17.067-7.629-17.067-17.067v-17.067c0-9.438 7.646-17.067 17.067-17.067s17.067 7.629 17.067 17.067zM494.933 259.089v-17.067c0-9.438 7.646-17.067 17.067-17.067s17.067 7.629 17.067 17.067v17.067c0 9.438-7.646 17.067-17.067 17.067s-17.067-7.629-17.067-17.067z" /> +<glyph unicode="" glyph-name="icon-comType4-sm" d="M512 960c-282.767 0-512-229.233-512-512s229.233-512 512-512c282.767 0 512 229.233 512 512-0.317 282.633-229.367 511.683-512 512zM954.808 268.633l-145.608-25.125c16.667 61.125 25.667 124.083 26.792 187.425h153.45c-1.925-55.717-13.65-110.658-34.633-162.3v0zM34.558 430.933h153.45c1.125-63.342 10.125-126.3 26.792-187.425l-145.608 25.125c-20.983 51.642-32.708 106.583-34.633 162.3zM69.192 627.367l145.608 25.125c-16.667-61.125-25.667-124.083-26.792-187.425h-153.45c1.925 55.717 13.65 110.658 34.633 162.3zM529.067 685.975c61.325-0.783 122.5-6.367 182.958-16.708l60.242-10.392c18.508-62.983 28.467-128.167 29.608-193.808h-272.808v220.908zM717.842 702.908c-62.375 10.658-125.5 16.417-188.775 17.2v204.8c97.842-9.4 182.833-98.983 231-229.358l-42.225 7.358zM494.933 720.108c-63.275-0.783-126.383-6.542-188.758-17.2l-42.242-7.308c48.167 130.408 133.158 220.025 231 229.383v-204.875zM311.992 669.267c60.45 10.342 121.617 15.925 182.942 16.708v-220.908h-272.808c1.142 65.642 11.1 130.825 29.608 193.808l60.258 10.392zM222.125 430.933h272.808v-220.908c-61.325 0.783-122.5 6.367-182.958 16.708l-60.242 10.392c-18.508 62.983-28.467 128.167-29.608 193.808v0zM306.158 193.092c62.375-10.675 125.492-16.458 188.775-17.292v-204.8c-97.842 9.408-182.833 98.992-231 229.367l42.225-7.275zM529.067 175.8c63.275 0.833 126.383 6.617 188.758 17.292l42.242 7.308c-48.167-130.408-133.158-220.025-231-229.383v204.783zM712.008 226.733c-60.45-10.342-121.617-15.925-182.942-16.708v220.908h272.808c-1.142-65.642-11.1-130.825-29.608-193.808l-60.258-10.392zM835.992 465.067c-1.125 63.342-10.125 126.3-26.792 187.425l145.608-25.125c20.983-51.642 32.708-106.583 34.633-162.3h-153.45zM937.542 664.983l-139.575 24.083c-25.092 81.858-72.033 155.325-135.783 212.483 119.208-39.783 218.067-124.708 275.358-236.567zM361.817 901.55c-63.75-57.158-110.692-130.625-135.783-212.483l-139.575-24.083c57.292 111.858 156.15 196.783 275.358 236.567zM86.458 231.017l139.575-24.083c25.092-81.858 72.033-155.325 135.783-212.483-119.208 39.783-218.067 124.708-275.358 236.567zM662.183-5.55c63.75 57.158 110.692 130.625 135.783 212.483l139.575 24.083c-57.292-111.858-156.15-196.783-275.358-236.567z" /> +<glyph unicode="" glyph-name="icon-create-white" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-206.769v-216.615c0-21.74-17.644-39.385-39.385-39.385s-39.385 17.644-39.385 39.385v216.615h-206.769c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h206.769v196.923c0 21.74 17.644 39.385 39.385 39.385s39.385-17.644 39.385-39.385v-196.923h206.769c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="" glyph-name="icon-delete-sm" horiz-adv-x="768" d="M76.189 89.99c0-56.431 46.171-102.602 102.602-102.602h410.413c56.431 0 102.602 46.171 102.602 102.602v615.621h-615.621v-615.621zM743.112 859.515h-179.556l-51.301 51.301h-256.51l-51.301-51.301h-179.556v-102.602h718.224v102.602z" /> +<glyph unicode="" glyph-name="icon-deploy-inactive" d="M890.522 252.945l-95.505-137.216-67.396 55.313c-7.27 5.99-18.039 4.898-24.013-2.355-5.99-7.287-4.932-18.057 2.372-24.013l81.681-67.055c3.072-2.526 6.895-3.891 10.82-3.891 0.768 0 1.553 0.051 2.338 0.171 4.71 0.649 8.943 3.243 11.674 7.151l106.052 152.388c5.376 7.731 3.482 18.364-4.267 23.757-7.748 5.461-18.364 3.516-23.757-4.25zM802.133 379.733c-122.334 0-221.867-99.533-221.867-221.867s99.533-221.867 221.867-221.867c122.334 0 221.867 99.533 221.867 221.867s-99.533 221.867-221.867 221.867zM802.133-29.867c-103.509 0-187.733 84.224-187.733 187.733s84.224 187.733 187.733 187.733c103.509 0 187.733-84.224 187.733-187.733s-84.224-187.733-187.733-187.733zM945.357 960h-866.714c-43.366 0-78.643-35.277-78.643-78.643v-201.097c0-16.623 5.359-31.898 14.251-44.527h995.482c8.909 12.629 14.268 27.904 14.268 44.51v201.114c0 43.366-35.277 78.643-78.643 78.643zM179.2 704c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM580.267 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM614.4 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM648.533 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM682.667 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM716.8 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM750.933 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM785.067 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM819.2 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM853.333 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM887.467 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM529.067 157.867c0 42.871 10.206 83.319 27.904 119.467h-542.72c-8.892-12.629-14.251-27.904-14.251-44.51v-201.097c0-43.383 35.277-78.66 78.643-78.66h543.471c-56.9 50.091-93.047 123.221-93.047 204.8zM179.2 55.467c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM14.251 601.6c-8.892-12.629-14.251-27.904-14.251-44.51v-201.097c0-16.623 5.359-31.898 14.251-44.527h562.278c49.22 72.055 131.959 119.467 225.587 119.467 87.433 0 165.205-41.472 215.211-105.609 4.147 9.421 6.656 19.695 6.656 30.652v201.114c0 16.623-5.359 31.881-14.251 44.51h-995.482zM179.2 379.733c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM580.267 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM648.533 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM716.8 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM785.067 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM853.333 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067z" /> +<glyph unicode="" glyph-name="icon-discard-sm" horiz-adv-x="1479" d="M758.634 737.255c-186.485 0-356.399-69.445-486.48-183.313l-253.815 253.815v-634.538h634.538l-254.874 254.874c97.649 82.136 222.794 132.9 360.628 132.9 249.937 0 461.451-162.512 535.483-387.773l166.743 54.991c-96.943 295.415-374.38 509.042-702.224 509.042z" /> +<glyph unicode="" glyph-name="icon-download" horiz-adv-x="887" d="M659.932 832.548v100.566l154.573-154.573h-100.566c-29.811 0.046-53.986 24.196-54.007 54.007zM585.477 364.458h-69.576c-9.948 0-18.011 8.062-18.011 18.011v198.042h-108.014v-198.042c0-9.948-8.062-18.011-18.011-18.011h-69.576l141.594-169.897 141.594 169.897zM47.825 4.396v900.156c0.046 29.811 24.196 53.986 54.007 54.007h522.086v-126.024c0.059-49.702 40.326-89.969 90.021-90.021h126.024v-738.132c-0.046-29.811-24.196-53.986-54.007-54.007h-684.124c-29.811 0.046-53.986 24.196-54.007 54.007zM353.88 670.511c0-9.948 8.062-18.011 18.011-18.011h144.035c9.948 0 18.011 8.062 18.011 18.011s-8.062 18.011-18.011 18.011h-144.035c-9.948 0-18.011-8.062-18.011-18.011zM250.034 370.934l180.031-216.028c3.413-4.101 8.495-6.483 13.819-6.483s10.405 2.382 13.819 6.483l180.031 216.028c4.472 5.362 5.429 12.843 2.466 19.159s-9.321 10.379-16.31 10.379h-90.021v198.042c0 9.948-8.062 18.011-18.011 18.011h-144.035c-9.948 0-18.011-8.062-18.011-18.011v-198.042h-90.021c-6.989 0-13.347-4.038-16.31-10.379s-2.006-13.797 2.466-19.159z" /> +<glyph unicode="" glyph-name="icon-drag" horiz-adv-x="372" d="M169.58 837.675c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM169.58 588.944c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM169.58 340.219c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM169.58 91.487c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 837.675c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 588.944c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 340.219c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 91.487c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908z" /> +<glyph unicode="" glyph-name="icon-edit" d="M0 152.176v-216.178h216.178l625.778 631.467-216.178 216.178-625.778-631.467zM1006.933 732.442c22.756 22.756 22.756 56.889 0 79.644l-130.844 130.847c-22.756 22.756-56.889 22.756-79.644 0l-102.4-102.4 216.178-216.178 96.711 108.087z" /> +<glyph unicode="" glyph-name="icon-file-code" horiz-adv-x="768" d="M512 960h-512v-1024h768v768l-256 256zM448 640h256v-640h-640v896h384v-256zM512 704v192l192-192h-192zM268.8 128h-44.8l-128 160 128 160h44.8l-128-160zM499.2 128h44.8l128 160-128 160h-44.8l128-160zM300.8 64h38.4l134.4 448h-51.2z" /> +<glyph unicode="" glyph-name="icon-import-blue" horiz-adv-x="1434" d="M1158.827 601.6c-41.813 203.093-221.013 358.4-442.027 358.4-173.227 0-322.56-95.573-394.24-238.933-185.173-23.893-322.56-173.227-322.56-358.4 0-197.12 161.28-358.4 358.4-358.4h776.533c167.253 0 298.667 131.413 298.667 298.667 0 155.307-125.44 286.72-274.773 298.667zM836.267 422.4v-238.933h-238.933v238.933h-179.2l298.667 298.667 298.667-298.667h-179.2z" /> +<glyph unicode="" glyph-name="icon-info" d="M503.979 944c-278.315 0-503.979-225.664-503.979-503.979s225.664-504.021 503.979-504.021c278.315 0 504.021 225.707 504.021 504.021s-225.707 503.979-504.021 503.979zM608.896 162.901c-25.941-10.24-46.592-18.005-62.080-23.381-15.445-5.376-33.408-8.064-53.845-8.064-31.403 0-55.851 7.68-73.259 22.997s-26.069 34.731-26.069 58.325c0 9.173 0.64 18.56 1.92 28.117 1.323 9.557 3.413 20.309 6.272 32.384l32.469 114.688c2.859 11.008 5.333 21.461 7.296 31.189 1.963 9.813 2.901 18.816 2.901 27.008 0 14.592-3.029 24.832-9.045 30.592-6.101 5.76-17.579 8.576-34.688 8.576-8.363 0-16.981-1.237-25.813-3.84-8.747-2.688-16.341-5.12-22.571-7.509l8.576 35.328c21.248 8.661 41.6 16.085 61.013 22.229 19.413 6.229 37.76 9.301 55.040 9.301 31.189 0 55.253-7.595 72.192-22.613 16.853-15.061 25.344-34.645 25.344-58.709 0-4.992-0.597-13.781-1.749-26.325-1.152-12.587-3.328-24.064-6.485-34.603l-32.299-114.347c-2.645-9.173-4.992-19.669-7.125-31.403-2.091-11.733-3.115-20.693-3.115-26.709 0-15.189 3.371-25.557 10.197-31.061 6.741-5.504 18.56-8.277 35.285-8.277 7.893 0 16.725 1.408 26.709 4.139 9.899 2.731 17.067 5.163 21.589 7.253l-8.661-35.285zM603.179 627.029c-15.061-13.995-33.195-20.992-54.4-20.992-21.163 0-39.424 6.997-54.613 20.992-15.104 13.995-22.741 31.019-22.741 50.901 0 19.84 7.68 36.907 22.741 51.029 15.189 14.165 33.451 21.205 54.613 21.205 21.205 0 39.381-7.040 54.4-21.205 15.061-14.123 22.613-31.189 22.613-51.029 0-19.925-7.552-36.907-22.613-50.901z" /> +<glyph unicode="" glyph-name="icon-menuDots" horiz-adv-x="4437" d="M1813.333 448c0 282.77 229.23 512 512 512s512-229.23 512-512c0-282.77-229.23-512-512-512s-512 229.23-512 512zM277.333 448c0 282.77 229.23 512 512 512s512-229.23 512-512c0-282.77-229.23-512-512-512s-512 229.23-512 512zM3413.333 448c0 282.77 229.23 512 512 512s512-229.23 512-512c0-282.77-229.23-512-512-512s-512 229.23-512 512z" /> +<glyph unicode="" glyph-name="icon-nav-dictionary" d="M991.457 533.163c-13.803 0-24.993-11.19-24.993-24.993v-203.273c0-13.803 11.19-24.993 24.993-24.993s24.993 11.19 24.993 24.993v203.273c-0.003 13.803-11.193 24.993-24.993 24.993v0zM960.173 959.5h-856.973c-56.907 0-103.2-34.087-103.2-75.984v-835.988c0-48.869 54-88.628 120.377-88.628h799.807c13.6 0 25.733 5.969 30.91 15.209 5.203 9.287 2.297 19.877-7.403 26.98-16.927 12.389-26.247 28.882-26.247 46.439 0 20.432 12.837 39.437 34.62 51.827h8.11c31.030 0 56.277 18.586 56.277 41.435v194.1c0 10.163-11.19 18.402-24.993 18.402s-24.993-8.239-24.993-18.402v-194.1c0-2.555-2.82-4.631-6.29-4.631h-839.797c-25.133 0-50.023-5.925-70.39-16.77v764.128c0 21.602 23.87 39.18 53.213 39.18h856.973c3.47 0 6.29-2.076 6.29-4.631v-144.885c0-10.163 11.19-18.402 24.993-18.402s24.993 8.239 24.993 18.402v144.885c0 22.847-25.247 41.435-56.277 41.435v0zM886.563 99.357c-12.343-15.459-19.107-33.27-19.107-51.829 0-18.522 6.64-36.286 19.090-51.827h-766.17c-38.813 0-70.39 23.249-70.39 51.827s31.577 51.827 70.39 51.827l766.187 0.002zM348.708 760.797c-53.594 0-97.198-43.604-97.198-97.198v-217.009c0-53.594 43.604-97.198 97.198-97.198h319.034c53.594 0 97.198 43.604 97.198 97.198v217.009c0 53.594-43.604 97.198-97.198 97.198h-319.034zM723.265 663.599v-217.009c0-30.617-24.909-55.523-55.523-55.523h-319.034c-30.617 0-55.526 24.909-55.526 55.523v217.009c0 30.617 24.909 55.526 55.526 55.526h319.034c30.617 0 55.523-24.909 55.523-55.526v0zM627.88 590.463c-6.871 0-9.357 1.746-14.802 5.569-7.384 5.184-17.496 12.282-36.054 12.282s-28.67-7.1-36.054-12.282c-5.445-3.823-7.931-5.569-14.802-5.569s-9.357 1.746-14.802 5.569c-7.384 5.184-17.498 12.282-36.054 12.282s-28.668-7.1-36.049-12.284c-5.445-3.823-7.931-5.569-14.8-5.569s-9.354 1.744-14.797 5.569c-7.384 5.184-17.496 12.284-36.052 12.284-10.213 0-18.492-8.279-18.492-18.492s8.279-18.492 18.492-18.492c6.869 0 9.354-1.744 14.797-5.569 7.384-5.184 17.496-12.284 36.052-12.284s28.668 7.1 36.052 12.284c5.443 3.823 7.929 5.569 14.797 5.569 6.871 0 9.357-1.746 14.805-5.569 7.384-5.184 17.498-12.282 36.054-12.282s28.668 7.1 36.054 12.282c5.445 3.823 7.931 5.569 14.805 5.569s9.357-1.746 14.802-5.569c7.384-5.184 17.496-12.282 36.054-12.282 10.213 0 18.492 8.279 18.492 18.492s-8.284 18.492-18.497 18.492v0zM497.633 493.266c-5.575 0-7.592 1.417-12.010 4.518-5.991 4.206-14.195 9.965-29.253 9.965s-23.262-5.761-29.253-9.965c-4.418-3.102-6.435-4.518-12.010-4.518s-7.592 1.417-12.012 4.518c-5.991 4.206-14.197 9.965-29.253 9.965-8.286 0-15.004-6.717-15.004-15.004s6.717-15.004 15.004-15.004c5.575 0 7.592-1.417 12.010-4.518 5.991-4.206 14.197-9.965 29.253-9.965s23.26 5.761 29.253 9.965c4.418 3.102 6.435 4.518 12.012 4.518 5.575 0 7.592-1.417 12.010-4.518 5.991-4.206 14.197-9.965 29.253-9.965 8.286 0 15.004 6.717 15.004 15.004s-6.717 15.004-15.004 15.004z" /> +<glyph unicode="" glyph-name="icon-nav-packages" horiz-adv-x="1205" d="M1154.309 638.745h-70.074v125.852c0 30.258-24.616 54.854-54.854 54.854h-497.001l-100.392 140.549h-377.133c-30.238 0-54.854-24.616-54.854-54.854v-877.166h0.12c-0.1-11.304 3.413-22.367 10.481-31.624 9.838-12.85 24.737-20.199 40.9-20.199h898.691c23.211 0 43.651 15.641 49.192 36.402l205.322 562.959v3.554c0 34.575-21.203 59.673-50.397 59.673zM40.157 905.146c0 8.112 6.606 14.697 14.697 14.697h356.452l100.392-140.549h517.662c8.112 0 14.697-6.586 14.697-14.697v-125.852h-788.44c-2.891 0-5.763-0.241-8.553-0.723-19.536-3.273-35.78-17.528-40.619-35.659l-166.29-453.512v756.294zM961.134 24.686c-1.325-4.919-5.843-8.373-10.943-8.373h-898.691c-4.879 0-7.73 2.791-8.995 4.457-1.265 1.646-3.213 5.14-2.47 8.192l204.619 561.252c1.325 4.919 5.843 8.373 10.943 8.373h898.711c7.63 0 9.577-10.963 10.079-16.444l-203.254-557.458zM743.632 478.118c-21.744 0-39.427-17.683-39.427-39.427 0-6.801 1.728-13.201 4.771-18.793l-64.588-64.588c-8.904 6.933-20.048 11.099-32.179 11.099s-23.275-4.166-32.185-11.092l-50.394 50.394c2.313 3.91 3.726 8.404 3.726 13.267 0 14.496-11.789 26.284-26.284 26.284s-26.284-11.789-26.284-26.284c0-14.496 11.789-26.284 26.284-26.284 4.863 0 9.357 1.413 13.267 3.726l50.394-50.394c-6.926-8.91-11.092-20.055-11.092-32.185s4.166-23.275 11.092-32.179l-83.217-83.223c-7.005 6.354-16.264 10.264-26.442 10.264-21.744 0-39.427-17.683-39.427-39.427s17.683-39.427 39.427-39.427c21.744 0 39.427 17.683 39.427 39.427 0 6.801-1.728 13.201-4.771 18.793l84.301 84.301c7.268-5.651 16.034-9.436 25.614-10.639v-66.763c-18.616-3.141-32.856-19.332-32.856-38.835 0-21.744 17.683-39.427 39.427-39.427s39.427 17.683 39.427 39.427c0 19.497-14.24 35.688-32.856 38.835v66.763c9.581 1.203 18.347 4.987 25.614 10.639l50.394-50.394c-2.32-3.916-3.732-8.411-3.732-13.274 0-14.496 11.789-26.284 26.284-26.284s26.284 11.789 26.284 26.284c0 14.496-11.789 26.284-26.284 26.284-4.863 0-9.357-1.413-13.267-3.726l-50.394 50.394c6.926 8.91 11.092 20.055 11.092 32.185s-4.166 23.275-11.092 32.179l63.51 63.51c6.998-6.354 16.257-10.264 26.436-10.264 21.744 0 39.427 17.683 39.427 39.427s-17.683 39.427-39.427 39.427z" /> +<glyph unicode="" glyph-name="icon-redo" horiz-adv-x="2219" d="M1078.769 851.691c286.482 0 547.508-106.684 747.34-281.608l389.917 389.917v-974.792h-974.792l391.541 391.541c-150.011 126.18-342.259 204.163-554.007 204.163-383.961 0-708.892-249.653-822.618-595.704l-256.152 84.482c148.925 453.821 575.127 782.001 1078.77 782.001z" /> +<glyph unicode="" glyph-name="icon-remove-file" d="M873.809 810.277c-199.621 199.621-524.446 199.641-724.086 0s-199.621-524.446 0-724.086c199.621-199.641 524.446-199.641 724.086 0 199.621 199.641 199.621 524.465 0 724.086zM713.671 246.329c-15.38-15.38-40.31-15.38-55.69 0l-146.215 146.215-153.167-153.167c-15.38-15.38-40.31-15.38-55.69 0s-15.38 40.31 0 55.69l153.167 153.167-146.215 146.215c-15.38 15.38-15.38 40.33 0 55.69 15.38 15.38 40.31 15.38 55.69 0l146.215-146.215 139.244 139.244c15.38 15.38 40.31 15.38 55.69 0s15.38-40.31 0-55.69l-139.244-139.244 146.215-146.215c15.38-15.38 15.38-40.31 0-55.69z" /> +<glyph unicode="" glyph-name="icon-save-sm" horiz-adv-x="1158" d="M445.306 27.963c-10.875-10.935-25.692-17.024-41.1-17.024s-30.225 6.089-41.1 17.024l-328.19 328.244c-34.048 34.048-34.048 89.287 0 123.274l41.1 41.106c34.079 34.048 89.232 34.048 123.28 0l204.884-204.914 553.661 553.67c34.079 34.048 89.287 34.048 123.28 0l41.1-41.106c34.048-34.048 34.048-89.281 0-123.274l-676.953-677.008z" /> +<glyph unicode="" glyph-name="icon-search" horiz-adv-x="945" d="M940.032 9.728l-275.377 286.405c70.274 70.215 113.743 167.247 113.743 274.432 0 0.083 0 0.166 0 0.249v-0.013c-0.269 214.812-174.313 388.885-389.089 389.199h-0.031c-214.874-0.224-389.009-174.331-389.278-389.173v-0.025c0.269-214.84 174.358-388.93 389.173-389.199h0.026c0.118 0 0.257 0 0.397 0 94.501 0 181.098 33.838 248.337 90.058l-0.611-0.497 276.007-287.114c3.367-3.552 8.119-5.762 13.387-5.762 4.996 0 9.527 1.988 12.847 5.215l-0.004-0.004c3.49 3.383 5.656 8.115 5.656 13.352 0 5.002-1.976 9.542-5.189 12.884l0.006-0.006zM389.199 218.624c-194.368 0.224-351.874 157.73-352.098 352.077v0.022c0.134 194.409 157.63 351.987 351.994 352.256h0.026c194.368-0.224 351.874-157.73 352.098-352.077v-0.022c-0.269-194.351-157.748-351.83-352.073-352.098h-0.025z" /> +<glyph unicode="" glyph-name="icon-search-light" horiz-adv-x="945" d="M932.421 16.871l-270.901 281.731c69.097 69.298 111.905 164.831 111.905 270.191 0 211.121-171.74 382.861-382.861 382.861s-382.861-171.74-382.861-382.861c0-211.121 171.74-382.861 382.861-382.861 92.671 0 177.72 33.127 244.010 88.094l271.559-282.424c3.574-3.737 8.35-5.597 13.145-5.597 4.557 0 9.097 1.696 12.635 5.087 7.256 6.982 7.475 18.523 0.511 25.779zM390.563 222.395c-191.011 0-346.398 155.387-346.398 346.398s155.387 346.398 346.398 346.398c191.011 0 346.398-155.387 346.398-346.398s-155.405-346.398-346.398-346.398z" /> +<glyph unicode="" glyph-name="icon-topologySource" d="M406.874 276.628c-0.418 2.887-1.963 5.488-4.297 7.234l-118.42 88.557 118.42 88.557c2.334 1.746 3.879 4.347 4.297 7.234 0.415 2.887-0.33 5.817-2.079 8.157l-18.812 25.154c-3.641 4.862-10.526 5.858-15.388 2.218l-163.831-122.516c-2.774-2.073-4.41-5.337-4.41-8.805s1.637-6.731 4.41-8.805l163.831-122.516c1.973-1.479 4.284-2.189 6.574-2.189 3.348 0 6.656 1.52 8.814 4.407l18.812 25.154c1.746 2.34 2.494 5.271 2.079 8.157zM815.952 381.223l-163.824 122.516c-4.862 3.637-11.748 2.642-15.385-2.218l-18.812-25.154c-1.746-2.337-2.494-5.271-2.079-8.157 0.418-2.884 1.96-5.488 4.297-7.234l118.416-88.557-118.416-88.557c-2.337-1.746-3.879-4.35-4.297-7.234-0.415-2.887 0.33-5.82 2.079-8.157l18.812-25.154c2.161-2.887 5.466-4.407 8.814-4.407 2.29 0 4.599 0.713 6.574 2.189l163.824 122.516c2.774 2.073 4.41 5.337 4.41 8.805s-1.64 6.731-4.413 8.805zM616.486 569.134l-28.933 12.235c-2.683 1.137-5.711 1.156-8.415 0.063-2.701-1.096-4.859-3.22-5.993-5.905l-172.761-408.607c-2.365-5.591 0.251-12.043 5.846-14.408l28.933-12.235c1.366-0.581 2.824-0.867 4.281-0.867 1.404 0 2.808 0.27 4.134 0.807 2.701 1.096 4.856 3.22 5.993 5.905l172.761 408.607c2.362 5.591-0.254 12.040-5.846 14.405zM967.749 958.546h-912.78c-30.309 0-54.969-24.661-54.969-54.969v-859.613c0-30.309 24.661-54.969 54.969-54.969h912.78c30.309 0 54.969 24.661 54.969 54.969v859.613c0 30.312-24.661 54.969-54.969 54.969zM858.982 874.26c25.113 0 45.546-20.433 45.546-45.546s-20.433-45.546-45.546-45.546c-25.113 0-45.546 20.433-45.546 45.546s20.433 45.546 45.546 45.546zM704.531 874.26c25.113 0 45.546-20.433 45.546-45.546s-20.433-45.546-45.546-45.546c-25.113 0-45.546 20.433-45.546 45.546s20.433 45.546 45.546 45.546zM139.462 852.273h183.755c13.010 0 23.558-10.545 23.558-23.558s-10.548-23.558-23.558-23.558h-183.755c-13.010 0-23.558 10.545-23.558 23.558s10.548 23.558 23.558 23.558zM935.408 84.241c0-3.952-3.216-7.171-7.174-7.171h-833.75c-3.955 0-7.174 3.22-7.174 7.171v592.004h848.098v-592.004z" /> +<glyph unicode="" glyph-name="icon-topologyView-active" horiz-adv-x="1097" d="M1097.143 820.363c0 76.406-62.211 138.566-138.679 138.566h-819.784c-76.468 0-138.679-62.16-138.679-138.566v-568.472c0-35.229 13.226-67.429 34.978-91.905-21.229-15.999-34.978-41.409-34.978-69.966 0-82.129 66.872-148.948 149.070-148.948h799.001c82.198 0 149.072 66.819 149.072 148.948 0 28.558-13.751 53.968-34.98 69.966 21.754 24.476 34.98 56.676 34.98 91.905v568.472zM64.286 820.363c0 40.959 33.373 74.28 74.394 74.28h819.784c41.021 0 74.394-33.321 74.394-74.28v-568.472c0-40.959-33.373-74.28-74.394-74.28h-217.899c-29.094 0-52.764-23.661-52.764-52.742 0-8.657-7.067-15.701-15.752-15.701h-246.956c-8.685 0-15.752 7.044-15.752 15.701 0 29.081-23.67 52.742-52.764 52.742h-217.899c-41.021 0-74.394 33.321-74.394 74.28v568.472zM948.073 5.357h-799.003c-46.751 0-84.784 37.98-84.784 84.662 0 12.851 10.483 23.306 23.364 23.306h258.238c5.616-38.655 38.996-68.441 79.206-68.441h246.956c40.211 0 73.59 29.788 79.206 68.441h258.238c12.883 0 23.364-10.455 23.364-23.306 0-46.682-38.034-84.662-84.784-84.662zM640.607 281.098c2.209-9.609 8.709-17.672 17.631-21.874 4.339-2.044 9.017-3.064 13.695-3.064 4.937 0 9.868 1.136 14.398 3.405l102.731 51.463c6.441 3.227 11.612 8.524 14.683 15.043l163.667 347.52c24.236 51.459 2.087 113.040-49.374 137.276h0.002c-24.93 11.741-52.937 13.071-78.864 3.746-25.931-9.326-46.674-28.189-58.414-53.117l-163.669-347.52c-3.071-6.519-3.861-13.879-2.246-20.901l25.759-111.975zM860.931 754.121c9.769 3.512 20.325 3.013 29.715-1.412h0.002c19.389-9.133 27.735-32.336 18.604-51.726l-15.171-32.211-70.331 33.124 15.171 32.211c4.423 9.392 12.238 16.5 22.009 20.014v0zM796.359 643.736l70.333-33.122-116.37-247.089-56.231-28.17-14.1 61.294 116.368 247.086zM173.406 256.161h311.329c17.751 0 32.143 14.391 32.143 32.143v251.098c0 17.751-14.391 32.143-32.143 32.143h-311.329c-17.751 0-32.143-14.391-32.143-32.143v-251.098c0-17.751 14.391-32.143 32.143-32.143zM205.549 507.259h247.044v-186.812h-247.044v186.812zM173.406 753.099h398.216c17.751 0 32.143 14.391 32.143 32.143s-14.391 32.143-32.143 32.143h-398.216c-17.751 0-32.143-14.391-32.143-32.143s14.391-32.143 32.143-32.143zM173.406 645.956h301.787c17.751 0 32.143 14.391 32.143 32.143s-14.391 32.143-32.143 32.143h-301.787c-17.751 0-32.143-14.391-32.143-32.143s14.391-32.143 32.143-32.143z" /> +<glyph unicode="" glyph-name="icon-undoActive" horiz-adv-x="2219" d="M1137.257 851.691c-286.482 0-547.508-106.684-747.34-281.608l-389.917 389.917v-974.792h974.792l-391.541 391.541c150.011 126.18 342.259 204.163 554.007 204.163 383.961 0 708.892-249.653 822.618-595.704l256.152 84.482c-148.925 453.821-575.127 782.001-1078.77 782.001z" /> +<glyph unicode="" glyph-name="icon-zoomIn" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-206.769v-216.615c0-21.74-17.644-39.385-39.385-39.385s-39.385 17.644-39.385 39.385v216.615h-206.769c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h206.769v196.923c0 21.74 17.644 39.385 39.385 39.385s39.385-17.644 39.385-39.385v-196.923h206.769c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="" glyph-name="icon-zoomOut" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-492.308c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h492.308c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="" glyph-name="icon-zoomOut" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-492.308c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h492.308c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="icon-zoomOut" glyph-name="icon-zoomOut" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-492.308c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h492.308c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="icon-zoomIn" glyph-name="icon-zoomIn" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-206.769v-216.615c0-21.74-17.644-39.385-39.385-39.385s-39.385 17.644-39.385 39.385v216.615h-206.769c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h206.769v196.923c0 21.74 17.644 39.385 39.385 39.385s39.385-17.644 39.385-39.385v-196.923h206.769c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="icon-undoActive" glyph-name="icon-undoActive" horiz-adv-x="2219" d="M1137.257 851.691c-286.482 0-547.508-106.684-747.34-281.608l-389.917 389.917v-974.792h974.792l-391.541 391.541c150.011 126.18 342.259 204.163 554.007 204.163 383.961 0 708.892-249.653 822.618-595.704l256.152 84.482c-148.925 453.821-575.127 782.001-1078.77 782.001z" /> +<glyph unicode="icon-topologyView-active" glyph-name="icon-topologyView-active" horiz-adv-x="1097" d="M1097.143 820.363c0 76.406-62.211 138.566-138.679 138.566h-819.784c-76.468 0-138.679-62.16-138.679-138.566v-568.472c0-35.229 13.226-67.429 34.978-91.905-21.229-15.999-34.978-41.409-34.978-69.966 0-82.129 66.872-148.948 149.070-148.948h799.001c82.198 0 149.072 66.819 149.072 148.948 0 28.558-13.751 53.968-34.98 69.966 21.754 24.476 34.98 56.676 34.98 91.905v568.472zM64.286 820.363c0 40.959 33.373 74.28 74.394 74.28h819.784c41.021 0 74.394-33.321 74.394-74.28v-568.472c0-40.959-33.373-74.28-74.394-74.28h-217.899c-29.094 0-52.764-23.661-52.764-52.742 0-8.657-7.067-15.701-15.752-15.701h-246.956c-8.685 0-15.752 7.044-15.752 15.701 0 29.081-23.67 52.742-52.764 52.742h-217.899c-41.021 0-74.394 33.321-74.394 74.28v568.472zM948.073 5.357h-799.003c-46.751 0-84.784 37.98-84.784 84.662 0 12.851 10.483 23.306 23.364 23.306h258.238c5.616-38.655 38.996-68.441 79.206-68.441h246.956c40.211 0 73.59 29.788 79.206 68.441h258.238c12.883 0 23.364-10.455 23.364-23.306 0-46.682-38.034-84.662-84.784-84.662zM640.607 281.098c2.209-9.609 8.709-17.672 17.631-21.874 4.339-2.044 9.017-3.064 13.695-3.064 4.937 0 9.868 1.136 14.398 3.405l102.731 51.463c6.441 3.227 11.612 8.524 14.683 15.043l163.667 347.52c24.236 51.459 2.087 113.040-49.374 137.276h0.002c-24.93 11.741-52.937 13.071-78.864 3.746-25.931-9.326-46.674-28.189-58.414-53.117l-163.669-347.52c-3.071-6.519-3.861-13.879-2.246-20.901l25.759-111.975zM860.931 754.121c9.769 3.512 20.325 3.013 29.715-1.412h0.002c19.389-9.133 27.735-32.336 18.604-51.726l-15.171-32.211-70.331 33.124 15.171 32.211c4.423 9.392 12.238 16.5 22.009 20.014v0zM796.359 643.736l70.333-33.122-116.37-247.089-56.231-28.17-14.1 61.294 116.368 247.086zM173.406 256.161h311.329c17.751 0 32.143 14.391 32.143 32.143v251.098c0 17.751-14.391 32.143-32.143 32.143h-311.329c-17.751 0-32.143-14.391-32.143-32.143v-251.098c0-17.751 14.391-32.143 32.143-32.143zM205.549 507.259h247.044v-186.812h-247.044v186.812zM173.406 753.099h398.216c17.751 0 32.143 14.391 32.143 32.143s-14.391 32.143-32.143 32.143h-398.216c-17.751 0-32.143-14.391-32.143-32.143s14.391-32.143 32.143-32.143zM173.406 645.956h301.787c17.751 0 32.143 14.391 32.143 32.143s-14.391 32.143-32.143 32.143h-301.787c-17.751 0-32.143-14.391-32.143-32.143s14.391-32.143 32.143-32.143z" /> +<glyph unicode="icon-topologySource" glyph-name="icon-topologySource" d="M406.874 276.628c-0.418 2.887-1.963 5.488-4.297 7.234l-118.42 88.557 118.42 88.557c2.334 1.746 3.879 4.347 4.297 7.234 0.415 2.887-0.33 5.817-2.079 8.157l-18.812 25.154c-3.641 4.862-10.526 5.858-15.388 2.218l-163.831-122.516c-2.774-2.073-4.41-5.337-4.41-8.805s1.637-6.731 4.41-8.805l163.831-122.516c1.973-1.479 4.284-2.189 6.574-2.189 3.348 0 6.656 1.52 8.814 4.407l18.812 25.154c1.746 2.34 2.494 5.271 2.079 8.157zM815.952 381.223l-163.824 122.516c-4.862 3.637-11.748 2.642-15.385-2.218l-18.812-25.154c-1.746-2.337-2.494-5.271-2.079-8.157 0.418-2.884 1.96-5.488 4.297-7.234l118.416-88.557-118.416-88.557c-2.337-1.746-3.879-4.35-4.297-7.234-0.415-2.887 0.33-5.82 2.079-8.157l18.812-25.154c2.161-2.887 5.466-4.407 8.814-4.407 2.29 0 4.599 0.713 6.574 2.189l163.824 122.516c2.774 2.073 4.41 5.337 4.41 8.805s-1.64 6.731-4.413 8.805zM616.486 569.134l-28.933 12.235c-2.683 1.137-5.711 1.156-8.415 0.063-2.701-1.096-4.859-3.22-5.993-5.905l-172.761-408.607c-2.365-5.591 0.251-12.043 5.846-14.408l28.933-12.235c1.366-0.581 2.824-0.867 4.281-0.867 1.404 0 2.808 0.27 4.134 0.807 2.701 1.096 4.856 3.22 5.993 5.905l172.761 408.607c2.362 5.591-0.254 12.040-5.846 14.405zM967.749 958.546h-912.78c-30.309 0-54.969-24.661-54.969-54.969v-859.613c0-30.309 24.661-54.969 54.969-54.969h912.78c30.309 0 54.969 24.661 54.969 54.969v859.613c0 30.312-24.661 54.969-54.969 54.969zM858.982 874.26c25.113 0 45.546-20.433 45.546-45.546s-20.433-45.546-45.546-45.546c-25.113 0-45.546 20.433-45.546 45.546s20.433 45.546 45.546 45.546zM704.531 874.26c25.113 0 45.546-20.433 45.546-45.546s-20.433-45.546-45.546-45.546c-25.113 0-45.546 20.433-45.546 45.546s20.433 45.546 45.546 45.546zM139.462 852.273h183.755c13.010 0 23.558-10.545 23.558-23.558s-10.548-23.558-23.558-23.558h-183.755c-13.010 0-23.558 10.545-23.558 23.558s10.548 23.558 23.558 23.558zM935.408 84.241c0-3.952-3.216-7.171-7.174-7.171h-833.75c-3.955 0-7.174 3.22-7.174 7.171v592.004h848.098v-592.004z" /> +<glyph unicode="icon-search-light" glyph-name="icon-search-light" horiz-adv-x="945" d="M932.421 16.871l-270.901 281.731c69.097 69.298 111.905 164.831 111.905 270.191 0 211.121-171.74 382.861-382.861 382.861s-382.861-171.74-382.861-382.861c0-211.121 171.74-382.861 382.861-382.861 92.671 0 177.72 33.127 244.010 88.094l271.559-282.424c3.574-3.737 8.35-5.597 13.145-5.597 4.557 0 9.097 1.696 12.635 5.087 7.256 6.982 7.475 18.523 0.511 25.779zM390.563 222.395c-191.011 0-346.398 155.387-346.398 346.398s155.387 346.398 346.398 346.398c191.011 0 346.398-155.387 346.398-346.398s-155.405-346.398-346.398-346.398z" /> +<glyph unicode="icon-search" glyph-name="icon-search" horiz-adv-x="945" d="M940.032 9.728l-275.377 286.405c70.274 70.215 113.743 167.247 113.743 274.432 0 0.083 0 0.166 0 0.249v-0.013c-0.269 214.812-174.313 388.885-389.089 389.199h-0.031c-214.874-0.224-389.009-174.331-389.278-389.173v-0.025c0.269-214.84 174.358-388.93 389.173-389.199h0.026c0.118 0 0.257 0 0.397 0 94.501 0 181.098 33.838 248.337 90.058l-0.611-0.497 276.007-287.114c3.367-3.552 8.119-5.762 13.387-5.762 4.996 0 9.527 1.988 12.847 5.215l-0.004-0.004c3.49 3.383 5.656 8.115 5.656 13.352 0 5.002-1.976 9.542-5.189 12.884l0.006-0.006zM389.199 218.624c-194.368 0.224-351.874 157.73-352.098 352.077v0.022c0.134 194.409 157.63 351.987 351.994 352.256h0.026c194.368-0.224 351.874-157.73 352.098-352.077v-0.022c-0.269-194.351-157.748-351.83-352.073-352.098h-0.025z" /> +<glyph unicode="icon-save-sm" glyph-name="icon-save-sm" horiz-adv-x="1158" d="M445.306 27.963c-10.875-10.935-25.692-17.024-41.1-17.024s-30.225 6.089-41.1 17.024l-328.19 328.244c-34.048 34.048-34.048 89.287 0 123.274l41.1 41.106c34.079 34.048 89.232 34.048 123.28 0l204.884-204.914 553.661 553.67c34.079 34.048 89.287 34.048 123.28 0l41.1-41.106c34.048-34.048 34.048-89.281 0-123.274l-676.953-677.008z" /> +<glyph unicode="icon-remove-file" glyph-name="icon-remove-file" d="M873.809 810.277c-199.621 199.621-524.446 199.641-724.086 0s-199.621-524.446 0-724.086c199.621-199.641 524.446-199.641 724.086 0 199.621 199.641 199.621 524.465 0 724.086zM713.671 246.329c-15.38-15.38-40.31-15.38-55.69 0l-146.215 146.215-153.167-153.167c-15.38-15.38-40.31-15.38-55.69 0s-15.38 40.31 0 55.69l153.167 153.167-146.215 146.215c-15.38 15.38-15.38 40.33 0 55.69 15.38 15.38 40.31 15.38 55.69 0l146.215-146.215 139.244 139.244c15.38 15.38 40.31 15.38 55.69 0s15.38-40.31 0-55.69l-139.244-139.244 146.215-146.215c15.38-15.38 15.38-40.31 0-55.69z" /> +<glyph unicode="icon-redo" glyph-name="icon-redo" horiz-adv-x="2219" d="M1078.769 851.691c286.482 0 547.508-106.684 747.34-281.608l389.917 389.917v-974.792h-974.792l391.541 391.541c-150.011 126.18-342.259 204.163-554.007 204.163-383.961 0-708.892-249.653-822.618-595.704l-256.152 84.482c148.925 453.821 575.127 782.001 1078.77 782.001z" /> +<glyph unicode="icon-nav-packages" glyph-name="icon-nav-packages" horiz-adv-x="1205" d="M1154.309 638.745h-70.074v125.852c0 30.258-24.616 54.854-54.854 54.854h-497.001l-100.392 140.549h-377.133c-30.238 0-54.854-24.616-54.854-54.854v-877.166h0.12c-0.1-11.304 3.413-22.367 10.481-31.624 9.838-12.85 24.737-20.199 40.9-20.199h898.691c23.211 0 43.651 15.641 49.192 36.402l205.322 562.959v3.554c0 34.575-21.203 59.673-50.397 59.673zM40.157 905.146c0 8.112 6.606 14.697 14.697 14.697h356.452l100.392-140.549h517.662c8.112 0 14.697-6.586 14.697-14.697v-125.852h-788.44c-2.891 0-5.763-0.241-8.553-0.723-19.536-3.273-35.78-17.528-40.619-35.659l-166.29-453.512v756.294zM961.134 24.686c-1.325-4.919-5.843-8.373-10.943-8.373h-898.691c-4.879 0-7.73 2.791-8.995 4.457-1.265 1.646-3.213 5.14-2.47 8.192l204.619 561.252c1.325 4.919 5.843 8.373 10.943 8.373h898.711c7.63 0 9.577-10.963 10.079-16.444l-203.254-557.458zM743.632 478.118c-21.744 0-39.427-17.683-39.427-39.427 0-6.801 1.728-13.201 4.771-18.793l-64.588-64.588c-8.904 6.933-20.048 11.099-32.179 11.099s-23.275-4.166-32.185-11.092l-50.394 50.394c2.313 3.91 3.726 8.404 3.726 13.267 0 14.496-11.789 26.284-26.284 26.284s-26.284-11.789-26.284-26.284c0-14.496 11.789-26.284 26.284-26.284 4.863 0 9.357 1.413 13.267 3.726l50.394-50.394c-6.926-8.91-11.092-20.055-11.092-32.185s4.166-23.275 11.092-32.179l-83.217-83.223c-7.005 6.354-16.264 10.264-26.442 10.264-21.744 0-39.427-17.683-39.427-39.427s17.683-39.427 39.427-39.427c21.744 0 39.427 17.683 39.427 39.427 0 6.801-1.728 13.201-4.771 18.793l84.301 84.301c7.268-5.651 16.034-9.436 25.614-10.639v-66.763c-18.616-3.141-32.856-19.332-32.856-38.835 0-21.744 17.683-39.427 39.427-39.427s39.427 17.683 39.427 39.427c0 19.497-14.24 35.688-32.856 38.835v66.763c9.581 1.203 18.347 4.987 25.614 10.639l50.394-50.394c-2.32-3.916-3.732-8.411-3.732-13.274 0-14.496 11.789-26.284 26.284-26.284s26.284 11.789 26.284 26.284c0 14.496-11.789 26.284-26.284 26.284-4.863 0-9.357-1.413-13.267-3.726l-50.394 50.394c6.926 8.91 11.092 20.055 11.092 32.185s-4.166 23.275-11.092 32.179l63.51 63.51c6.998-6.354 16.257-10.264 26.436-10.264 21.744 0 39.427 17.683 39.427 39.427s-17.683 39.427-39.427 39.427z" /> +<glyph unicode="icon-nav-dictionary" glyph-name="icon-nav-dictionary" d="M991.457 533.163c-13.803 0-24.993-11.19-24.993-24.993v-203.273c0-13.803 11.19-24.993 24.993-24.993s24.993 11.19 24.993 24.993v203.273c-0.003 13.803-11.193 24.993-24.993 24.993v0zM960.173 959.5h-856.973c-56.907 0-103.2-34.087-103.2-75.984v-835.988c0-48.869 54-88.628 120.377-88.628h799.807c13.6 0 25.733 5.969 30.91 15.209 5.203 9.287 2.297 19.877-7.403 26.98-16.927 12.389-26.247 28.882-26.247 46.439 0 20.432 12.837 39.437 34.62 51.827h8.11c31.030 0 56.277 18.586 56.277 41.435v194.1c0 10.163-11.19 18.402-24.993 18.402s-24.993-8.239-24.993-18.402v-194.1c0-2.555-2.82-4.631-6.29-4.631h-839.797c-25.133 0-50.023-5.925-70.39-16.77v764.128c0 21.602 23.87 39.18 53.213 39.18h856.973c3.47 0 6.29-2.076 6.29-4.631v-144.885c0-10.163 11.19-18.402 24.993-18.402s24.993 8.239 24.993 18.402v144.885c0 22.847-25.247 41.435-56.277 41.435v0zM886.563 99.357c-12.343-15.459-19.107-33.27-19.107-51.829 0-18.522 6.64-36.286 19.090-51.827h-766.17c-38.813 0-70.39 23.249-70.39 51.827s31.577 51.827 70.39 51.827l766.187 0.002zM348.708 760.797c-53.594 0-97.198-43.604-97.198-97.198v-217.009c0-53.594 43.604-97.198 97.198-97.198h319.034c53.594 0 97.198 43.604 97.198 97.198v217.009c0 53.594-43.604 97.198-97.198 97.198h-319.034zM723.265 663.599v-217.009c0-30.617-24.909-55.523-55.523-55.523h-319.034c-30.617 0-55.526 24.909-55.526 55.523v217.009c0 30.617 24.909 55.526 55.526 55.526h319.034c30.617 0 55.523-24.909 55.523-55.526v0zM627.88 590.463c-6.871 0-9.357 1.746-14.802 5.569-7.384 5.184-17.496 12.282-36.054 12.282s-28.67-7.1-36.054-12.282c-5.445-3.823-7.931-5.569-14.802-5.569s-9.357 1.746-14.802 5.569c-7.384 5.184-17.498 12.282-36.054 12.282s-28.668-7.1-36.049-12.284c-5.445-3.823-7.931-5.569-14.8-5.569s-9.354 1.744-14.797 5.569c-7.384 5.184-17.496 12.284-36.052 12.284-10.213 0-18.492-8.279-18.492-18.492s8.279-18.492 18.492-18.492c6.869 0 9.354-1.744 14.797-5.569 7.384-5.184 17.496-12.284 36.052-12.284s28.668 7.1 36.052 12.284c5.443 3.823 7.929 5.569 14.797 5.569 6.871 0 9.357-1.746 14.805-5.569 7.384-5.184 17.498-12.282 36.054-12.282s28.668 7.1 36.054 12.282c5.445 3.823 7.931 5.569 14.805 5.569s9.357-1.746 14.802-5.569c7.384-5.184 17.496-12.282 36.054-12.282 10.213 0 18.492 8.279 18.492 18.492s-8.284 18.492-18.497 18.492v0zM497.633 493.266c-5.575 0-7.592 1.417-12.010 4.518-5.991 4.206-14.195 9.965-29.253 9.965s-23.262-5.761-29.253-9.965c-4.418-3.102-6.435-4.518-12.010-4.518s-7.592 1.417-12.012 4.518c-5.991 4.206-14.197 9.965-29.253 9.965-8.286 0-15.004-6.717-15.004-15.004s6.717-15.004 15.004-15.004c5.575 0 7.592-1.417 12.010-4.518 5.991-4.206 14.197-9.965 29.253-9.965s23.26 5.761 29.253 9.965c4.418 3.102 6.435 4.518 12.012 4.518 5.575 0 7.592-1.417 12.010-4.518 5.991-4.206 14.197-9.965 29.253-9.965 8.286 0 15.004 6.717 15.004 15.004s-6.717 15.004-15.004 15.004z" /> +<glyph unicode="icon-menuDots" glyph-name="icon-menuDots" horiz-adv-x="4437" d="M1813.333 448c0 282.77 229.23 512 512 512s512-229.23 512-512c0-282.77-229.23-512-512-512s-512 229.23-512 512zM277.333 448c0 282.77 229.23 512 512 512s512-229.23 512-512c0-282.77-229.23-512-512-512s-512 229.23-512 512zM3413.333 448c0 282.77 229.23 512 512 512s512-229.23 512-512c0-282.77-229.23-512-512-512s-512 229.23-512 512z" /> +<glyph unicode="icon-info" glyph-name="icon-info" d="M503.979 944c-278.315 0-503.979-225.664-503.979-503.979s225.664-504.021 503.979-504.021c278.315 0 504.021 225.707 504.021 504.021s-225.707 503.979-504.021 503.979zM608.896 162.901c-25.941-10.24-46.592-18.005-62.080-23.381-15.445-5.376-33.408-8.064-53.845-8.064-31.403 0-55.851 7.68-73.259 22.997s-26.069 34.731-26.069 58.325c0 9.173 0.64 18.56 1.92 28.117 1.323 9.557 3.413 20.309 6.272 32.384l32.469 114.688c2.859 11.008 5.333 21.461 7.296 31.189 1.963 9.813 2.901 18.816 2.901 27.008 0 14.592-3.029 24.832-9.045 30.592-6.101 5.76-17.579 8.576-34.688 8.576-8.363 0-16.981-1.237-25.813-3.84-8.747-2.688-16.341-5.12-22.571-7.509l8.576 35.328c21.248 8.661 41.6 16.085 61.013 22.229 19.413 6.229 37.76 9.301 55.040 9.301 31.189 0 55.253-7.595 72.192-22.613 16.853-15.061 25.344-34.645 25.344-58.709 0-4.992-0.597-13.781-1.749-26.325-1.152-12.587-3.328-24.064-6.485-34.603l-32.299-114.347c-2.645-9.173-4.992-19.669-7.125-31.403-2.091-11.733-3.115-20.693-3.115-26.709 0-15.189 3.371-25.557 10.197-31.061 6.741-5.504 18.56-8.277 35.285-8.277 7.893 0 16.725 1.408 26.709 4.139 9.899 2.731 17.067 5.163 21.589 7.253l-8.661-35.285zM603.179 627.029c-15.061-13.995-33.195-20.992-54.4-20.992-21.163 0-39.424 6.997-54.613 20.992-15.104 13.995-22.741 31.019-22.741 50.901 0 19.84 7.68 36.907 22.741 51.029 15.189 14.165 33.451 21.205 54.613 21.205 21.205 0 39.381-7.040 54.4-21.205 15.061-14.123 22.613-31.189 22.613-51.029 0-19.925-7.552-36.907-22.613-50.901z" /> +<glyph unicode="icon-import-blue" glyph-name="icon-import-blue" horiz-adv-x="1434" d="M1158.827 601.6c-41.813 203.093-221.013 358.4-442.027 358.4-173.227 0-322.56-95.573-394.24-238.933-185.173-23.893-322.56-173.227-322.56-358.4 0-197.12 161.28-358.4 358.4-358.4h776.533c167.253 0 298.667 131.413 298.667 298.667 0 155.307-125.44 286.72-274.773 298.667zM836.267 422.4v-238.933h-238.933v238.933h-179.2l298.667 298.667 298.667-298.667h-179.2z" /> +<glyph unicode="icon-file-code" glyph-name="icon-file-code" horiz-adv-x="768" d="M512 960h-512v-1024h768v768l-256 256zM448 640h256v-640h-640v896h384v-256zM512 704v192l192-192h-192zM268.8 128h-44.8l-128 160 128 160h44.8l-128-160zM499.2 128h44.8l128 160-128 160h-44.8l128-160zM300.8 64h38.4l134.4 448h-51.2z" /> +<glyph unicode="icon-edit" glyph-name="icon-edit" d="M0 152.176v-216.178h216.178l625.778 631.467-216.178 216.178-625.778-631.467zM1006.933 732.442c22.756 22.756 22.756 56.889 0 79.644l-130.844 130.847c-22.756 22.756-56.889 22.756-79.644 0l-102.4-102.4 216.178-216.178 96.711 108.087z" /> +<glyph unicode="icon-drag" glyph-name="icon-drag" horiz-adv-x="372" d="M169.58 837.675c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM169.58 588.944c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM169.58 340.219c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM169.58 91.487c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 837.675c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 588.944c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 340.219c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908zM368.561 91.487c0-45.792-37.121-82.908-82.908-82.908s-82.908 37.121-82.908 82.908c0 45.792 37.121 82.908 82.908 82.908s82.908-37.121 82.908-82.908z" /> +<glyph unicode="icon-download" glyph-name="icon-download" horiz-adv-x="887" d="M659.932 832.548v100.566l154.573-154.573h-100.566c-29.811 0.046-53.986 24.196-54.007 54.007zM585.477 364.458h-69.576c-9.948 0-18.011 8.062-18.011 18.011v198.042h-108.014v-198.042c0-9.948-8.062-18.011-18.011-18.011h-69.576l141.594-169.897 141.594 169.897zM47.825 4.396v900.156c0.046 29.811 24.196 53.986 54.007 54.007h522.086v-126.024c0.059-49.702 40.326-89.969 90.021-90.021h126.024v-738.132c-0.046-29.811-24.196-53.986-54.007-54.007h-684.124c-29.811 0.046-53.986 24.196-54.007 54.007zM353.88 670.511c0-9.948 8.062-18.011 18.011-18.011h144.035c9.948 0 18.011 8.062 18.011 18.011s-8.062 18.011-18.011 18.011h-144.035c-9.948 0-18.011-8.062-18.011-18.011zM250.034 370.934l180.031-216.028c3.413-4.101 8.495-6.483 13.819-6.483s10.405 2.382 13.819 6.483l180.031 216.028c4.472 5.362 5.429 12.843 2.466 19.159s-9.321 10.379-16.31 10.379h-90.021v198.042c0 9.948-8.062 18.011-18.011 18.011h-144.035c-9.948 0-18.011-8.062-18.011-18.011v-198.042h-90.021c-6.989 0-13.347-4.038-16.31-10.379s-2.006-13.797 2.466-19.159z" /> +<glyph unicode="icon-discard-sm" glyph-name="icon-discard-sm" horiz-adv-x="1479" d="M758.634 737.255c-186.485 0-356.399-69.445-486.48-183.313l-253.815 253.815v-634.538h634.538l-254.874 254.874c97.649 82.136 222.794 132.9 360.628 132.9 249.937 0 461.451-162.512 535.483-387.773l166.743 54.991c-96.943 295.415-374.38 509.042-702.224 509.042z" /> +<glyph unicode="icon-deploy-inactive" glyph-name="icon-deploy-inactive" d="M890.522 252.945l-95.505-137.216-67.396 55.313c-7.27 5.99-18.039 4.898-24.013-2.355-5.99-7.287-4.932-18.057 2.372-24.013l81.681-67.055c3.072-2.526 6.895-3.891 10.82-3.891 0.768 0 1.553 0.051 2.338 0.171 4.71 0.649 8.943 3.243 11.674 7.151l106.052 152.388c5.376 7.731 3.482 18.364-4.267 23.757-7.748 5.461-18.364 3.516-23.757-4.25zM802.133 379.733c-122.334 0-221.867-99.533-221.867-221.867s99.533-221.867 221.867-221.867c122.334 0 221.867 99.533 221.867 221.867s-99.533 221.867-221.867 221.867zM802.133-29.867c-103.509 0-187.733 84.224-187.733 187.733s84.224 187.733 187.733 187.733c103.509 0 187.733-84.224 187.733-187.733s-84.224-187.733-187.733-187.733zM945.357 960h-866.714c-43.366 0-78.643-35.277-78.643-78.643v-201.097c0-16.623 5.359-31.898 14.251-44.527h995.482c8.909 12.629 14.268 27.904 14.268 44.51v201.114c0 43.366-35.277 78.643-78.643 78.643zM179.2 704c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM580.267 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM614.4 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM648.533 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM682.667 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM716.8 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM750.933 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM785.067 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM819.2 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM853.333 789.333c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM887.467 738.133c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM529.067 157.867c0 42.871 10.206 83.319 27.904 119.467h-542.72c-8.892-12.629-14.251-27.904-14.251-44.51v-201.097c0-43.383 35.277-78.66 78.643-78.66h543.471c-56.9 50.091-93.047 123.221-93.047 204.8zM179.2 55.467c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM14.251 601.6c-8.892-12.629-14.251-27.904-14.251-44.51v-201.097c0-16.623 5.359-31.898 14.251-44.527h562.278c49.22 72.055 131.959 119.467 225.587 119.467 87.433 0 165.205-41.472 215.211-105.609 4.147 9.421 6.656 19.695 6.656 30.652v201.114c0 16.623-5.359 31.881-14.251 44.51h-995.482zM179.2 379.733c-42.342 0-76.8 34.458-76.8 76.8s34.458 76.8 76.8 76.8c42.342 0 76.8-34.458 76.8-76.8s-34.458-76.8-76.8-76.8zM580.267 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM648.533 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM716.8 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM785.067 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067zM853.333 465.067c-9.421 0-17.067 7.646-17.067 17.067s7.646 17.067 17.067 17.067c9.421 0 17.067-7.646 17.067-17.067s-7.646-17.067-17.067-17.067z" /> +<glyph unicode="icon-delete-sm" glyph-name="icon-delete-sm" horiz-adv-x="768" d="M76.189 89.99c0-56.431 46.171-102.602 102.602-102.602h410.413c56.431 0 102.602 46.171 102.602 102.602v615.621h-615.621v-615.621zM743.112 859.515h-179.556l-51.301 51.301h-256.51l-51.301-51.301h-179.556v-102.602h718.224v102.602z" /> +<glyph unicode="icon-create-white" glyph-name="icon-create-white" d="M512 960c-282.309 0-512-229.671-512-512s229.691-512 512-512c282.309 0 512 229.671 512 512s-229.691 512-512 512zM758.154 408.615h-206.769v-216.615c0-21.74-17.644-39.385-39.385-39.385s-39.385 17.644-39.385 39.385v216.615h-206.769c-21.74 0-39.385 17.644-39.385 39.385s17.644 39.385 39.385 39.385h206.769v196.923c0 21.74 17.644 39.385 39.385 39.385s39.385-17.644 39.385-39.385v-196.923h206.769c21.74 0 39.385-17.644 39.385-39.385s-17.644-39.385-39.385-39.385z" /> +<glyph unicode="icon-comType4-sm" glyph-name="icon-comType4-sm" d="M512 960c-282.767 0-512-229.233-512-512s229.233-512 512-512c282.767 0 512 229.233 512 512-0.317 282.633-229.367 511.683-512 512zM954.808 268.633l-145.608-25.125c16.667 61.125 25.667 124.083 26.792 187.425h153.45c-1.925-55.717-13.65-110.658-34.633-162.3v0zM34.558 430.933h153.45c1.125-63.342 10.125-126.3 26.792-187.425l-145.608 25.125c-20.983 51.642-32.708 106.583-34.633 162.3zM69.192 627.367l145.608 25.125c-16.667-61.125-25.667-124.083-26.792-187.425h-153.45c1.925 55.717 13.65 110.658 34.633 162.3zM529.067 685.975c61.325-0.783 122.5-6.367 182.958-16.708l60.242-10.392c18.508-62.983 28.467-128.167 29.608-193.808h-272.808v220.908zM717.842 702.908c-62.375 10.658-125.5 16.417-188.775 17.2v204.8c97.842-9.4 182.833-98.983 231-229.358l-42.225 7.358zM494.933 720.108c-63.275-0.783-126.383-6.542-188.758-17.2l-42.242-7.308c48.167 130.408 133.158 220.025 231 229.383v-204.875zM311.992 669.267c60.45 10.342 121.617 15.925 182.942 16.708v-220.908h-272.808c1.142 65.642 11.1 130.825 29.608 193.808l60.258 10.392zM222.125 430.933h272.808v-220.908c-61.325 0.783-122.5 6.367-182.958 16.708l-60.242 10.392c-18.508 62.983-28.467 128.167-29.608 193.808v0zM306.158 193.092c62.375-10.675 125.492-16.458 188.775-17.292v-204.8c-97.842 9.408-182.833 98.992-231 229.367l42.225-7.275zM529.067 175.8c63.275 0.833 126.383 6.617 188.758 17.292l42.242 7.308c-48.167-130.408-133.158-220.025-231-229.383v204.783zM712.008 226.733c-60.45-10.342-121.617-15.925-182.942-16.708v220.908h272.808c-1.142-65.642-11.1-130.825-29.608-193.808l-60.258-10.392zM835.992 465.067c-1.125 63.342-10.125 126.3-26.792 187.425l145.608-25.125c20.983-51.642 32.708-106.583 34.633-162.3h-153.45zM937.542 664.983l-139.575 24.083c-25.092 81.858-72.033 155.325-135.783 212.483 119.208-39.783 218.067-124.708 275.358-236.567zM361.817 901.55c-63.75-57.158-110.692-130.625-135.783-212.483l-139.575-24.083c57.292 111.858 156.15 196.783 275.358 236.567zM86.458 231.017l139.575-24.083c25.092-81.858 72.033-155.325 135.783-212.483-119.208 39.783-218.067 124.708-275.358 236.567zM662.183-5.55c63.75 57.158 110.692 130.625 135.783 212.483l139.575 24.083c-57.292-111.858-156.15-196.783-275.358-236.567z" /> +<glyph unicode="icon-comType3-sm" glyph-name="icon-comType3-sm" d="M179.2 856.422c-42.342 0-76.8-34.458-76.8-76.8s34.458-76.8 76.8-76.8c42.342 0 76.8 34.458 76.8 76.8s-34.458 76.8-76.8 76.8zM179.2 736.956c-23.518 0-42.667 19.132-42.667 42.667s19.149 42.667 42.667 42.667c23.518 0 42.667-19.132 42.667-42.667s-19.149-42.667-42.667-42.667zM904.533 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM836.267 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM938.667 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM870.4 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM768 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM802.133 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM699.733 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM733.867 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM631.467 805.222c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM665.6 754.022c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM1024 679.083v201.097c0 43.366-35.277 78.643-78.643 78.643h-866.714c-43.366 0-78.643-35.277-78.643-78.643v-201.097c0-25.071 11.998-47.172 30.327-61.577-18.33-14.421-30.327-36.523-30.327-61.594v-201.097c0-43.366 35.277-78.643 78.643-78.643h866.714c43.366 0 78.643 35.277 78.643 78.643v201.097c0 25.071-11.998 47.172-30.327 61.577 18.33 14.421 30.327 36.523 30.327 61.594zM989.867 555.913v-201.097c0-24.542-19.968-44.51-44.51-44.51h-866.714c-24.542-0.017-44.51 19.951-44.51 44.51v201.097c0 24.542 19.968 44.51 44.51 44.51h866.697c24.559 0 44.527-19.968 44.527-44.51zM78.643 634.556c-24.542 0-44.51 19.968-44.51 44.527v201.097c0 24.542 19.968 44.51 44.51 44.51h866.697c24.559 0 44.527-19.968 44.527-44.51v-201.097c0-24.542-19.968-44.51-44.51-44.51l-866.714-0.017zM179.2 378.556c42.342 0 76.8 34.458 76.8 76.8s-34.458 76.8-76.8 76.8c-42.342 0-76.8-34.441-76.8-76.8s34.458-76.8 76.8-76.8zM179.2 498.022c23.518 0 42.667-19.132 42.667-42.667s-19.149-42.667-42.667-42.667c-23.518 0-42.667 19.132-42.667 42.667s19.149 42.667 42.667 42.667zM537.139 98.901c3.908-2.202 7.492-4.915 10.684-8.038 3.328-3.26 7.646-4.881 11.947-4.881 4.42 0 8.841 1.724 12.186 5.12 6.605 6.741 6.485 17.527-0.239 24.132-5.308 5.205-11.264 9.677-17.732 13.363-8.243 4.625-18.62 1.792-23.262-6.434-4.642-8.192-1.775-18.603 6.417-23.262zM537.668 9.967c-3.84-2.253-7.97-3.959-12.271-5.12-9.097-2.458-14.49-11.81-12.049-20.924 2.065-7.612 8.943-12.629 16.469-12.629 1.468 0 2.953 0.188 4.454 0.58 7.202 1.946 14.131 4.83 20.565 8.585 8.141 4.745 10.906 15.206 6.161 23.347-4.745 8.158-15.189 10.889-23.33 6.161zM580.267 71.765c-9.421 0-17.067-8.038-17.067-17.459 0-4.506-0.58-8.943-1.724-13.227-2.441-9.097 2.987-18.449 12.083-20.89 1.468-0.393 2.953-0.58 4.403-0.58 7.543 0 14.438 5.035 16.486 12.663 1.911 7.134 2.884 14.558 2.884 22.016v0.802c0 9.438-7.646 16.674-17.067 16.674zM486.571 9.865c-3.874 2.219-7.441 4.932-10.598 8.073-6.69 6.656-17.476 6.588-24.132-0.068-6.656-6.69-6.622-17.493 0.068-24.132 5.291-5.257 11.247-9.796 17.715-13.5 2.679-1.536 5.581-2.253 8.465-2.253 5.922 0 11.674 3.089 14.831 8.585 4.659 8.175 1.826 18.603-6.349 23.296zM489.25 136.533c-7.168-1.963-14.063-4.898-20.48-8.67-8.124-4.779-10.837-15.241-6.059-23.364 3.191-5.393 8.892-8.414 14.729-8.414 2.935 0 5.922 0.751 8.636 2.355 3.857 2.27 7.97 4.011 12.271 5.205 9.079 2.492 14.421 11.895 11.913 20.975-2.526 9.079-11.913 14.387-21.009 11.913zM460.8 54.289c0 4.403 0.563 8.755 1.655 12.954 2.372 9.114-3.089 18.432-12.22 20.821-9.131 2.355-18.449-3.089-20.821-12.22-1.826-6.997-2.748-14.251-2.748-21.914v-0.034c0-9.438 7.629-16.862 17.067-16.862 9.438-0.017 17.067 7.817 17.067 17.254zM904.533 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM836.267 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM938.667 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM870.4 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM768 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM802.133 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM699.733 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM733.867 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM631.467 480.956c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM665.6 429.756c0-28.277-22.923-51.2-51.2-51.2s-51.2 22.923-51.2 51.2c0 28.277 22.923 51.2 51.2 51.2s51.2-22.923 51.2-51.2zM375.467 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM238.933 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM307.2 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM34.133 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM102.4 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM170.667 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM665.6 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM802.133 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM733.867 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM1006.933 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM870.4 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM938.667 71.356h-17.067c-9.421 0-17.067-7.629-17.067-17.067s7.646-17.067 17.067-17.067h17.067c9.421 0 17.067 7.629 17.067 17.067s-7.646 17.067-17.067 17.067zM529.067 173.756v17.067c0 9.438-7.646 17.067-17.067 17.067s-17.067-7.629-17.067-17.067v-17.067c0-9.438 7.646-17.067 17.067-17.067s17.067 7.629 17.067 17.067zM494.933 259.089v-17.067c0-9.438 7.646-17.067 17.067-17.067s17.067 7.629 17.067 17.067v17.067c0 9.438-7.646 17.067-17.067 17.067s-17.067-7.629-17.067-17.067z" /> +<glyph unicode="icon-comType3" glyph-name="icon-comType3" horiz-adv-x="1053" d="M184.32 853.463c-43.552 0-78.994-35.442-78.994-78.994s35.442-78.994 78.994-78.994c43.552 0 78.994 35.442 78.994 78.994s-35.442 78.994-78.994 78.994zM184.32 730.583c-24.19 0-43.886 19.678-43.886 43.886s19.696 43.886 43.886 43.886c24.19 0 43.886-19.678 43.886-43.886s-19.696-43.886-43.886-43.886zM906.971 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM836.754 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM942.080 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM871.863 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM766.537 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM801.646 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM696.32 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM731.429 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM626.103 800.8c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM661.211 748.137c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM1053.257 671.056v206.842c0 44.605-36.285 80.89-80.89 80.89h-891.477c-44.605 0-80.89-36.285-80.89-80.89v-206.842c0-25.787 12.341-48.52 31.194-63.336-18.853-14.833-31.194-37.566-31.194-63.353v-206.842c0-44.605 36.285-80.89 80.89-80.89h891.477c44.605 0 80.89 36.285 80.89 80.89v206.842c0 25.787-12.341 48.52-31.194 63.336 18.853 14.833 31.194 37.566 31.194 63.353zM1018.149 544.367v-206.842c0-25.243-20.539-45.782-45.782-45.782h-891.477c-25.243-0.018-45.782 20.521-45.782 45.782v206.842c0 25.243 20.539 45.782 45.782 45.782h891.459c25.261 0 45.799-20.539 45.799-45.782zM80.89 625.257c-25.243 0-45.782 20.539-45.782 45.799v206.842c0 25.243 20.539 45.782 45.782 45.782h891.459c25.261 0 45.799-20.539 45.799-45.782v-206.842c0-25.243-20.539-45.782-45.782-45.782l-891.477-0.018zM184.32 361.943c43.552 0 78.994 35.442 78.994 78.994s-35.442 78.994-78.994 78.994c-43.552 0-78.994-35.425-78.994-78.994s35.442-78.994 78.994-78.994zM184.32 484.823c24.19 0 43.886-19.678 43.886-43.886s-19.696-43.886-43.886-43.886c-24.19 0-43.886 19.678-43.886 43.886s19.696 43.886 43.886 43.886zM552.486 74.299c4.020-2.265 7.706-5.056 10.989-8.268 3.423-3.353 7.864-5.021 12.288-5.021 4.547 0 9.093 1.773 12.534 5.266 6.794 6.934 6.671 18.028-0.246 24.822-5.459 5.354-11.586 9.953-18.239 13.745-8.479 4.757-19.152 1.843-23.926-6.618-4.775-8.426-1.826-19.134 6.6-23.926zM553.030-17.177c-3.95-2.317-8.198-4.073-12.622-5.266-9.356-2.528-14.904-12.148-12.393-21.522 2.124-7.829 9.198-12.99 16.94-12.99 1.51 0 3.037 0.193 4.582 0.597 7.408 2.001 14.535 4.968 21.153 8.83 8.373 4.88 11.217 15.641 6.337 24.014-4.88 8.391-15.623 11.2-23.997 6.337zM596.846 46.387c-9.69 0-17.554-8.268-17.554-17.958 0-4.634-0.597-9.198-1.773-13.605-2.51-9.356 3.072-18.976 12.428-21.486 1.51-0.404 3.037-0.597 4.529-0.597 7.759 0 14.851 5.179 16.957 13.025 1.966 7.338 2.967 14.974 2.967 22.645v0.825c0 9.708-7.864 17.151-17.554 17.151zM500.473-17.282c-3.985 2.282-7.654 5.073-10.901 8.303-6.881 6.846-17.976 6.776-24.822-0.070-6.846-6.881-6.811-17.993 0.070-24.822 5.442-5.407 11.568-10.076 18.221-13.885 2.756-1.58 5.74-2.317 8.707-2.317 6.091 0 12.007 3.177 15.255 8.83 4.792 8.409 1.878 19.134-6.53 23.962zM503.229 113.006c-7.373-2.019-14.465-5.038-21.065-8.918-8.356-4.915-11.147-15.676-6.232-24.032 3.283-5.547 9.146-8.654 15.149-8.654 3.019 0 6.091 0.772 8.882 2.422 3.967 2.335 8.198 4.125 12.622 5.354 9.339 2.563 14.833 12.235 12.253 21.574-2.598 9.339-12.253 14.798-21.609 12.253zM473.966 28.412c0 4.529 0.579 9.005 1.703 13.324 2.44 9.374-3.177 18.959-12.569 21.416-9.392 2.422-18.976-3.177-21.416-12.569-1.878-7.197-2.826-14.658-2.826-22.54l17.554-0.035h-17.554c0-9.708 7.847-17.344 17.554-17.344 9.708-0.018 17.554 8.040 17.554 17.747zM906.971 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM836.754 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM942.080 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM871.863 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM766.537 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM801.646 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM696.32 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM731.429 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM626.103 467.269c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM661.211 414.606c0-16.158-13.099-29.257-29.257-29.257s-29.257 13.099-29.257 29.257c0 16.158 13.099 29.257 29.257 29.257s29.257-13.099 29.257-29.257zM386.194 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM245.76 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM315.977 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM35.109 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM105.326 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM175.543 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM684.617 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM825.051 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM754.834 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM1035.703 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM895.269 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM965.486 45.966h-17.554c-9.69 0-17.554-7.847-17.554-17.554s7.864-17.554 17.554-17.554h17.554c9.69 0 17.554 7.847 17.554 17.554s-7.864 17.554-17.554 17.554zM544.183 151.292v17.554c0 9.708-7.864 17.554-17.554 17.554s-17.554-7.847-17.554-17.554v-17.554c0-9.708 7.864-17.554 17.554-17.554s17.554 7.847 17.554 17.554zM509.074 239.063v-17.554c0-9.708 7.864-17.554 17.554-17.554s17.554 7.847 17.554 17.554v17.554c0 9.708-7.864 17.554-17.554 17.554s-17.554-7.847-17.554-17.554z" /> +<glyph unicode="icon-comType2-sm" glyph-name="icon-comType2-sm" horiz-adv-x="926" d="M918.242 804.814c-21.117 78.231-178.291 155.186-453.231 155.186s-432.132-76.955-453.231-155.186c-1.532-2.681-2.662-5.617-2.662-8.936v-674.722c0-2.954 0.784-5.744 2.134-8.224 21.536-89.264 214.215-155.897 453.76-155.897 238.998 0 431.366 66.36 453.614 155.296 1.459 2.608 2.279 5.617 2.279 8.826v674.722c0 3.319-1.131 6.255-2.662 8.936zM882.993 340.259c-0.511-2.207-1.222-4.395-2.115-6.62-0.729-1.805-1.623-3.611-2.608-5.416-1.222-2.243-2.589-4.486-4.212-6.729-1.204-1.696-2.571-3.374-3.994-5.051-2.024-2.389-4.176-4.778-6.62-7.148-1.477-1.441-3.1-2.863-4.741-4.304-2.991-2.608-6.109-5.197-9.592-7.768-1.495-1.112-3.1-2.188-4.687-3.282-4.121-2.845-8.425-5.671-13.148-8.443-1.24-0.748-2.571-1.459-3.866-2.188-5.434-3.064-11.106-6.109-17.233-9.063-0.784-0.383-1.605-0.748-2.407-1.112-6.838-3.228-13.987-6.401-21.628-9.464-0.219-0.091-0.438-0.164-0.656-0.255-41.413-16.54-94.388-30.454-156.116-39.572-0.31-0.036-0.62-0.073-0.93-0.128-11.999-1.769-24.308-3.337-36.946-4.723-2.061-0.219-4.231-0.365-6.31-0.584-11.033-1.149-22.193-2.207-33.681-3.045-5.252-0.383-10.759-0.565-16.102-0.894-8.644-0.511-17.196-1.076-26.059-1.386-14.479-0.456-29.25-0.748-44.331-0.748s-29.852 0.292-44.349 0.802c-8.863 0.31-17.415 0.894-26.059 1.386-5.343 0.31-10.85 0.511-16.102 0.894-11.489 0.839-22.649 1.897-33.681 3.045-2.079 0.219-4.249 0.365-6.31 0.584-12.637 1.386-24.946 2.972-36.946 4.723-0.31 0.036-0.62 0.073-0.93 0.128-61.728 9.118-114.703 23.032-156.116 39.572-0.219 0.073-0.438 0.164-0.656 0.255-7.641 3.064-14.807 6.237-21.628 9.464-0.784 0.383-1.623 0.748-2.407 1.112-6.127 2.954-11.799 5.981-17.233 9.063-1.277 0.729-2.626 1.441-3.866 2.188-4.723 2.772-9.027 5.598-13.148 8.443-1.568 1.094-3.191 2.17-4.687 3.282-3.483 2.571-6.601 5.161-9.592 7.768-1.623 1.422-3.264 2.845-4.741 4.304-2.444 2.371-4.595 4.741-6.62 7.148-1.422 1.678-2.79 3.355-3.994 5.051-1.605 2.243-2.972 4.486-4.212 6.729-0.985 1.805-1.86 3.611-2.608 5.416-0.894 2.207-1.605 4.413-2.115 6.62-0.675 2.899-1.422 5.854-1.422 8.79 0 2.061 0.237 4.121 0.565 6.164 0.456 2.754 0.201 5.507-0.565 8.115v135.382c0.511-0.474 1.149-0.93 1.678-1.404 3.975-3.501 8.024-6.984 12.583-10.34 68.694-51.954 206.064-92.328 405.162-92.328 198.259 0 335.282 40.046 404.268 91.689 5.507 4.012 10.467 8.151 15.136 12.364l0.018 0.018v-135.382c-0.766-2.608-1.021-5.361-0.565-8.115 0.346-2.042 0.565-4.103 0.565-6.164 0-2.936-0.748-5.89-1.441-8.844zM884.433 717.592v-135.382c-0.766-2.608-1.021-5.361-0.565-8.115 0.346-2.042 0.565-4.103 0.565-6.164 0-2.936-0.748-5.89-1.441-8.844-0.511-2.207-1.222-4.395-2.115-6.62-0.729-1.805-1.623-3.611-2.608-5.416-1.222-2.243-2.589-4.486-4.212-6.729-1.204-1.696-2.571-3.374-3.994-5.051-2.024-2.389-4.176-4.778-6.62-7.148-1.477-1.441-3.1-2.863-4.741-4.304-2.991-2.608-6.109-5.197-9.592-7.768-1.495-1.112-3.1-2.188-4.687-3.282-4.121-2.845-8.425-5.671-13.148-8.443-1.24-0.748-2.571-1.459-3.866-2.188-5.434-3.064-11.106-6.109-17.233-9.063-0.784-0.383-1.605-0.748-2.407-1.112-6.838-3.228-13.987-6.401-21.628-9.464-0.219-0.091-0.438-0.164-0.656-0.255-41.413-16.54-94.388-30.454-156.116-39.572-0.31-0.036-0.62-0.073-0.93-0.128-11.999-1.769-24.308-3.337-36.946-4.723-2.061-0.219-4.231-0.365-6.31-0.584-11.033-1.149-22.193-2.207-33.681-3.045-5.252-0.383-10.759-0.565-16.102-0.894-8.644-0.511-17.196-1.076-26.059-1.386-14.479-0.456-29.25-0.748-44.331-0.748s-29.852 0.292-44.349 0.802c-8.863 0.31-17.415 0.894-26.059 1.386-5.343 0.31-10.85 0.511-16.102 0.894-11.489 0.839-22.649 1.897-33.681 3.045-2.079 0.219-4.249 0.365-6.31 0.584-12.637 1.386-24.946 2.972-36.946 4.723-0.31 0.036-0.62 0.073-0.93 0.128-61.728 9.118-114.703 23.032-156.116 39.572-0.219 0.073-0.438 0.164-0.656 0.255-7.641 3.064-14.807 6.237-21.628 9.464-0.784 0.383-1.623 0.748-2.407 1.112-6.127 2.954-11.799 5.981-17.233 9.063-1.277 0.729-2.626 1.441-3.866 2.188-4.723 2.772-9.027 5.598-13.148 8.443-1.568 1.094-3.191 2.17-4.687 3.282-3.483 2.571-6.601 5.161-9.592 7.768-1.623 1.422-3.264 2.845-4.741 4.304-2.444 2.371-4.595 4.741-6.62 7.148-1.422 1.678-2.79 3.355-3.994 5.051-1.605 2.243-2.972 4.486-4.212 6.729-0.985 1.805-1.86 3.611-2.608 5.416-0.894 2.207-1.605 4.413-2.115 6.62-0.675 2.899-1.422 5.854-1.422 8.79 0 2.061 0.237 4.121 0.565 6.164 0.456 2.754 0.201 5.507-0.565 8.115v135.382c2.188-1.988 4.687-3.939 7.057-5.908 1.313-1.094 2.535-2.188 3.921-3.282 5.471-4.304 11.379-8.553 17.78-12.692 1.331-0.857 2.827-1.696 4.212-2.553 5.361-3.337 11.033-6.601 16.996-9.811 2.207-1.185 4.413-2.352 6.693-3.519 6.656-3.392 13.64-6.693 20.989-9.884 1.204-0.529 2.298-1.076 3.519-1.587 8.553-3.629 17.634-7.094 27.080-10.449 2.608-0.93 5.343-1.805 8.024-2.717 7.513-2.535 15.282-4.96 23.324-7.313 2.899-0.839 5.744-1.714 8.717-2.517 10.668-2.954 21.682-5.762 33.244-8.352 1.587-0.365 3.301-0.656 4.905-1.003 10.194-2.225 20.771-4.285 31.639-6.218 3.684-0.656 7.422-1.277 11.179-1.897 10.34-1.696 20.989-3.246 31.913-4.668 2.808-0.365 5.489-0.784 8.334-1.131 13.567-1.641 27.609-3.045 42.033-4.249 3.556-0.292 7.258-0.511 10.868-0.766 11.543-0.839 23.342-1.532 35.414-2.079 4.395-0.201 8.771-0.401 13.257-0.565 15.719-0.529 31.73-0.912 48.325-0.912s32.605 0.383 48.325 0.912c4.468 0.164 8.844 0.365 13.257 0.565 12.072 0.547 23.871 1.24 35.414 2.079 3.611 0.274 7.294 0.474 10.869 0.766 14.424 1.185 28.466 2.608 42.033 4.249 2.845 0.346 5.525 0.766 8.334 1.131 10.923 1.422 21.555 2.972 31.913 4.668 3.757 0.62 7.495 1.24 11.179 1.897 10.869 1.933 21.445 3.994 31.639 6.218 1.605 0.346 3.319 0.656 4.905 1.003 11.561 2.589 22.576 5.416 33.244 8.352 2.972 0.821 5.817 1.678 8.717 2.517 8.042 2.352 15.81 4.778 23.324 7.313 2.681 0.912 5.416 1.787 8.024 2.717 9.446 3.355 18.546 6.82 27.080 10.449 1.222 0.511 2.316 1.058 3.519 1.587 7.349 3.209 14.333 6.492 20.989 9.884 2.279 1.167 4.504 2.334 6.693 3.519 5.963 3.191 11.634 6.455 16.996 9.811 1.386 0.857 2.881 1.696 4.212 2.553 6.401 4.14 12.309 8.37 17.78 12.692 1.368 1.094 2.589 2.188 3.921 3.282 2.371 1.969 4.869 3.921 7.057 5.908zM465.011 923.529c247.185 0 419.422-72.068 419.422-136.768s-172.237-136.768-419.422-136.768c-247.185 0-419.422 72.068-419.422 136.768s172.237 136.768 419.422 136.768zM884.433 126.572c-0.255-0.802-0.438-1.623-0.584-2.462-10.34-63.077-181.117-130.604-418.838-130.604s-408.499 67.527-418.838 130.604c-0.146 0.821-0.346 1.623-0.584 2.389v153.435c0.511-0.474 1.149-0.93 1.678-1.404 3.975-3.501 8.024-6.984 12.583-10.34 68.694-51.954 206.064-92.328 405.162-92.328 198.259 0 335.282 40.046 404.268 91.689 5.507 4.012 10.467 8.151 15.136 12.364l0.018 0.018v-153.363z" /> +<glyph unicode="icon-comType2" glyph-name="icon-comType2" horiz-adv-x="945" d="M933.258 802.276c-21.462 79.511-181.206 157.724-460.642 157.724s-439.199-78.213-460.642-157.724c-1.557-2.724-2.706-5.708-2.706-9.082v-685.756c0-3.002 0.797-5.838 2.168-8.359 21.889-90.724 217.718-158.447 461.18-158.447 242.906 0 438.42 67.445 461.032 157.835 1.483 2.65 2.317 5.708 2.317 8.97v685.756c0 3.373-1.149 6.357-2.706 9.082zM897.432 330.124c-0.519-2.243-1.242-4.467-2.15-6.728-0.741-1.835-1.65-3.67-2.65-5.505-1.242-2.28-2.632-4.559-4.281-6.839-1.223-1.724-2.613-3.429-4.059-5.134-2.057-2.428-4.244-4.856-6.728-7.265-1.501-1.464-3.151-2.91-4.819-4.374-3.040-2.65-6.209-5.282-9.749-7.895-1.52-1.131-3.151-2.224-4.763-3.336-4.189-2.891-8.563-5.764-13.363-8.581-1.26-0.76-2.613-1.483-3.929-2.224-5.523-3.114-11.287-6.209-17.515-9.211-0.797-0.389-1.631-0.76-2.446-1.131-6.95-3.281-14.216-6.505-21.981-9.619-0.222-0.093-0.445-0.167-0.667-0.259-42.091-16.81-95.932-30.952-158.669-40.219-0.315-0.037-0.63-0.074-0.945-0.13-12.195-1.798-24.706-3.392-37.55-4.8-2.094-0.222-4.3-0.371-6.413-0.593-11.213-1.168-22.556-2.243-34.232-3.095-5.338-0.389-10.935-0.575-16.365-0.908-8.785-0.519-17.478-1.094-26.485-1.409-14.716-0.463-29.728-0.76-45.056-0.76s-30.34 0.297-45.075 0.815c-9.007 0.315-17.7 0.908-26.485 1.409-5.43 0.315-11.028 0.519-16.365 0.908-11.676 0.853-23.019 1.928-34.232 3.095-2.113 0.222-4.318 0.371-6.413 0.593-12.844 1.409-25.354 3.021-37.55 4.8-0.315 0.037-0.63 0.074-0.945 0.13-62.737 9.267-116.578 23.408-158.669 40.219-0.222 0.074-0.445 0.167-0.667 0.259-7.766 3.114-15.050 6.339-21.981 9.619-0.797 0.389-1.65 0.76-2.446 1.131-6.227 3.002-11.991 6.079-17.515 9.211-1.297 0.741-2.669 1.464-3.929 2.224-4.8 2.817-9.174 5.69-13.363 8.581-1.594 1.112-3.243 2.206-4.763 3.336-3.54 2.613-6.709 5.245-9.749 7.895-1.65 1.446-3.318 2.891-4.819 4.374-2.484 2.409-4.671 4.819-6.728 7.265-1.446 1.705-2.836 3.41-4.059 5.134-1.631 2.28-3.021 4.559-4.281 6.839-1.001 1.835-1.89 3.67-2.65 5.505-0.908 2.243-1.631 4.485-2.15 6.728-0.686 2.947-1.446 5.949-1.446 8.933 0 2.094 0.241 4.189 0.575 6.264 0.463 2.799 0.204 5.597-0.575 8.248v137.596c0.519-0.482 1.168-0.945 1.705-1.427 4.040-3.559 8.155-7.098 12.788-10.509 69.817-52.803 209.433-93.837 411.787-93.837 201.501 0 340.765 40.701 410.879 93.189 5.597 4.077 10.638 8.285 15.383 12.566l0.019 0.019v-137.596c-0.778-2.65-1.038-5.449-0.575-8.248 0.352-2.076 0.575-4.17 0.575-6.264 0-2.984-0.76-5.986-1.464-8.989zM898.896 713.628v-137.596c-0.778-2.65-1.038-5.449-0.575-8.248 0.352-2.076 0.575-4.17 0.575-6.264 0-2.984-0.76-5.986-1.464-8.989-0.519-2.243-1.242-4.467-2.15-6.728-0.741-1.835-1.65-3.67-2.65-5.505-1.242-2.28-2.632-4.559-4.281-6.839-1.223-1.724-2.613-3.429-4.059-5.134-2.057-2.428-4.244-4.856-6.728-7.265-1.501-1.464-3.151-2.91-4.819-4.374-3.040-2.65-6.209-5.282-9.749-7.895-1.52-1.131-3.151-2.224-4.763-3.336-4.189-2.891-8.563-5.764-13.363-8.581-1.26-0.76-2.613-1.483-3.929-2.224-5.523-3.114-11.287-6.209-17.515-9.211-0.797-0.389-1.631-0.76-2.446-1.131-6.95-3.281-14.216-6.505-21.981-9.619-0.222-0.093-0.445-0.167-0.667-0.259-42.091-16.81-95.932-30.952-158.669-40.219-0.315-0.037-0.63-0.074-0.945-0.13-12.195-1.798-24.706-3.392-37.55-4.8-2.094-0.222-4.3-0.371-6.413-0.593-11.213-1.168-22.556-2.243-34.232-3.095-5.338-0.389-10.935-0.575-16.365-0.908-8.785-0.519-17.478-1.094-26.485-1.409-14.716-0.463-29.728-0.76-45.056-0.76s-30.34 0.297-45.075 0.815c-9.007 0.315-17.7 0.908-26.485 1.409-5.43 0.315-11.028 0.519-16.365 0.908-11.676 0.853-23.019 1.928-34.232 3.095-2.113 0.222-4.318 0.371-6.413 0.593-12.844 1.409-25.354 3.021-37.55 4.8-0.315 0.037-0.63 0.074-0.945 0.13-62.737 9.267-116.578 23.408-158.669 40.219-0.222 0.074-0.445 0.167-0.667 0.259-7.766 3.114-15.050 6.339-21.981 9.619-0.797 0.389-1.65 0.76-2.446 1.131-6.227 3.002-11.991 6.079-17.515 9.211-1.297 0.741-2.669 1.464-3.929 2.224-4.8 2.817-9.174 5.69-13.363 8.581-1.594 1.112-3.243 2.206-4.763 3.336-3.54 2.613-6.709 5.245-9.749 7.895-1.65 1.446-3.318 2.891-4.819 4.374-2.484 2.409-4.671 4.819-6.728 7.265-1.446 1.705-2.836 3.41-4.059 5.134-1.631 2.28-3.021 4.559-4.281 6.839-1.001 1.835-1.89 3.67-2.65 5.505-0.908 2.243-1.631 4.485-2.15 6.728-0.686 2.947-1.446 5.949-1.446 8.933 0 2.094 0.241 4.189 0.575 6.264 0.463 2.799 0.204 5.597-0.575 8.248v137.596c2.224-2.020 4.763-4.003 7.173-6.005 1.334-1.112 2.576-2.224 3.985-3.336 5.56-4.374 11.565-8.692 18.071-12.9 1.353-0.871 2.873-1.724 4.281-2.595 5.449-3.392 11.213-6.709 17.274-9.971 2.243-1.205 4.485-2.391 6.802-3.577 6.765-3.447 13.863-6.802 21.333-10.045 1.223-0.537 2.335-1.094 3.577-1.612 8.692-3.688 17.922-7.21 27.523-10.62 2.65-0.945 5.43-1.835 8.155-2.762 7.636-2.576 15.531-5.041 23.705-7.432 2.947-0.853 5.838-1.742 8.859-2.558 10.842-3.002 22.037-5.857 33.787-8.489 1.612-0.371 3.355-0.667 4.986-1.019 10.36-2.261 21.11-4.355 32.156-6.32 3.744-0.667 7.543-1.297 11.361-1.928 10.509-1.724 21.333-3.299 32.434-4.745 2.854-0.371 5.579-0.797 8.47-1.149 13.789-1.668 28.060-3.095 42.721-4.318 3.614-0.297 7.377-0.519 11.046-0.778 11.732-0.853 23.723-1.557 35.993-2.113 4.467-0.204 8.915-0.408 13.474-0.575 15.976-0.537 32.249-0.927 49.115-0.927s33.139 0.389 49.115 0.927c4.541 0.167 8.989 0.371 13.474 0.575 12.269 0.556 24.261 1.26 35.993 2.113 3.67 0.278 7.414 0.482 11.046 0.778 14.66 1.205 28.931 2.65 42.721 4.318 2.891 0.352 5.616 0.778 8.47 1.149 11.102 1.446 21.907 3.021 32.434 4.745 3.818 0.63 7.617 1.26 11.361 1.928 11.046 1.965 21.796 4.059 32.156 6.32 1.631 0.352 3.373 0.667 4.986 1.019 11.751 2.632 22.945 5.505 33.787 8.489 3.021 0.834 5.912 1.705 8.859 2.558 8.173 2.391 16.069 4.856 23.705 7.432 2.724 0.927 5.505 1.816 8.155 2.762 9.601 3.41 18.849 6.932 27.523 10.62 1.242 0.519 2.354 1.075 3.577 1.612 7.469 3.262 14.568 6.598 21.333 10.045 2.317 1.186 4.578 2.372 6.802 3.577 6.061 3.243 11.825 6.561 17.274 9.971 1.409 0.871 2.928 1.724 4.281 2.595 6.505 4.207 12.51 8.507 18.071 12.9 1.39 1.112 2.632 2.224 3.985 3.336 2.409 2.002 4.949 3.985 7.173 6.005zM472.615 922.932c251.228 0 426.281-73.246 426.281-139.005s-175.053-139.005-426.281-139.005c-251.228 0-426.281 73.246-426.281 139.005s175.053 139.005 426.281 139.005zM898.896 112.943c-0.259-0.815-0.445-1.65-0.593-2.502-10.509-64.109-184.079-132.74-425.687-132.74s-415.179 68.631-425.687 132.74c-0.148 0.834-0.352 1.65-0.593 2.428v155.945c0.519-0.482 1.168-0.945 1.705-1.427 4.040-3.559 8.155-7.098 12.788-10.509 69.817-52.803 209.433-93.837 411.787-93.837 201.501 0 340.765 40.701 410.879 93.189 5.597 4.077 10.638 8.285 15.383 12.566l0.019 0.019v-155.87z" /> +<glyph unicode="icon-comType1-sm" glyph-name="icon-comType1-sm" d="M1024 940.966c-0.026 4.551-1.873 8.898-5.136 12.076-3.271 3.169-7.669 4.89-12.22 4.785h-989.288c-4.551 0.113-8.958-1.616-12.22-4.785s-5.119-7.525-5.136-12.076v-817.72c-0.051-9.712 7.644-17.712 17.356-18.034h237.907l8.322-18.678c2.975-6.703 9.864-10.788 17.178-10.178l34.856 2.644c13.034-16.186 28.153-30.576 44.966-42.788l-1.025-34.763c-0.212-7.356 4.237-14.051 11.102-16.695l74.042-28.585c6.839-2.636 14.602-0.695 19.39 4.864l22.602 26.195c20.653-1.924 41.449-1.39 61.975 1.61l24.195-25.237c5.042-5.254 12.814-6.805 19.483-3.89l72.746 31.831c6.737 2.949 10.89 9.831 10.347 17.169l-2.559 34.856c16.203 13.034 30.61 28.161 42.831 44.983l34.788-1.025c7.305-0.39 14.042 3.949 16.703 10.763l2.805 6.924h236.636c9.712 0.331 17.407 8.322 17.356 18.034v633.729c0 0.059 0 0.11 0 0.169s0 0.11 0 0.169v183.653zM989.288 923.11v-149.695h-954.576v149.695h954.576zM707.356 123.525c-5.983 0.195-11.644-2.729-14.949-7.72-12.915-19.39-29.102-36.39-47.839-50.237-4.788-3.534-7.424-9.288-6.992-15.22l2.347-31.915-50.39-22.042-22.127 23.076c-4.034 4.212-9.915 6.11-15.653 5.059-23.093-4.229-46.703-4.839-69.983-1.805-5.788 0.754-11.568-1.458-15.373-5.873l-20.593-23.864-51.178 19.737 0.941 31.898c0.178 5.975-2.746 11.627-7.72 14.949-19.39 12.915-36.39 29.102-50.237 47.839-3.542 4.78-9.288 7.415-15.22 6.983l-31.924-2.339-6.864 15.686c-0.449 1.686-1.153 3.305-2.093 4.788l-13.085 29.915 23.076 22.127c4.212 4.034 6.11 9.915 5.059 15.644-4.229 23.093-4.839 46.703-1.805 69.983 0.746 5.788-1.458 11.568-5.873 15.381l-23.864 20.593 19.737 51.178 31.898-0.941c5.983-0.195 11.644 2.729 14.949 7.72 12.915 19.398 29.102 36.398 47.839 50.237 4.788 3.542 7.424 9.288 6.992 15.229l-2.347 31.915 50.39 22.042 22.136-23.076c4.034-4.212 9.915-6.11 15.644-5.059 23.102 4.229 46.712 4.839 69.992 1.805 5.788-0.746 11.568 1.458 15.381 5.873l20.593 23.864 51.178-19.737-0.941-31.89c-0.178-5.983 2.737-11.636 7.72-14.958 19.39-12.907 36.39-29.102 50.229-47.839 3.542-4.78 9.288-7.415 15.22-6.983l31.915 2.347 22.051-50.39-23.085-22.127c-4.203-4.034-6.102-9.915-5.059-15.644 4.229-23.093 4.839-46.703 1.814-69.983-0.754-5.788 1.449-11.568 5.873-15.381l23.864-20.593-19.754-51.178-31.89 0.924zM783.407 139.924l12.364 32.407c2.636 6.89 0.703 14.695-4.856 19.559l-26.195 22.686c1.932 20.661 1.398 41.483-1.602 62.017l25.237 24.22c5.246 5.042 6.797 12.822 3.881 19.492l-31.822 72.746c-2.949 6.746-9.831 10.898-17.169 10.356l-34.864-2.559c-13.025 16.203-28.136 30.61-44.949 42.839l1.025 34.788c0.212 7.356-4.237 14.051-11.102 16.703l-74.042 28.576c-6.839 2.636-14.602 0.695-19.39-4.856l-22.61-26.212c-20.653 1.932-41.458 1.398-61.983-1.602l-24.195 25.246c-5.034 5.254-12.814 6.805-19.483 3.89l-72.746-31.822c-6.737-2.949-10.89-9.839-10.347-17.178l2.559-34.856c-16.203-13.034-30.602-28.161-42.831-44.975l-34.788 1.017c-7.364 0.237-14.068-4.212-16.703-11.093l-28.568-74.042c-2.636-6.839-0.695-14.602 4.856-19.39l26.203-22.61c-1.932-20.644-1.398-41.449 1.602-61.966l-25.229-24.203c-5.263-5.169-6.805-13.042-3.89-19.822l8.305-19.356h-205.364v598.78h954.576v-598.78h-205.881zM224.127 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.737-24.424-52.737-54.458s23.661-54.466 52.737-54.466zM224.127 868.525c9.941 0 18.025-8.864 18.025-19.746s-8.085-19.754-18.025-19.754c-9.932 0-18.025 8.856-18.025 19.746s8.093 19.754 18.025 19.754zM339.093 794.305c29.068 0 52.729 24.432 52.729 54.466s-23.644 54.458-52.729 54.458c-29.085 0-52.72-24.424-52.72-54.458s23.644-54.466 52.72-54.466zM339.093 868.525c9.932 0 18.017-8.864 18.017-19.746s-8.085-19.754-18.017-19.754c-9.941 0-18.008 8.856-18.008 19.746s8.076 19.754 18.008 19.754zM109.161 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.729-24.432-52.729-54.458s23.653-54.466 52.729-54.466zM109.161 868.525c9.932 0 18.025-8.864 18.025-19.746s-8.093-19.754-18.025-19.754c-9.932 0-18.017 8.864-18.017 19.754 0 10.898 8.085 19.746 18.017 19.746zM512 406.958c-92.22 0-166.983-74.763-166.983-166.992 0-92.22 74.763-166.983 166.983-166.983s166.983 74.763 166.983 166.983c-0.102 92.186-74.805 166.881-166.983 166.992zM512 107.695c-73.051 0-132.271 59.22-132.271 132.271 0 73.059 59.22 132.28 132.271 132.28s132.271-59.22 132.271-132.28c-0.076-73.017-59.254-132.186-132.271-132.271zM512 323.381c-46.068 0-83.415-37.347-83.415-83.415 0-46.059 37.347-83.407 83.415-83.407s83.407 37.339 83.407 83.407c-0.051 46.042-37.364 83.356-83.407 83.415v0zM512 191.271c-26.898 0-48.703 21.805-48.703 48.695 0 26.898 21.805 48.703 48.703 48.703s48.695-21.805 48.695-48.703c-0.025-26.881-21.814-48.661-48.695-48.695v0z" /> +<glyph unicode="icon-comType1" glyph-name="icon-comType1" d="M1024 940.966c-0.026 4.551-1.873 8.898-5.136 12.076-3.271 3.169-7.669 4.89-12.22 4.785h-989.288c-4.551 0.113-8.958-1.616-12.22-4.785s-5.119-7.525-5.136-12.076v-817.72c-0.051-9.712 7.644-17.712 17.356-18.034h237.907l8.322-18.678c2.975-6.703 9.864-10.788 17.178-10.178l34.856 2.644c13.034-16.186 28.153-30.576 44.966-42.788l-1.025-34.763c-0.212-7.356 4.237-14.051 11.102-16.695l74.042-28.585c6.839-2.636 14.602-0.695 19.39 4.864l22.602 26.195c20.653-1.924 41.449-1.39 61.975 1.61l24.195-25.237c5.042-5.254 12.814-6.805 19.483-3.89l72.746 31.831c6.737 2.949 10.89 9.831 10.347 17.169l-2.559 34.856c16.203 13.034 30.61 28.161 42.831 44.983l34.788-1.025c7.305-0.39 14.042 3.949 16.703 10.763l2.805 6.924h236.636c9.712 0.331 17.407 8.322 17.356 18.034v633.729c0 0.059 0 0.11 0 0.169s0 0.11 0 0.169v183.653zM989.288 923.11v-149.695h-954.576v149.695h954.576zM707.356 123.525c-5.983 0.195-11.644-2.729-14.949-7.72-12.915-19.39-29.102-36.39-47.839-50.237-4.788-3.534-7.424-9.288-6.992-15.22l2.347-31.915-50.39-22.042-22.127 23.076c-4.034 4.212-9.915 6.11-15.653 5.059-23.093-4.229-46.703-4.839-69.983-1.805-5.788 0.754-11.568-1.458-15.373-5.873l-20.593-23.864-51.178 19.737 0.941 31.898c0.178 5.975-2.746 11.627-7.72 14.949-19.39 12.915-36.39 29.102-50.237 47.839-3.542 4.78-9.288 7.415-15.22 6.983l-31.924-2.339-6.864 15.686c-0.449 1.686-1.153 3.305-2.093 4.788l-13.085 29.915 23.076 22.127c4.212 4.034 6.11 9.915 5.059 15.644-4.229 23.093-4.839 46.703-1.805 69.983 0.746 5.788-1.458 11.568-5.873 15.381l-23.864 20.593 19.737 51.178 31.898-0.941c5.983-0.195 11.644 2.729 14.949 7.72 12.915 19.398 29.102 36.398 47.839 50.237 4.788 3.542 7.424 9.288 6.992 15.229l-2.347 31.915 50.39 22.042 22.136-23.076c4.034-4.212 9.915-6.11 15.644-5.059 23.102 4.229 46.712 4.839 69.992 1.805 5.788-0.746 11.568 1.458 15.381 5.873l20.593 23.864 51.178-19.737-0.941-31.89c-0.178-5.983 2.737-11.636 7.72-14.958 19.39-12.907 36.39-29.102 50.229-47.839 3.542-4.78 9.288-7.415 15.22-6.983l31.915 2.347 22.051-50.39-23.085-22.127c-4.203-4.034-6.102-9.915-5.059-15.644 4.229-23.093 4.839-46.703 1.814-69.983-0.754-5.788 1.449-11.568 5.873-15.381l23.864-20.593-19.754-51.178-31.89 0.924zM783.407 139.924l12.364 32.407c2.636 6.89 0.703 14.695-4.856 19.559l-26.195 22.686c1.932 20.661 1.398 41.483-1.602 62.017l25.237 24.22c5.246 5.042 6.797 12.822 3.881 19.492l-31.822 72.746c-2.949 6.746-9.831 10.898-17.169 10.356l-34.864-2.559c-13.025 16.203-28.136 30.61-44.949 42.839l1.025 34.788c0.212 7.356-4.237 14.051-11.102 16.703l-74.042 28.576c-6.839 2.636-14.602 0.695-19.39-4.856l-22.61-26.212c-20.653 1.932-41.458 1.398-61.983-1.602l-24.195 25.246c-5.034 5.254-12.814 6.805-19.483 3.89l-72.746-31.822c-6.737-2.949-10.89-9.839-10.347-17.178l2.559-34.856c-16.203-13.034-30.602-28.161-42.831-44.975l-34.788 1.017c-7.364 0.237-14.068-4.212-16.703-11.093l-28.568-74.042c-2.636-6.839-0.695-14.602 4.856-19.39l26.203-22.61c-1.932-20.644-1.398-41.449 1.602-61.966l-25.229-24.203c-5.263-5.169-6.805-13.042-3.89-19.822l8.305-19.356h-205.364v598.78h954.576v-598.78h-205.881zM224.127 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.737-24.424-52.737-54.458s23.661-54.466 52.737-54.466zM224.127 868.525c9.941 0 18.025-8.864 18.025-19.746s-8.085-19.754-18.025-19.754c-9.932 0-18.025 8.856-18.025 19.746s8.093 19.754 18.025 19.754zM339.093 794.305c29.068 0 52.729 24.432 52.729 54.466s-23.644 54.458-52.729 54.458c-29.085 0-52.72-24.424-52.72-54.458s23.644-54.466 52.72-54.466zM339.093 868.525c9.932 0 18.017-8.864 18.017-19.746s-8.085-19.754-18.017-19.754c-9.941 0-18.008 8.856-18.008 19.746s8.076 19.754 18.008 19.754zM109.161 794.305c29.076 0 52.737 24.432 52.737 54.466s-23.653 54.458-52.737 54.458c-29.085 0-52.729-24.432-52.729-54.458s23.653-54.466 52.729-54.466zM109.161 868.525c9.932 0 18.025-8.864 18.025-19.746s-8.093-19.754-18.025-19.754c-9.932 0-18.017 8.864-18.017 19.754 0 10.898 8.085 19.746 18.017 19.746zM512 406.958c-92.22 0-166.983-74.763-166.983-166.992 0-92.22 74.763-166.983 166.983-166.983s166.983 74.763 166.983 166.983c-0.102 92.186-74.805 166.881-166.983 166.992zM512 107.695c-73.051 0-132.271 59.22-132.271 132.271 0 73.059 59.22 132.28 132.271 132.28s132.271-59.22 132.271-132.28c-0.076-73.017-59.254-132.186-132.271-132.271zM512 323.381c-46.068 0-83.415-37.347-83.415-83.415 0-46.059 37.347-83.407 83.415-83.407s83.407 37.339 83.407 83.407c-0.051 46.042-37.364 83.356-83.407 83.415v0zM512 191.271c-26.898 0-48.703 21.805-48.703 48.695 0 26.898 21.805 48.703 48.703 48.703s48.695-21.805 48.695-48.703c-0.025-26.881-21.814-48.661-48.695-48.695v0z" /> +<glyph unicode="icon-close" glyph-name="icon-close" d="M602.197 448.32l402.432 402.432c25.003 24.981 25.003 65.515 0 90.496-25.003 25.003-65.493 25.003-90.496 0l-402.432-402.432-402.453 402.432c-25.003 25.003-65.493 25.003-90.496 0-25.003-24.981-25.003-65.515 0-90.496l402.453-402.432-402.453-402.432c-25.003-24.981-25.003-65.515 0-90.496 12.501-12.48 28.885-18.731 45.248-18.731s32.747 6.251 45.248 18.752l402.453 402.432 402.432-402.432c12.501-12.501 28.885-18.752 45.248-18.752s32.747 6.251 45.248 18.752c25.003 24.981 25.003 65.515 0 90.496l-402.432 402.411z" /> +<glyph unicode="icon-clone-sm" glyph-name="icon-clone-sm" horiz-adv-x="796" d="M197.666 693.407c15.831 0 28.663 12.832 28.663 28.663v196.012h239.183c15.831 0 28.671-12.832 28.671-28.671v-132.42h-78.057c-7.711 0-15.004-3.122-20.298-8.408l-224.675-224.682c-5.042-5.035-8.408-12.314-8.408-20.255v-355.096h-132.42c-15.839 0-28.671 12.839-28.671 28.671v516.186h196.012zM168.996 877.543v-126.802h-126.802zM444.776 503.645v196.012h239.162c15.839 0 28.671-12.839 28.671-28.671v-667.013c0-15.839-12.832-28.671-28.671-28.671h-435.188c-15.831 0-28.671 12.832-28.671 28.671v471.001h196.033c15.824 0 28.663 12.825 28.663 28.671zM387.442 532.316h-126.802l126.802 126.781zM657.88 895.073v64.927l-86.57-86.57 86.57-86.57v64.927c47.735 0 86.57-38.835 86.57-86.57v-43.285h43.285v43.285c0 71.603-58.254 129.854-129.854 129.854z" /> +<glyph unicode="icon-btn-card-topology" glyph-name="icon-btn-card-topology" d="M944 960h-864c-44.16-0.052-79.948-35.84-80-80v-864c0.052-44.16 35.84-79.948 80-80h864c44.16 0.052 79.948 35.84 80 80v864c-0.052 44.16-35.84 79.948-80 80zM992 16c0-26.51-21.49-48-48-48h-864c-26.51 0-48 21.49-48 48v864c0 26.51 21.49 48 48 48h864c26.51 0 48-21.49 48-48v-864zM112 880c-0.442 0.010-0.884 0.010-1.326 0-17.306-0.366-31.040-14.694-30.674-32v-64h32v64h80v32h-80zM848 800h-672c-8.836 0-16-7.164-16-16v-192c0-8.836 7.164-16 16-16h672c8.836 0 16 7.164 16 16v192c0 8.836-7.164 16-16 16zM832 608h-640v160h640v-160zM432 528h-256c-8.836 0-16-7.164-16-16v-256c0-8.836 7.164-16 16-16h256c8.836 0 16 7.164 16 16v256c0 8.836-7.164 16-16 16zM192 272v201.376l201.376-201.376h-201.376zM416 294.63l-201.37 201.37h201.37v-201.37zM848 528h-352c-8.836 0-16-11.462-16-25.6v-153.6c0-14.138 7.164-25.6 16-25.6h352c8.836 0 16 11.462 16 25.6v153.6c0 14.138-7.164 25.6-16 25.6zM832 374.4h-320v102.4h320v-102.4zM480 352h384v-78.769h-384v78.769zM480 272h384v-78.769h-384v78.769zM288 192h576v-78.769h-576v78.769zM160 112h576v-78.769h-576v78.769zM160 192h78.769v-78.769h-78.769v78.769zM224 192h78.769v-78.769h-78.769v78.769z" /> +<glyph unicode="icon-btn-card-config" glyph-name="icon-btn-card-config" d="M971.283 561.778h-95.801c-15.398 0-28.084 8.476-33.982 22.699s-2.901 29.203 7.964 40.088l67.736 67.717c9.956 9.956 15.436 23.211 15.436 37.281 0 14.089-5.48 27.326-15.436 37.3l-86.338 86.338c-19.911 19.911-54.632 19.949-74.581 0l-67.717-67.717c-10.885-10.866-25.903-13.9-40.088-7.983-14.222 5.897-22.699 18.584-22.699 33.982v95.801c0 29.070-23.647 52.717-52.717 52.717h-122.121c-29.070 0-52.717-23.647-52.717-52.717v-95.801c0-15.398-8.476-28.084-22.699-33.982-14.184-5.935-29.203-2.882-40.088 7.983l-67.717 67.717c-19.949 19.949-54.67 19.911-74.581 0l-86.338-86.338c-9.956-9.956-15.436-23.211-15.436-37.3 0-14.071 5.48-27.307 15.436-37.281l67.736-67.717c10.866-10.885 13.843-25.865 7.964-40.088s-18.584-22.699-33.982-22.699h-95.801c-29.070 0-52.717-23.647-52.717-52.717v-122.103c0-29.089 23.647-52.736 52.717-52.736h95.801c15.398 0 28.084-8.476 33.982-22.699s2.901-29.203-7.964-40.088l-67.736-67.717c-9.956-9.956-15.436-23.211-15.436-37.281 0-14.089 5.48-27.326 15.436-37.3l86.338-86.338c19.93-19.93 54.632-19.968 74.581 0l67.717 67.736c10.885 10.866 25.847 13.862 40.088 7.964 14.222-5.897 22.699-18.584 22.699-33.982v-95.801c0-29.070 23.647-52.717 52.717-52.717h122.103c29.070 0 52.717 23.647 52.717 52.717v95.801c0 15.398 8.476 28.084 22.699 33.982 14.241 5.916 29.203 2.901 40.088-7.964l67.717-67.736c19.949-19.949 54.67-19.911 74.581 0l86.338 86.338c9.956 9.956 15.436 23.211 15.436 37.3 0 14.071-5.48 27.307-15.436 37.281l-67.736 67.717c-10.866 10.885-13.843 25.865-7.964 40.088s18.603 22.699 34.001 22.699h95.801c29.070 0 52.717 23.647 52.717 52.717v122.121c0 29.070-23.647 52.717-52.717 52.717zM986.074 386.939c0-8.154-6.637-14.791-14.791-14.791h-95.801c-30.796 0-57.249-17.673-69.025-46.118-11.795-28.444-5.594-59.657 16.194-81.427l67.736-67.717c5.784-5.784 5.784-15.17 0-20.935l-86.338-86.338c-5.765-5.765-15.151-5.803-20.935 0l-67.717 67.736c-21.788 21.788-52.983 27.951-81.427 16.194-28.444-11.776-46.118-38.229-46.118-69.025v-95.801c0-8.154-6.637-14.791-14.791-14.791h-122.121c-8.154 0-14.791 6.637-14.791 14.791v95.801c0 30.796-17.673 57.249-46.118 69.025-9.538 3.963-19.361 5.897-29.070 5.897-19.228 0-37.869-7.585-52.357-22.073l-67.717-67.736c-5.803-5.803-15.189-5.765-20.935 0l-86.338 86.338c-5.784 5.784-5.784 15.17 0 20.935l67.736 67.717c21.769 21.769 27.989 52.983 16.194 81.427-11.776 28.425-38.229 46.099-69.025 46.099h-95.801c-8.154 0-14.791 6.637-14.791 14.791v122.121c0 8.154 6.637 14.791 14.791 14.791h95.801c30.796 0 57.249 17.673 69.025 46.118 11.795 28.444 5.594 59.657-16.194 81.427l-67.736 67.717c-5.784 5.784-5.784 15.17 0 20.935l86.338 86.338c5.765 5.784 15.151 5.784 20.935 0l67.717-67.717c21.751-21.751 52.945-27.989 81.427-16.194 28.444 11.757 46.118 38.21 46.118 69.006v95.801c0 8.154 6.637 14.791 14.791 14.791h122.103c8.173 0 14.81-6.637 14.81-14.791v-95.801c0-30.796 17.673-57.249 46.118-69.025 28.482-11.795 59.657-5.575 81.427 16.194l67.717 67.717c5.803 5.784 15.189 5.784 20.935 0l86.338-86.338c5.784-5.784 5.784-15.17 0-20.935l-67.736-67.717c-21.769-21.769-27.989-52.983-16.194-81.427 11.776-28.444 38.229-46.118 69.025-46.118h95.801c8.154 0.019 14.791-6.618 14.791-14.772v-122.121zM512 618.667c-94.113 0-170.667-76.553-170.667-170.667s76.553-170.667 170.667-170.667c94.113 0 170.667 76.553 170.667 170.667s-76.553 170.667-170.667 170.667zM512 315.259c-73.178 0-132.741 59.563-132.741 132.741s59.563 132.741 132.741 132.741c73.178 0 132.741-59.563 132.741-132.741s-59.563-132.741-132.741-132.741z" /> +<glyph unicode="icon-archive-sm" glyph-name="icon-archive-sm" d="M943.405 684.258h-864.783c-10.653 0-19.867-3.887-27.644-11.668-7.781-7.777-11.668-16.991-11.668-27.637v-589.626c0-10.644 3.887-19.863 11.668-27.637 7.777-7.781 16.991-11.677 27.644-11.677h864.783c10.647 0 19.854 3.896 27.637 11.677 7.775 7.773 11.662 16.991 11.662 27.637v589.626c0 10.653-3.872 19.858-11.662 27.637-7.775 7.781-16.991 11.668-27.637 11.668zM617.255 499.387c-7.773-7.779-16.991-11.668-27.637-11.668h-157.233c-10.64 0-19.854 3.892-27.637 11.668-7.777 7.781-11.668 16.991-11.668 27.644 0 10.644 3.892 19.858 11.668 27.637 7.781 7.781 16.995 11.673 27.637 11.673h157.249c10.638 0 19.85-3.892 27.637-11.673 7.775-7.777 11.662-16.991 11.662-27.637 0-10.651-3.896-19.863-11.677-27.644zM1010.357 947.749c-7.783 7.781-16.991 11.668-27.639 11.668h-943.409c-10.644 0-19.858-3.887-27.637-11.668-7.779-7.777-11.671-16.991-11.671-27.637v-157.233c0-10.644 3.892-19.854 11.673-27.637 7.779-7.781 16.991-11.668 27.637-11.668h943.394c10.644 0 19.863 3.887 27.652 11.668 7.773 7.781 11.66 16.991 11.66 27.637v157.233c0 10.653-3.887 19.86-11.66 27.637z" /> +<glyph unicode="icon-add" glyph-name="icon-add" d="M512 960c-282.785 0-512-229.215-512-512s229.215-512 512-512c282.785 0 512 229.249 512 512s-229.215 512-512 512zM512 0c-247.425 0-448 200.575-448 448s200.575 448 448 448c247.425 0 448-200.575 448-448s-200.575-448-448-448zM704 480h-160v160c0 17.664-14.336 32-32 32s-32-14.336-32-32v-160h-160c-17.664 0-32-14.336-32-32s14.336-32 32-32h160v-160c0-17.664 14.336-32 32-32s32 14.336 32 32v160h160c17.664 0 32 14.336 32 32s-14.336 32-32 32z" /> </font></defs></svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.ttf b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.ttf Binary files differindex 67d9da298..85433c9af 100755 --- a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.ttf +++ b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.ttf diff --git a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.woff b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.woff Binary files differindex 6378c642f..7062f6c01 100755 --- a/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.woff +++ b/cds-ui/designer-client/src/assets/icomoon/fonts/icomoon.woff diff --git a/cds-ui/designer-client/src/assets/icomoon/style.css b/cds-ui/designer-client/src/assets/icomoon/style.css index cc5d3fb83..4e99ab416 100755 --- a/cds-ui/designer-client/src/assets/icomoon/style.css +++ b/cds-ui/designer-client/src/assets/icomoon/style.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('fonts/icomoon.eot?3iboyv'); - src: url('fonts/icomoon.eot?3iboyv#iefix') format('embedded-opentype'), - url('fonts/icomoon.ttf?3iboyv') format('truetype'), - url('fonts/icomoon.woff?3iboyv') format('woff'), - url('fonts/icomoon.svg?3iboyv#icomoon') format('svg'); + src: url('fonts/icomoon.eot?njx1om'); + src: url('fonts/icomoon.eot?njx1om#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?njx1om') format('truetype'), + url('fonts/icomoon.woff?njx1om') format('woff'), + url('fonts/icomoon.svg?njx1om#icomoon') format('svg'); font-weight: normal; font-style: normal; font-display: block; @@ -19,63 +19,136 @@ font-variant: normal; text-transform: none; line-height: 1; + + /* Enable Ligatures ================ */ + letter-spacing: 0; + -webkit-font-feature-settings: "liga"; + -moz-font-feature-settings: "liga=1"; + -moz-font-feature-settings: "liga"; + -ms-font-feature-settings: "liga" 1; + font-feature-settings: "liga"; + -webkit-font-variant-ligatures: discretionary-ligatures; + font-variant-ligatures: discretionary-ligatures; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -.icon-package:before { - content: "\e90f"; +.icon-enter-link:before { + content: "\e902"; } -.icon-dictionary:before { - content: "\e910"; +.icon-use-attributes:before { + content: "\e900"; } -.icon-deploy:before { - content: "\e911"; +.icon-upload-attributes:before { + content: "\e901"; } -.icon-Upload-attribute:before { - content: "\e90c"; +.icon-add:before { + content: "\e915"; } -.icon-import-cds:before { - content: "\e90d"; +.icon-archive-sm:before { + content: "\e952"; } -.icon-current-template:before { - content: "\e90e"; +.icon-btn-card-config:before { + content: "\e953"; } -.icon-generic-script-mode:before { - content: "\e900"; +.icon-btn-card-topology:before { + content: "\e954"; } -.icon-clone:before { - content: "\e901"; +.icon-clone-sm:before { + content: "\e955"; } -.icon-delete:before { - content: "\e902"; +.icon-close:before { + content: "\e956"; +} +.icon-comType1:before { + content: "\e957"; +} +.icon-comType1-sm:before { + content: "\e958"; +} +.icon-comType2:before { + content: "\e959"; +} +.icon-comType2-sm:before { + content: "\e95a"; +} +.icon-comType3:before { + content: "\e95b"; +} +.icon-comType3-sm:before { + content: "\e95c"; +} +.icon-comType4-sm:before { + content: "\e95d"; +} +.icon-create-white:before { + content: "\e95e"; } -.icon-designer-mode:before { - content: "\e903"; +.icon-delete-sm:before { + content: "\e95f"; } -.icon-scripting-mode:before { - content: "\e904"; +.icon-deploy-inactive:before { + content: "\e965"; } -.icon-archive:before { - content: "\e905"; +.icon-discard-sm:before { + content: "\e966"; } -.icon-enter:before { - content: "\e906"; +.icon-download:before { + content: "\e967"; +} +.icon-drag:before { + content: "\e968"; +} +.icon-edit:before { + content: "\e969"; } .icon-file-code:before { - content: "\e907"; + content: "\e96a"; +} +.icon-import-blue:before { + content: "\e96b"; +} +.icon-info:before { + content: "\e96c"; +} +.icon-menuDots:before { + content: "\e96d"; +} +.icon-nav-dictionary:before { + content: "\e96e"; +} +.icon-nav-packages:before { + content: "\e96f"; +} +.icon-redo:before { + content: "\e970"; +} +.icon-remove-file:before { + content: "\e971"; +} +.icon-save-sm:before { + content: "\e972"; +} +.icon-search:before { + content: "\e973"; +} +.icon-search-light:before { + content: "\e974"; +} +.icon-topologySource:before { + content: "\e975"; } -.icon-drag-menu:before { - content: "\e908"; +.icon-topologyView-active:before { + content: "\e976"; } -.icon-mapping:before { - content: "\e909"; +.icon-undoActive:before { + content: "\e977"; } -.icon-template-mapping:before { - content: "\e90a"; +.icon-zoomIn:before { + content: "\e978"; } -.icon-template:before { - content: "\e90b"; +.icon-zoomOut:before { + content: "\e979"; } diff --git a/cds-ui/designer-client/src/assets/img/icon-deploy-active.svg b/cds-ui/designer-client/src/assets/img/icon-deploy-active.svg new file mode 100644 index 000000000..adaf6956e --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-deploy-active.svg @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 59.1 (86144) - https://sketch.com --> + <title>deploy</title> + <desc>Created with Sketch.</desc> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="1.1.1-Packages-List" transform="translate(-678.000000, -229.000000)" fill-rule="nonzero"> + <g id="Tab-content" transform="translate(80.000000, 155.000000)"> + <g id="cards" transform="translate(0.000000, 48.000000)"> + <g id="row-1"> + <g id="1" transform="translate(337.000000, 0.000000)"> + <g id="info" transform="translate(20.000000, 20.000000)"> + <g id="deploy" transform="translate(241.000000, 6.000000)"> + <path d="M11.30545,8.97628333 L10.0929833,10.7182833 L9.23736667,10.0160667 C9.14506667,9.94001667 9.00835,9.95388333 8.93251667,10.0459667 C8.85646667,10.1384833 8.8699,10.2752 8.96263333,10.3508167 L9.9996,11.2021 C10.0386,11.2341667 10.0871333,11.2515 10.1369667,11.2515 C10.1467167,11.2515 10.1566833,11.25085 10.16665,11.2493333 C10.22645,11.2411 10.2801833,11.2081667 10.31485,11.15855 L11.6612167,9.22393333 C11.7294667,9.12578333 11.7054167,8.9908 11.60705,8.92233333 C11.5086833,8.853 11.3739167,8.8777 11.30545,8.97628333 Z" id="Path" fill="#000000"></path> + <path d="M10.1833333,7.36666667 C8.63026667,7.36666667 7.36666667,8.63026667 7.36666667,10.1833333 C7.36666667,11.7364 8.63026667,13 10.1833333,13 C11.7364,13 13,11.7364 13,10.1833333 C13,8.63026667 11.7364,7.36666667 10.1833333,7.36666667 Z M10.1833333,12.5666667 C8.86925,12.5666667 7.8,11.4974167 7.8,10.1833333 C7.8,8.86925 8.86925,7.8 10.1833333,7.8 C11.4974167,7.8 12.5666667,8.86925 12.5666667,10.1833333 C12.5666667,11.4974167 11.4974167,12.5666667 10.1833333,12.5666667 Z" id="Shape" fill="#000000"></path> + <path d="M12.0016,0 L0.9984,0 C0.44785,0 0,0.44785 0,0.9984 L0,3.55138333 C0,3.76241667 0.0680333333,3.95633333 0.180916667,4.11666667 L12.8188667,4.11666667 C12.9319667,3.95633333 13,3.76241667 13,3.5516 L13,0.9984 C13,0.44785 12.55215,0 12.0016,0 Z M2.275,3.25 C1.73745,3.25 1.3,2.81255 1.3,2.275 C1.3,1.73745 1.73745,1.3 2.275,1.3 C2.81255,1.3 3.25,1.73745 3.25,2.275 C3.25,2.81255 2.81255,3.25 2.275,3.25 Z M7.36666667,2.16666667 C7.24706667,2.16666667 7.15,2.0696 7.15,1.95 C7.15,1.8304 7.24706667,1.73333333 7.36666667,1.73333333 C7.48626667,1.73333333 7.58333333,1.8304 7.58333333,1.95 C7.58333333,2.0696 7.48626667,2.16666667 7.36666667,2.16666667 Z M7.8,2.81666667 C7.6804,2.81666667 7.58333333,2.7196 7.58333333,2.6 C7.58333333,2.4804 7.6804,2.38333333 7.8,2.38333333 C7.9196,2.38333333 8.01666667,2.4804 8.01666667,2.6 C8.01666667,2.7196 7.9196,2.81666667 7.8,2.81666667 Z M8.23333333,2.16666667 C8.11373333,2.16666667 8.01666667,2.0696 8.01666667,1.95 C8.01666667,1.8304 8.11373333,1.73333333 8.23333333,1.73333333 C8.35293333,1.73333333 8.45,1.8304 8.45,1.95 C8.45,2.0696 8.35293333,2.16666667 8.23333333,2.16666667 Z M8.66666667,2.81666667 C8.54706667,2.81666667 8.45,2.7196 8.45,2.6 C8.45,2.4804 8.54706667,2.38333333 8.66666667,2.38333333 C8.78626667,2.38333333 8.88333333,2.4804 8.88333333,2.6 C8.88333333,2.7196 8.78626667,2.81666667 8.66666667,2.81666667 Z M9.1,2.16666667 C8.9804,2.16666667 8.88333333,2.0696 8.88333333,1.95 C8.88333333,1.8304 8.9804,1.73333333 9.1,1.73333333 C9.2196,1.73333333 9.31666667,1.8304 9.31666667,1.95 C9.31666667,2.0696 9.2196,2.16666667 9.1,2.16666667 Z M9.53333333,2.81666667 C9.41373333,2.81666667 9.31666667,2.7196 9.31666667,2.6 C9.31666667,2.4804 9.41373333,2.38333333 9.53333333,2.38333333 C9.65293333,2.38333333 9.75,2.4804 9.75,2.6 C9.75,2.7196 9.65293333,2.81666667 9.53333333,2.81666667 Z M9.96666667,2.16666667 C9.84706667,2.16666667 9.75,2.0696 9.75,1.95 C9.75,1.8304 9.84706667,1.73333333 9.96666667,1.73333333 C10.0862667,1.73333333 10.1833333,1.8304 10.1833333,1.95 C10.1833333,2.0696 10.0862667,2.16666667 9.96666667,2.16666667 Z M10.4,2.81666667 C10.2804,2.81666667 10.1833333,2.7196 10.1833333,2.6 C10.1833333,2.4804 10.2804,2.38333333 10.4,2.38333333 C10.5196,2.38333333 10.6166667,2.4804 10.6166667,2.6 C10.6166667,2.7196 10.5196,2.81666667 10.4,2.81666667 Z M10.8333333,2.16666667 C10.7137333,2.16666667 10.6166667,2.0696 10.6166667,1.95 C10.6166667,1.8304 10.7137333,1.73333333 10.8333333,1.73333333 C10.9529333,1.73333333 11.05,1.8304 11.05,1.95 C11.05,2.0696 10.9529333,2.16666667 10.8333333,2.16666667 Z M11.2666667,2.81666667 C11.1470667,2.81666667 11.05,2.7196 11.05,2.6 C11.05,2.4804 11.1470667,2.38333333 11.2666667,2.38333333 C11.3862667,2.38333333 11.4833333,2.4804 11.4833333,2.6 C11.4833333,2.7196 11.3862667,2.81666667 11.2666667,2.81666667 Z" id="Shape" fill="#66BB00"></path> + <path d="M6.71666667,10.1833333 C6.71666667,9.63906667 6.84623333,9.12556667 7.07091667,8.66666667 L0.180916667,8.66666667 C0.0680333333,8.827 0,9.02091667 0,9.23173333 L0,11.7847167 C0,12.3354833 0.44785,12.7833333 0.9984,12.7833333 L7.89793333,12.7833333 C7.17556667,12.1474167 6.71666667,11.219 6.71666667,10.1833333 Z M2.275,11.4833333 C1.73745,11.4833333 1.3,11.0458833 1.3,10.5083333 C1.3,9.97078333 1.73745,9.53333333 2.275,9.53333333 C2.81255,9.53333333 3.25,9.97078333 3.25,10.5083333 C3.25,11.0458833 2.81255,11.4833333 2.275,11.4833333 Z" id="Shape" fill="#66BB00"></path> + <path d="M0.180916667,4.55 C0.0680333333,4.71033333 0,4.90425 0,5.11506667 L0,7.66805 C0,7.87908333 0.0680333333,8.073 0.180916667,8.23333333 L7.31921667,8.23333333 C7.94408333,7.31856667 8.99448333,6.71666667 10.1831167,6.71666667 C11.2931,6.71666667 12.28045,7.24316667 12.9152833,8.0574 C12.9679333,7.9378 12.9997833,7.80736667 12.9997833,7.66826667 L12.9997833,5.11506667 C12.9997833,4.90403333 12.93175,4.71033333 12.8188667,4.55 L0.180916667,4.55 Z M2.275,7.36666667 C1.73745,7.36666667 1.3,6.92921667 1.3,6.39166667 C1.3,5.85411667 1.73745,5.41666667 2.275,5.41666667 C2.81255,5.41666667 3.25,5.85411667 3.25,6.39166667 C3.25,6.92921667 2.81255,7.36666667 2.275,7.36666667 Z M7.36666667,6.28333333 C7.24706667,6.28333333 7.15,6.18626667 7.15,6.06666667 C7.15,5.94706667 7.24706667,5.85 7.36666667,5.85 C7.48626667,5.85 7.58333333,5.94706667 7.58333333,6.06666667 C7.58333333,6.18626667 7.48626667,6.28333333 7.36666667,6.28333333 Z M8.23333333,6.28333333 C8.11373333,6.28333333 8.01666667,6.18626667 8.01666667,6.06666667 C8.01666667,5.94706667 8.11373333,5.85 8.23333333,5.85 C8.35293333,5.85 8.45,5.94706667 8.45,6.06666667 C8.45,6.18626667 8.35293333,6.28333333 8.23333333,6.28333333 Z M9.1,6.28333333 C8.9804,6.28333333 8.88333333,6.18626667 8.88333333,6.06666667 C8.88333333,5.94706667 8.9804,5.85 9.1,5.85 C9.2196,5.85 9.31666667,5.94706667 9.31666667,6.06666667 C9.31666667,6.18626667 9.2196,6.28333333 9.1,6.28333333 Z M9.96666667,6.28333333 C9.84706667,6.28333333 9.75,6.18626667 9.75,6.06666667 C9.75,5.94706667 9.84706667,5.85 9.96666667,5.85 C10.0862667,5.85 10.1833333,5.94706667 10.1833333,6.06666667 C10.1833333,6.18626667 10.0862667,6.28333333 9.96666667,6.28333333 Z M10.8333333,6.28333333 C10.7137333,6.28333333 10.6166667,6.18626667 10.6166667,6.06666667 C10.6166667,5.94706667 10.7137333,5.85 10.8333333,5.85 C10.9529333,5.85 11.05,5.94706667 11.05,6.06666667 C11.05,6.18626667 10.9529333,6.28333333 10.8333333,6.28333333 Z" id="Shape" fill="#66BB00"></path> + </g> + </g> + </g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-deploy-inactive.svg b/cds-ui/designer-client/src/assets/img/icon-deploy-inactive.svg new file mode 100644 index 000000000..a5fb1a91f --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-deploy-inactive.svg @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="11px" height="11px" viewBox="0 0 11 11" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>deploy</title> + <desc>Created with Sketch.</desc> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Package-Info---View" transform="translate(-268.000000, -29.000000)" fill="#C1CDDD" fill-rule="nonzero"> + <g id="info"> + <g transform="translate(56.000000, 24.000000)"> + <g id="left-side"> + <g id="name" transform="translate(60.000000, 0.000000)"> + <g id="deploy" transform="translate(152.000000, 5.000000)"> + <path d="M9.56615,7.59531667 L8.54021667,9.06931667 L7.81623333,8.47513333 C7.73813333,8.41078333 7.62245,8.42251667 7.55828333,8.50043333 C7.49393333,8.57871667 7.5053,8.6944 7.58376667,8.75838333 L8.4612,9.4787 C8.4942,9.50583333 8.53526667,9.5205 8.57743333,9.5205 C8.58568333,9.5205 8.59411667,9.51995 8.60255,9.51866667 C8.65315,9.5117 8.69861667,9.48383333 8.72795,9.44185 L9.86718333,7.80486667 C9.92493333,7.72181667 9.90458333,7.6076 9.82135,7.54966667 C9.73811667,7.491 9.62408333,7.5119 9.56615,7.59531667 Z" id="Path"></path> + <path d="M8.61666667,6.23333333 C7.30253333,6.23333333 6.23333333,7.30253333 6.23333333,8.61666667 C6.23333333,9.9308 7.30253333,11 8.61666667,11 C9.9308,11 11,9.9308 11,8.61666667 C11,7.30253333 9.9308,6.23333333 8.61666667,6.23333333 Z M8.61666667,10.6333333 C7.50475,10.6333333 6.6,9.72858333 6.6,8.61666667 C6.6,7.50475 7.50475,6.6 8.61666667,6.6 C9.72858333,6.6 10.6333333,7.50475 10.6333333,8.61666667 C10.6333333,9.72858333 9.72858333,10.6333333 8.61666667,10.6333333 Z" id="Shape"></path> + <path d="M10.1552,0 L0.8448,0 C0.37895,0 0,0.37895 0,0.8448 L0,3.00501667 C0,3.18358333 0.0575666667,3.34766667 0.153083333,3.48333333 L10.8467333,3.48333333 C10.9424333,3.34766667 11,3.18358333 11,3.0052 L11,0.8448 C11,0.37895 10.62105,0 10.1552,0 Z M1.925,2.75 C1.47015,2.75 1.1,2.37985 1.1,1.925 C1.1,1.47015 1.47015,1.1 1.925,1.1 C2.37985,1.1 2.75,1.47015 2.75,1.925 C2.75,2.37985 2.37985,2.75 1.925,2.75 Z M6.23333333,1.83333333 C6.13213333,1.83333333 6.05,1.7512 6.05,1.65 C6.05,1.5488 6.13213333,1.46666667 6.23333333,1.46666667 C6.33453333,1.46666667 6.41666667,1.5488 6.41666667,1.65 C6.41666667,1.7512 6.33453333,1.83333333 6.23333333,1.83333333 Z M6.6,2.38333333 C6.4988,2.38333333 6.41666667,2.3012 6.41666667,2.2 C6.41666667,2.0988 6.4988,2.01666667 6.6,2.01666667 C6.7012,2.01666667 6.78333333,2.0988 6.78333333,2.2 C6.78333333,2.3012 6.7012,2.38333333 6.6,2.38333333 Z M6.96666667,1.83333333 C6.86546667,1.83333333 6.78333333,1.7512 6.78333333,1.65 C6.78333333,1.5488 6.86546667,1.46666667 6.96666667,1.46666667 C7.06786667,1.46666667 7.15,1.5488 7.15,1.65 C7.15,1.7512 7.06786667,1.83333333 6.96666667,1.83333333 Z M7.33333333,2.38333333 C7.23213333,2.38333333 7.15,2.3012 7.15,2.2 C7.15,2.0988 7.23213333,2.01666667 7.33333333,2.01666667 C7.43453333,2.01666667 7.51666667,2.0988 7.51666667,2.2 C7.51666667,2.3012 7.43453333,2.38333333 7.33333333,2.38333333 Z M7.7,1.83333333 C7.5988,1.83333333 7.51666667,1.7512 7.51666667,1.65 C7.51666667,1.5488 7.5988,1.46666667 7.7,1.46666667 C7.8012,1.46666667 7.88333333,1.5488 7.88333333,1.65 C7.88333333,1.7512 7.8012,1.83333333 7.7,1.83333333 Z M8.06666667,2.38333333 C7.96546667,2.38333333 7.88333333,2.3012 7.88333333,2.2 C7.88333333,2.0988 7.96546667,2.01666667 8.06666667,2.01666667 C8.16786667,2.01666667 8.25,2.0988 8.25,2.2 C8.25,2.3012 8.16786667,2.38333333 8.06666667,2.38333333 Z M8.43333333,1.83333333 C8.33213333,1.83333333 8.25,1.7512 8.25,1.65 C8.25,1.5488 8.33213333,1.46666667 8.43333333,1.46666667 C8.53453333,1.46666667 8.61666667,1.5488 8.61666667,1.65 C8.61666667,1.7512 8.53453333,1.83333333 8.43333333,1.83333333 Z M8.8,2.38333333 C8.6988,2.38333333 8.61666667,2.3012 8.61666667,2.2 C8.61666667,2.0988 8.6988,2.01666667 8.8,2.01666667 C8.9012,2.01666667 8.98333333,2.0988 8.98333333,2.2 C8.98333333,2.3012 8.9012,2.38333333 8.8,2.38333333 Z M9.16666667,1.83333333 C9.06546667,1.83333333 8.98333333,1.7512 8.98333333,1.65 C8.98333333,1.5488 9.06546667,1.46666667 9.16666667,1.46666667 C9.26786667,1.46666667 9.35,1.5488 9.35,1.65 C9.35,1.7512 9.26786667,1.83333333 9.16666667,1.83333333 Z M9.53333333,2.38333333 C9.43213333,2.38333333 9.35,2.3012 9.35,2.2 C9.35,2.0988 9.43213333,2.01666667 9.53333333,2.01666667 C9.63453333,2.01666667 9.71666667,2.0988 9.71666667,2.2 C9.71666667,2.3012 9.63453333,2.38333333 9.53333333,2.38333333 Z" id="Shape"></path> + <path d="M5.68333333,8.61666667 C5.68333333,8.15613333 5.79296667,7.72163333 5.98308333,7.33333333 L0.153083333,7.33333333 C0.0575666667,7.469 0,7.63308333 0,7.81146667 L0,9.97168333 C0,10.4377167 0.37895,10.8166667 0.8448,10.8166667 L6.68286667,10.8166667 C6.07163333,10.2785833 5.68333333,9.493 5.68333333,8.61666667 Z M1.925,9.71666667 C1.47015,9.71666667 1.1,9.34651667 1.1,8.89166667 C1.1,8.43681667 1.47015,8.06666667 1.925,8.06666667 C2.37985,8.06666667 2.75,8.43681667 2.75,8.89166667 C2.75,9.34651667 2.37985,9.71666667 1.925,9.71666667 Z" id="Shape"></path> + <path d="M0.153083333,3.85 C0.0575666667,3.98566667 0,4.14975 0,4.32813333 L0,6.48835 C0,6.66691667 0.0575666667,6.831 0.153083333,6.96666667 L6.19318333,6.96666667 C6.72191667,6.19263333 7.61071667,5.68333333 8.61648333,5.68333333 C9.5557,5.68333333 10.39115,6.12883333 10.9283167,6.8178 C10.9728667,6.7166 10.9998167,6.60623333 10.9998167,6.48853333 L10.9998167,4.32813333 C10.9998167,4.14956667 10.94225,3.98566667 10.8467333,3.85 L0.153083333,3.85 Z M1.925,6.23333333 C1.47015,6.23333333 1.1,5.86318333 1.1,5.40833333 C1.1,4.95348333 1.47015,4.58333333 1.925,4.58333333 C2.37985,4.58333333 2.75,4.95348333 2.75,5.40833333 C2.75,5.86318333 2.37985,6.23333333 1.925,6.23333333 Z M6.23333333,5.31666667 C6.13213333,5.31666667 6.05,5.23453333 6.05,5.13333333 C6.05,5.03213333 6.13213333,4.95 6.23333333,4.95 C6.33453333,4.95 6.41666667,5.03213333 6.41666667,5.13333333 C6.41666667,5.23453333 6.33453333,5.31666667 6.23333333,5.31666667 Z M6.96666667,5.31666667 C6.86546667,5.31666667 6.78333333,5.23453333 6.78333333,5.13333333 C6.78333333,5.03213333 6.86546667,4.95 6.96666667,4.95 C7.06786667,4.95 7.15,5.03213333 7.15,5.13333333 C7.15,5.23453333 7.06786667,5.31666667 6.96666667,5.31666667 Z M7.7,5.31666667 C7.5988,5.31666667 7.51666667,5.23453333 7.51666667,5.13333333 C7.51666667,5.03213333 7.5988,4.95 7.7,4.95 C7.8012,4.95 7.88333333,5.03213333 7.88333333,5.13333333 C7.88333333,5.23453333 7.8012,5.31666667 7.7,5.31666667 Z M8.43333333,5.31666667 C8.33213333,5.31666667 8.25,5.23453333 8.25,5.13333333 C8.25,5.03213333 8.33213333,4.95 8.43333333,4.95 C8.53453333,4.95 8.61666667,5.03213333 8.61666667,5.13333333 C8.61666667,5.23453333 8.53453333,5.31666667 8.43333333,5.31666667 Z M9.16666667,5.31666667 C9.06546667,5.31666667 8.98333333,5.23453333 8.98333333,5.13333333 C8.98333333,5.03213333 9.06546667,4.95 9.16666667,4.95 C9.26786667,4.95 9.35,5.03213333 9.35,5.13333333 C9.35,5.23453333 9.26786667,5.31666667 9.16666667,5.31666667 Z" id="Shape"></path> + </g> + </g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-discard-sm.svg b/cds-ui/designer-client/src/assets/img/icon-discard-sm.svg new file mode 100644 index 000000000..96ca98bb1 --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-discard-sm.svg @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="26px" height="18px" viewBox="0 0 26 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>Path</title> + <desc>Created with Sketch.</desc> + <defs> + <filter x="-16.0%" y="-3.0%" width="132.0%" height="106.0%" filterUnits="objectBoundingBox" id="filter-1"> + <feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> + <feGaussianBlur stdDeviation="3" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> + <feColorMatrix values="0 0 0 0 0.184313725 0 0 0 0 0.325490196 0 0 0 0 0.592156863 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> + <feMerge> + <feMergeNode in="shadowMatrixOuter1"></feMergeNode> + <feMergeNode in="SourceGraphic"></feMergeNode> + </feMerge> + </filter> + </defs> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Sliding-actions---Package---Active" transform="translate(-37.000000, -120.000000)" fill="#C3CDDB" fill-rule="nonzero"> + <g id="sliding-actions" filter="url(#filter-1)"> + <g id="discard" transform="translate(30.000000, 106.000000)"> + <g id="btn"> + <path d="M20.1847507,17.6842513 C18.3748671,17.6842513 16.7258065,18.3582386 15.4633431,19.4633431 L13,17 L13,23.1583578 L19.1583578,23.1583578 L16.6847507,20.6847507 C17.6324643,19.8875962 18.8470079,19.3949276 20.1847507,19.3949276 C22.6104701,19.3949276 24.663256,20.9721408 25.3817311,23.1583578 L27,22.6246334 C26.0591505,19.7575651 23.3665689,17.6842513 20.1847507,17.6842513 Z" id="Path"></path> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-download-sm.svg b/cds-ui/designer-client/src/assets/img/icon-download-sm.svg new file mode 100644 index 000000000..11d74860c --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-download-sm.svg @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>download</title> + <desc>Created with Sketch.</desc> + <defs> + <filter x="-16.0%" y="-3.0%" width="132.0%" height="106.0%" filterUnits="objectBoundingBox" id="filter-1"> + <feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> + <feGaussianBlur stdDeviation="3" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> + <feColorMatrix values="0 0 0 0 0.184313725 0 0 0 0 0.325490196 0 0 0 0 0.592156863 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> + <feMerge> + <feMergeNode in="shadowMatrixOuter1"></feMergeNode> + <feMergeNode in="SourceGraphic"></feMergeNode> + </feMerge> + </filter> + </defs> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Sliding-actions---Package---Active" transform="translate(-31.000000, -390.000000)"> + <g id="sliding-actions" filter="url(#filter-1)"> + <g id="download" transform="translate(25.000000, 389.000000)"> + <g id="btn" transform="translate(5.000000, 0.000000)"> + <g id="download" transform="translate(13.000000, 13.000000)"></g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-file-code.svg b/cds-ui/designer-client/src/assets/img/icon-file-code.svg new file mode 100644 index 000000000..58030f02f --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-file-code.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="12px" height="16px" viewBox="0 0 12 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>file-code</title> + <desc>Created with Sketch.</desc> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="3.3.1-Template-&-Mapping---Upload" transform="translate(-430.000000, -630.000000)" fill="#1273EB" fill-rule="nonzero"> + <g id="modal-new" transform="translate(380.000000, 254.000000)"> + <g id="file" transform="translate(30.000000, 354.000000)"> + <g id="content" transform="translate(20.000000, 22.000000)"> + <g id="file-code"> + <path d="M8,0 L0,0 L0,16 L12,16 L12,4 L8,0 Z M7,5 L11,5 L11,15 L1,15 L1,1 L7,1 L7,5 Z M8,4 L8,1 L11,4 L8,4 Z" id="Shape"></path> + <polygon id="Path" points="4.2 13 3.5 13 1.5 10.5 3.5 8 4.2 8 2.2 10.5"></polygon> + <polygon id="Path" points="7.8 13 8.5 13 10.5 10.5 8.5 8 7.8 8 9.8 10.5"></polygon> + <polygon id="Path" points="4.7 14 5.3 14 7.4 7 6.6 7"></polygon> + </g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-remove-file.svg b/cds-ui/designer-client/src/assets/img/icon-remove-file.svg new file mode 100644 index 000000000..94da3e0ec --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-remove-file.svg @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>remove</title> + <desc>Created with Sketch.</desc> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="3.3.1-Template-&-Mapping---Upload" transform="translate(-990.000000, -630.000000)" fill="#1B3E6F" fill-rule="nonzero"> + <g id="modal-new" transform="translate(380.000000, 254.000000)"> + <g id="file" transform="translate(30.000000, 354.000000)"> + <g id="content" transform="translate(20.000000, 22.000000)"> + <path d="M575.359928,2.63185096 C571.850966,-0.877110575 566.141159,-0.877456729 562.631851,2.63185096 C559.122543,6.14115866 559.122889,11.8506202 562.631851,15.3599279 C566.140813,18.8692356 571.85062,18.8692356 575.359928,15.3599279 C578.868889,11.8506202 578.868889,6.1408125 575.359928,2.63185096 Z M572.545005,12.5450048 C572.274659,12.815351 571.836428,12.815351 571.566082,12.5450048 L568.995889,9.9748125 L566.303505,12.6671971 C566.033159,12.9375433 565.594928,12.9375433 565.324582,12.6671971 C565.054236,12.396851 565.054236,11.9586202 565.324582,11.688274 L568.016966,8.99588942 L565.446774,6.42569712 C565.176428,6.15535096 565.176428,5.71677404 565.446774,5.44677404 C565.71712,5.17642789 566.155351,5.17642789 566.425697,5.44677404 L568.995889,8.01696635 L571.443543,5.5693125 C571.713889,5.29896635 572.15212,5.29896635 572.422466,5.5693125 C572.692813,5.83965866 572.692813,6.27788942 572.422466,6.54823558 L569.974813,8.99588942 L572.545005,11.5660817 C572.815351,11.8364279 572.815351,12.2746587 572.545005,12.5450048 Z" id="remove"></path> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-required-no.svg b/cds-ui/designer-client/src/assets/img/icon-required-no.svg new file mode 100644 index 000000000..6cbaa5bf4 --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-required-no.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>no</title> + <desc>Created with Sketch.</desc> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Table-Mapping-2" transform="translate(-83.000000, -244.000000)" fill="#C4CEDB" fill-rule="nonzero"> + <g id="table"> + <g id="body" transform="translate(0.000000, 19.000000)"> + <g id="columns" transform="translate(26.000000, 0.000000)"> + <g id="Required" transform="translate(35.000000, 0.000000)"> + <g id="no" transform="translate(22.000000, 225.000000)"> + <path d="M8.7350625,17.4706875 C3.918375,17.4706875 0,13.55175 0,8.7350625 C0,3.918375 3.918375,0 8.7350625,0 C13.55175,0 17.470125,3.918375 17.470125,8.7350625 C17.4706875,13.55175 13.55175,17.4706875 8.7350625,17.4706875 Z M8.7350625,0.997875 C4.4685,0.997875 0.997875,4.4690625 0.997875,8.7350625 C0.997875,13.0010625 4.4685,16.4716875 8.7350625,16.4716875 C13.0010625,16.4716875 16.4716875,13.0010625 16.4716875,8.7350625 C16.4716875,4.4690625 13.0010625,0.997875 8.7350625,0.997875 Z" id="Shape"></path> + <path d="M12.17925,9.234 L5.290875,9.234 C5.01525,9.234 4.791375,9.01125 4.791375,8.7350625 C4.791375,8.4594375 5.0146875,8.2355625 5.290875,8.2355625 L12.17925,8.2355625 C12.454875,8.2355625 12.6781875,8.4594375 12.6781875,8.7350625 C12.6781875,9.01125 12.4554375,9.234 12.17925,9.234 Z" id="Path"></path> + </g> + </g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-required-yes.svg b/cds-ui/designer-client/src/assets/img/icon-required-yes.svg new file mode 100644 index 000000000..8adbeed61 --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-required-yes.svg @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>yes</title> + <desc>Created with Sketch.</desc> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Table-Mapping-2" transform="translate(-83.000000, -76.000000)" fill="#66BB00" fill-rule="nonzero"> + <g id="table"> + <g id="body" transform="translate(0.000000, 19.000000)"> + <g id="columns" transform="translate(26.000000, 0.000000)"> + <g id="Required" transform="translate(35.000000, 0.000000)"> + <path d="M37.3639492,59.6360156 C35.6640742,57.9361758 33.4039844,57 31,57 C28.5959805,57 26.3358906,57.9361758 24.6360156,59.6360156 C22.9361758,61.3358906 22,63.5960156 22,66 C22,68.4039844 22.9361758,70.6640742 24.6360156,72.3639492 C26.3358906,74.0638242 28.5960156,75 31,75 C33.4039844,75 35.6640742,74.0638242 37.3639492,72.3639844 C39.0638242,70.6640742 40,68.4039844 40,66 C40,63.5960156 39.0638242,61.3359258 37.3639492,59.6360156 Z M35.2998203,63.8580352 L30.2701914,68.8876992 C30.1672187,68.9906719 30.0322539,69.0421406 29.8973242,69.0421406 C29.7623594,69.0421406 29.6273945,68.9906719 29.5244219,68.8876992 L26.7001797,66.0634922 C26.4942344,65.857582 26.4942344,65.5237031 26.7001797,65.3177227 C26.9060898,65.1117773 27.2400039,65.1117773 27.4459492,65.3177227 L29.8973242,67.7690625 L34.5540508,63.1122656 C34.7599609,62.9063203 35.093875,62.9063203 35.2998203,63.1122656 C35.5057656,63.3182109 35.5057656,63.6520898 35.2998203,63.8580352 Z" id="yes"></path> + </g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/assets/img/icon-save-sm.svg b/cds-ui/designer-client/src/assets/img/icon-save-sm.svg new file mode 100644 index 000000000..b508f5efc --- /dev/null +++ b/cds-ui/designer-client/src/assets/img/icon-save-sm.svg @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="26px" height="23px" viewBox="0 0 26 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> + <title>Path</title> + <desc>Created with Sketch.</desc> + <defs> + <filter x="-16.0%" y="-3.0%" width="132.0%" height="106.0%" filterUnits="objectBoundingBox" id="filter-1"> + <feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> + <feGaussianBlur stdDeviation="3" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> + <feColorMatrix values="0 0 0 0 0.184313725 0 0 0 0 0.325490196 0 0 0 0 0.592156863 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> + <feMerge> + <feMergeNode in="shadowMatrixOuter1"></feMergeNode> + <feMergeNode in="SourceGraphic"></feMergeNode> + </feMerge> + </filter> + </defs> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Sliding-actions---Package---Active" transform="translate(-37.000000, -36.000000)" fill="#FFFFFF" fill-rule="nonzero"> + <g id="sliding-actions" filter="url(#filter-1)"> + <g id="save" transform="translate(30.000000, 25.000000)"> + <g id="btn"> + <g id="check" transform="translate(13.000000, 15.000000)"> + <path d="M5.36086387,10.6613874 C5.22722513,10.7958115 5.0448953,10.8708115 4.85549738,10.8708115 C4.66609947,10.8708115 4.48376963,10.7958115 4.3501309,10.6613874 L0.314136126,6.62473821 C-0.104712042,6.20589004 -0.104712042,5.52670157 0.314136126,5.10863876 L0.819502609,4.60314136 C1.23848169,4.18429319 1.91688481,4.18429319 2.33573298,4.60314136 L4.85549738,7.12303665 L11.664267,0.314136126 C12.0832461,-0.104712042 12.7623037,-0.104712042 13.1804974,0.314136126 L13.6858639,0.819633525 C14.104712,1.23848169 14.104712,1.91753925 13.6858639,2.33573298 L5.36086387,10.6613874 Z" id="Path"></path> + </g> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/styles.css b/cds-ui/designer-client/src/styles.css index 36cb20804..3c0a049bf 100644 --- a/cds-ui/designer-client/src/styles.css +++ b/cds-ui/designer-client/src/styles.css @@ -14,15 +14,43 @@ body{ *:focus{ outline: none; } +:hover{ + transition: 0.3s !important; +} /*Bootstrap*/ .custom-control-label::before{ - border: solid 1px #1B3E6F !important; + border: solid 1px #C3CDDB !important; border-radius: 0 !important; } .custom-control-input:checked ~ .custom-control-label::before{ background: #1B3E6F !important; } - +.custom-radio .custom-control-label::before{ + border-radius: 50% !important; +} +.custom-control-label{ + font-size: 13px; + line-height: 24px; +} +.form-check-input + span{ + display: inline-flex !important; +} +.form-check-input + span i{ + margin-right: 9px !important; +} +.form-control:focus{ + background-color: #F4F9FE !important; +} +.label-input input[type="radio"]{ + width: 14px !important; + height: 14px; +} +/*ICONS*/ +.icon-menuDots{ + font-size: 3px !important; + color: #1B3E6F; + vertical-align: middle; +} /*Components*/ /* Menu Styles */ .primary-nav{ @@ -178,7 +206,7 @@ input#menu[type="checkbox"]{ } .overflow-container{ position: relative; - height: calc(100vh - 60px)!important; + height: calc(100vh - 50px)!important; overflow-y: auto; border-top: 60px solid #fff; z-index: -1; @@ -252,11 +280,14 @@ background-color: #333; } .import-container-all{ width: 100%; + padding-bottom: 20px; } .import-container{ width: 100%; - background: #E0E8F2; - padding:25px ; + background: #E7F1FC; + margin-bottom: 20px; + padding: 9px 18px; + border: solid 1px #EEF4F9; } .import-container-input{ width: 40%; @@ -266,18 +297,26 @@ background-color: #333; } .import-container-input input{ width: 100%; - height: 40px; - padding: 5px 20px; + height: 36px; + padding: 5px 40px 5px 12px; border: 0px; + border-radius: 2px; -webkit-box-shadow: 0px 0px 42px -27px rgba(0,0,0,0.75); --moz-box-shadow: 0px 0px 42px -27px rgba(0,0,0,0.75); -box-shadow: 0px 0px 42px -27px rgba(0,0,0,0.75); -font-size: 13px; + -moz-box-shadow: 0px 0px 42px -27px rgba(0,0,0,0.75); + box-shadow: 0px 0px 42px -27px rgba(0,0,0,0.75); + font-size: 13px; + color: #172B4D; +} +.import-container-input input:focus{ + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.18); +} +.import-container-input input::placeholder{ + color: #959DA8 !important; } .enter-link{ position: absolute; - right: 18px; - font-size: 23px; + right: 12px; + font-size: 20px; top: 6px; color: #1273EB; } @@ -290,6 +329,19 @@ font-size: 13px; .import-container-span{ font-size: 12px; } +.import-container-all .accordion .card-header{ + background: #fff !important; + border-bottom: 0 !important; +} +.import-container-all .collapse.show{ + border-top: solid 1px #ECEDF2; +} +.import-container-all .card-header .accordion-delete{ + display: none; +} +.import-container-all .card-header:hover .accordion-delete{ + display: inline; +} .accordion-delete{ color: #FF6469; font-size: 18px; @@ -323,6 +375,18 @@ height: 40px; font-size: 14px !important; text-indent: 6px !important; } +.packagesFilter .reset-filter{ + margin-top: 6px; + padding-top: 6px; + padding-left: 9px; + border-top: solid 1px #ECEDF2; + font-size: 13px; +} +.packagesFilter .reset-filter a:hover{ + background: none !important; + text-decoration: none; + color: #1B3E6F; +} /**Packages Sort**/ .sort-packages{ font-size: 12px; @@ -339,10 +403,13 @@ height: 40px; color: #1B3E6F; } .sort-packages .dropdown-text::after{ - border-color: #1B3E6F transparent transparent transparent; + right: 18px !important; + border: solid !important; + border-color: #1B3E6F transparent transparent transparent !important; } .sort-packages .dropdown-toggle:focus ~ .dropdown-text::after{ - border-color: transparent transparent #1B3E6F transparent; + top: 12px !important; + border-color: transparent transparent #1B3E6F transparent !important; } .sort-packages .dropdown-toggle:hover ~ .dropdown-text, .sort-packages .dropdown-toggle:focus ~ .dropdown-text{ @@ -366,25 +433,36 @@ height: 40px; font-size: 12px; } .sort-packages .dropdown-content a:hover{ + color: #1B3E6F; background-color: #F4F9FE; text-decoration: unset; + cursor: pointer; } /**Pagination**/ +.page-item{ + margin: 3px 2px 0; +} .page-item .page-link, .page-item.disabled .page-link{ + padding: 5px 9px; background: transparent !important; border: 0; color: #1B3E6F !important; - font-size: 14px; + font-size: 13px; + font-weight: bold; } +.page-item.active .page-link, .page-link:hover{ - color: #fff !important; - background-color: #C3CDDB !important; - border-radius: 100%; + color: #1B3E6F !important; + background-color: #fff !important; + border-radius: 100% !important; + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.1); + outline: 0; } /**Packages Cards***/ /***Package Info Card***/ .packages-card .card{ + width: 100%; margin: 0; border-radius: 2px; border: 0; @@ -392,48 +470,82 @@ height: 40px; } .packages-card .card-title{ margin-bottom: 0 !important; - font-size: 15px; + font-size: 13px; font-weight: bold; + color: #1B3E6F; +} +.packages-card .card-title span{ + color: #1B3E6F; + font-size: 11px; + vertical-align: bottom; } .packages-card p{ - font-size: 14px; + font-size: 12px; color: #D0D7E4; } +.packages-card p.package-desc{ + font-size: 13px; + text-align: left; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; +} +.packages-card p.package-desc:hover{ + color: #1B3E6F !important; + text-decoration: underline; +} + +.packages-card [data-tooltip]::before, +.packages-card .tooltip::before{ + border: 0 !important; +} +.packages-card .tooltip:after, +.packages-card [data-tooltip]:after { + padding: 9px; + font-size: 11px; + background: #F4F9FE; + border: solid 1px #E6EDF5; + box-shadow: 0 0 12 rgba(0,0,0,0.8); + border-radius: 3px; +} /***Add Package Card***/ .addPaackage-card{ padding: 10px 0; background: #F4F9FE !important; border: solid 1px #D7E7F9 !important; -} -.addPaackage-card img{ - margin-bottom: 12px; - margin-top: 8px; + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.18) !important; } .addPaackage-card a{ - margin-bottom: 20px; - padding: 10px 10px 10px 32px; + margin: 0; + padding: 8px 15px; font-weight: bold; - font-size: 10px; + font-size: 12px; border-radius: 2px; - border-width: .5px; + border-width: 0px; border-style: solid; - background-position: 10px center; + background-position: 15px center; background-repeat: no-repeat; + text-align: left; } .addPaackage-card a:hover{ text-decoration: unset; } +.btn-create-package i, +.btn-import-package i{ + margin-right: 9px; + font-size: 14px; + vertical-align: middle; +} .btn-create-package, .btn-create-package:hover{ background-color: #1B3E6F; - border-color: #1B3E6F; color: #fff; - background-image: url(../src/assets/img/icon-create-white.svg); } .btn-import-package, .btn-import-package:hover{ + background: #C3CDDB; color: #1B3E6F; - background-image: url(../src/assets/img/icon-import-blue.svg); } /***Actions Menu***/ .packages-card .dropdown{ @@ -450,6 +562,9 @@ height: 40px; border-bottom-right-radius: 0; opacity: .6; } +.packages-card .dropdown-text:hover{ + opacity: 1; +} .packages-card .dropdown-text::after{ display: none; } @@ -460,7 +575,6 @@ height: 40px; right: 0; width: 120px; padding: 6px 0; - border: 0; border-radius: 50%; } @@ -484,6 +598,7 @@ height: 40px; .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover{ border: 0 !important; + transition: 0.3s; } .nav-tabs .nav-link:hover{ color: #1B3E6F !important; @@ -508,6 +623,11 @@ height: 40px; .nav-tabs .nav-link:first-child{ padding-left: 20px !important; } +.nav-item.nav-link.complete, +.nav-item.active.complete{ + padding: 15px 20px 15px 44px !important; + background: url(/assets/img/icon-required-yes.svg) 20px center no-repeat !important; +} /**Sliding Search Input**/ .searchBox{ position: absolute; @@ -518,13 +638,13 @@ height: 40px; } .searchButton{ float: right; - margin-top: 14px; + margin-top: 18px; padding-left: 0 !important; padding-right: 24px !important; width: 60px; - height: 24px; + height: 20px; background: url(../src/assets/img/icon-search.svg) center center no-repeat; - background-size: 28%; + background-size: 24%; border: 0 !important; border-right: solid 1px #1B3E6F !important; display: flex; @@ -536,6 +656,9 @@ height: 40px; width: 240px; border-bottom: solid 1px #C3CDDB; } +.searchBox > .searchInput:focus{ + border-bottom: solid 1px #1B3E6F !important; +} .searchBox:hover > .searchButton{ color: #1B3E6F; } @@ -546,9 +669,9 @@ height: 40px; float: left; padding: 0; color: #1B3E6F; - font-size: 14px; + font-size: 12px; transition: 0.4s; - line-height: 40px; + line-height: 49px; width: 0px; } .searchInput::placeholder{ @@ -622,7 +745,7 @@ height: 40px; list-style-type: none; border-radius: 3px; text-indent: 10px; - line-height: 32px; + line-height: 28px; background-color: #eee; border: 1px solid #ccc; } @@ -730,7 +853,7 @@ height: 40px; } /*Page Title*/ .page-title{ - padding: 15px 30px 14px; + padding: 20px 30px; background:#fff; border-left: solid 1px #FAFAFA; margin-bottom: 21px; @@ -738,22 +861,24 @@ height: 40px; box-shadow: 0 4px 10px 0 #eef0f5; position: relative; z-index: 8; - position: fixed; - width: calc(100% - 50px); + /* position: fixed; + width: calc(100% - 50px); */ } .page-title h2{ font-size: 16px; font-weight: bold; - padding-top: 3px; - padding-bottom: 2px; + padding-top: 1px; } .page-title h2 span{ - color: #BABBC3; + color: #C3CDDB; font-size: 14px; } /*Content*/ .body-container{ - padding: 90px 30px 0 !important; + padding: 0 30px !important; +} +.body-container > .container{ + padding: 0; } .search-filter-col{ padding-right: 0 !important; @@ -763,6 +888,7 @@ height: 40px; .packagesFilter{ margin-top: 12px; margin-bottom: 7px; + z-index: 220 !important; } .packagesFilter .dropdown-toggle{ height: 36px !important; @@ -780,7 +906,9 @@ height: 40px; } .packagesFilter .dropdown-text::after{ right: 12px; - border-color: #1B3E6F transparent transparent transparent; + border: solid !important; + border-width: 5px 4px 0 4px !important; + border-color: #1B3E6F transparent transparent transparent !important; } .packagesFilter .dropdown-toggle:hover ~ .dropdown-text, .packagesFilter .dropdown-toggle:focus ~ .dropdown-text{ @@ -796,7 +924,7 @@ height: 40px; top: 12px; } .packagesFilter .dropdown-content{ - padding: 6px 0 15px; + padding: 6px 0; background: #fff; box-shadow: 0 2px 6px 0 rgba(47, 83, 151, .15); border: 0; @@ -805,6 +933,9 @@ height: 40px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; } +.packagesFilter .dropdown-content li:hover .custom-checkbox{ + cursor: pointer; +} .packagesFilter .dropdown-content:hover, .packagesFilter .dropdown-toggle:focus ~ .dropdown-content{ top: 30px; @@ -829,6 +960,9 @@ height: 40px; .packagesFilter .custom-checkbox{ margin-left: 8px; } +.packagesFilter .custom-control-input{ + left: 10px; +} .packagesFilter .custom-control-label{ line-height: 28px !important; font-size: 13px !important; @@ -889,9 +1023,14 @@ height: 40px; font-size: 14px; } .page-link:hover{ - color: #fff !important; - background-color: #C3CDDB !important; + color: #1B3E6F !important; + background-color: #fff !important; border-radius: 100%; + transition: 0.3s; + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.12); +} +.page-item.disabled{ + opacity: .3; } /**Packages Cards***/ /***Package Info Card***/ @@ -899,31 +1038,46 @@ height: 40px; margin: 0; border-radius: 2px; border: 0; - box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.1); + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.12); } .packages-card .card:hover{ - box-shadow: 0 2px 13px 6px rgba(47, 83, 151, .15); + box-shadow: 0 2px 13px 6px rgba(47, 83, 151, .17); transition: all 0.5s ease; + cursor: pointer; +} +.packages-card .card:hover .card-title, +.packages-card .card:hover .card-title span{ + color: #1273EB !important; } .packages-card .card-title{ margin-bottom: 0 !important; - font-size: 15px; + font-size: 14px; font-weight: bold; } -.packages-card p{ - font-size: 14px; - color: #D0D7E4; +.packages-card .card-title .packageName{ + margin-bottom: 0; + display: inline-block; + width: auto; + max-width: 76%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 13px; + vertical-align: bottom; + color: #1B3E6F; +} +.packages-card .card-title:hover, +.packages-card .card-title:hover .packageName{ + text-decoration: none; + color: #1273EB; } .packages-card .card-body{ padding-bottom: 0 !important; } .packages-card .card-footer .col{ - padding: 0; - text-align: center; -} -.packages-card .card-footer .col:last-child{ - padding-left: 20px; + text-align: left; } + /***Add Package Card***/ .addPaackage-card{ background: #F4F9FE !important; @@ -932,22 +1086,7 @@ height: 40px; .addPaackage-card:hover{ box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.1) !important; } -.addPaackage-card img{ - margin-bottom: 33px; - margin-top: 8px; -} -.addPaackage-card a{ - margin: 0 0 14px; - padding: 10px 20px 10px 42px; - font-weight: bold; - font-size: 13px; - border-radius: 2px; - border-width: 0px; - border-style: solid; - background-position: 20px center; - background-repeat: no-repeat; - text-align: left; -} + .addPaackage-card a:hover{ text-decoration: unset; } @@ -959,19 +1098,18 @@ height: 40px; text-align: left; } .btn-create-package, +.btn-import-package{ + margin-bottom: 9px !important; +} +.btn-create-package, .btn-create-package:hover{ background-color: #1B3E6F; border-color: #1B3E6F; color: #fff; - background-image: url(../src/assets/img/icon-create-white.svg); - background-repeat: no-repeat; } .btn-import-package, .btn-import-package:hover{ color: #1B3E6F; - background-image: url(../src/assets/img/icon-import-blue.svg); - background-size: 16px; - background-color: #C3CDDB; } /***Actions Menu***/ .packages-card .dropdown{ @@ -1000,48 +1138,53 @@ height: 40px; padding: 6px 0; border: 0; text-indent: 0; - border-radius: 2px; - border-top-left-radius: 0; + border-radius: 4px; border-top-right-radius: 0; background: #1B3E6F; } .packages-card .dropdown-content a{ - padding-left: 45px; + padding-left: 12px; color: #fff; - font-size: 13px; - background-position: 20px center; + font-size: 12px; + /* background-position: 14px center; background-size: 10%; - background-repeat: no-repeat; + background-repeat: no-repeat; */ +} +.packages-card .dropdown-content a i{ + margin-right: 4px; } .packages-card .dropdown-content a:hover{ background-color: #172B4D; text-decoration: unset; } -.packages-card .action-clone a, -.packages-card .action-clone a:hover{ - background-image: url(../src/assets/img/icon-clone-sm.svg); -} -.packages-card .action-archive a, -.packages-card .action-archive a:hover{ - background-image: url(../src/assets/img/icon-archive-sm.svg); -} -.packages-card .action-delete a, -.packages-card .action-delete a:hover{ - background-image: url(../src/assets/img/icon-delete-sm.svg); -} .packages-card .dropdown-content:hover, .packages-card .dropdown-toggle:focus ~ .dropdown-content{ - top: 24px; + top: 22px; +} +.packages-card .dropdown-toggle:focus ~ .dropdown-text .icon-menuDots{ + color: #D0D7E4; } .packages-card .dropdown-toggle:hover ~ .dropdown-text{ background: transparent; opacity: 1; } .packages-card .dropdown-toggle:focus ~ .dropdown-text{ + width: 27px; + text-align: center; opacity: 1; background: #1B3E6F; box-shadow: none; } +.package-version{ + color: #C3CDDB !important; +} +.package-version::before{ + content: "|"; + margin-left: 8px; + margin-right: 6px; + vertical-align: text-bottom; +} + /***Contributers***/ ul.package-contributers{ /*margin-bottom: 0 !important;*/ @@ -1062,6 +1205,7 @@ ul.package-contributers{ } .package-modifier, .package-contributers button{ + height: 20px !important; padding: 0 !important; border-radius: 100%; border: 0 !important; @@ -1105,8 +1249,8 @@ ul.package-contributers{ } .package-modifier img, .package-contributers button img{ - width: 28px; - height: 28px; + width: 20px; + height: 20px; object-fit: cover; vertical-align: top; border-radius: 100%; @@ -1120,42 +1264,43 @@ ul.package-contributers{ } /***Package Footer***/ .packages-card .card-footer{ - padding: 0 20px !important; + padding: 0 !important; background: transparent !important; border-top-color: #F7F6F6 !important; } +.packages-card .card-footer .col{ + text-align: center; +} .packages-card .card-footer .col:first-child{ border-right: solid 1px #F7F6F6; } .packages-card .card-footer .btn{ + padding: 10px 0 10px 0 !important; background-color: transparent !important; - color: #C3CDDB !important; + color: #1B3E6F !important; border: 0; font-size: 13px; - opacity: .7; + text-align: left; + opacity: .4; } .packages-card .card-footer .btn:hover{ opacity: 1; } -.btn-card-config, -.btn-card-topology{ - padding: 15px 0 15px 28px !important; - background-size: 16%; - background-position: left center; - background-repeat: no-repeat; -} -.btn-card-config{ - background-image: url(../src/assets/img/icon-btn-card-config.svg); +.packages-card .card-footer i{ + margin-right: 6px; } -.btn-card-topology{ - background-image: url(../src/assets/img/icon-btn-card-topology.svg); -} -.icon-deployed{ - margin-right: 5px; +.icon-deployed-active, +.icon-deploy-inactive{ + margin-right: 9px; display: inline; - background: url(../src/assets/img/icon-deploy.svg) center center no-repeat; + background-image: url(/assets/img/icon-deploy-active.svg); + background-position: center center; + background-repeat: no-repeat; + vertical-align: baseline; +} +.icon-deploy-inactive{ + background-image: url(/assets/img/icon-deploy-inactive.svg); } - @@ -1204,7 +1349,6 @@ ul.package-contributers{ width: 4em; line-height: 4em; } - .title-action:before{ -webkit-transition: all 0.2s ease; -moz-transition: all 0.2s ease; @@ -1456,6 +1600,32 @@ ul.package-contributers{ margin-left: 0; margin-bottom: -16px; } + +/*TooltipModule - Shady*/ +.tooltip:before, +.tooltip:after{ + width: 100% !important; +} +.tooltip .tooltip-inner{ + max-width: 280px !important; + width: 100% !important; + text-align: left!important; + color:#1B3E6F; + background-color: #F4F9FE; + border: solid 1px #E6EDF5; + border-radius: 3px !important; + font-size: 11px; +} +.bs-tooltip-bottom .arrow::before{ + border-bottom-color: #E6EDF5 !important; +}
 +.bs-tooltip-top .arrow::before{ + border-top-color: #E6EDF5 !important; +}
 + + + + .btn{ padding-right: 20px !important; padding-left: 20px !important; @@ -1482,6 +1652,14 @@ padding-left: 20px !important; .package-view-button{ margin-top: 6px; } +.package-view-button .btn{ + padding: 6px 12px; + border-radius: 2px; + font-weight: bold; +} +.package-view-button .btn:hover{ + opacity: .9; +} .package-view-button .btn-primary{ background-color: #1B3E6F !important; border-color: #1B3E6F !important; @@ -1492,7 +1670,6 @@ padding-left: 20px !important; background-color: #fff !important; border-color: #D0DFF1 !important; color: #1B3E6F !important; - margin-left: 10px; } .package-view-title { font-size: 11px; @@ -1510,6 +1687,7 @@ padding-left: 20px !important; } .package-view-button .btn-outline-secondary i{ font-size: 18px; + margin-right: 4px; } .card.creat-card{ margin: 0; @@ -1528,40 +1706,48 @@ padding-left: 20px !important; } .single-line label{ margin-bottom: 0px; - } - .single-line-model label{ - margin-bottom: 0px; - border-bottom: 1px solid #efefef; - padding: 15px 25px; - } - .single-line-model .label-name{ - width: 325px; - } - .single-line-model .label-input{ - width: calc(100% - 325px); - } - - .single-line-model input{ - border-bottom: 1px solid #efefef !important; - padding: 15px 25px 15px 0px; - } - .model-note-container{ - width: calc(100% - 325px); - padding: 0px 25px 0px 0px ; - margin-left: 325px; - } - .error-message{ - font-size:11px ; - } - .tages-container{ - margin-bottom: 25px; - } - .tag-notes{ -font-size: 11px; -color: #C3CDDB; -padding: 5px 25px 5px 0px; -margin-bottom: 5px; - } +} +.single-line-model label{ + margin-bottom: 0px; + border-bottom: 1px solid #FAFAFA; + padding: 15px 25px; +} +.single-line-model .label-name{ + width: 325px; +} +.single-line-model .label-input{ + width: calc(100% - 325px); +} +.single-line-model input{ + border-bottom: 1px solid #FAFAFA !important; + padding: 15px 25px 15px 0px; +} +.customKeyTitle span{ + color: #C3CDDB !important; + font-size: 11px; +} +.single-line-model input:focus, +.single-line-custom-key input:focus{ + border-bottom-color: #1B3E6F !important; +} +.model-note-container{ + width: calc(100% - 325px); + padding: 0px 25px 0px 0px ; + margin-left: 325px; +} +.error-message{ + font-size:11px ; + color: #FF6469; +} +.tages-container{ + margin-bottom: 25px; +} +.tag-notes{ + font-size: 11px; + color: #C3CDDB; + padding: 5px 25px 5px 0px; + margin-bottom: 5px; +} .single-tage{ background: #E0E8F2; font-size: 13px; @@ -1579,7 +1765,7 @@ margin-bottom: 5px; width: 300px; display: inline-block; margin-bottom: 0px; - font-size: 14px; + font-size: 13px; font-weight: bold; } .label-name span{ @@ -1611,7 +1797,7 @@ margin-bottom: 5px; .form-check-input+span{ margin-left: 20px; margin-right: 50px; - font-size: 14px; + font-size: 13px; display: flex; } .form-check-input+span i{ @@ -1619,40 +1805,40 @@ margin-bottom: 5px; margin-left: 5px; } - .label-input input{ - margin-bottom: 0px; - outline: 0px; - border: 0px; - font-size: 14px; - width: 100%; - color: #1B3E6F; - } - .label-input input[type=radio]{ - width: auto; - - } - .label-input input[type=radio]+span{ - font-size: 12px; - display: block; - margin-right: 100px; - } - .single-line select{ - margin-bottom: 0px; - outline: 0px; - border: 0px; - background: none; - background: url(/assets/img/arrow.svg) center right no-repeat; - background-size: 10spx; - width: auto; - -webkit-appearance: none; - -moz-appearance: none; - text-indent: 1px; - text-overflow: ''; - font-size: 14px; - padding-left: 0px; - color: #1B3E6F; - padding-right: 20px; - } +.label-input input{ + margin-bottom: 0px; + outline: 0px; + border: 0px; + font-size: 14px; + width: 100%; + color: #1B3E6F; + transition: all 250ms ease-out; +} +.label-input input[type=radio]{ + width: auto; +} +.label-input input[type=radio]+span{ + font-size: 12px; + display: block; + margin-right: 100px; +} +.single-line select{ + margin-bottom: 0px; + padding-left: 10px; + padding-right: 50px; + outline: 0px; + border: solid 1px #EEF4F9; + background: none; + background: url(/assets/img/arrow.svg) 90% center #F4F9FE no-repeat; + background-size: 10px; + width: auto; + -webkit-appearance: none; + -moz-appearance: none; + text-indent: 0; + text-overflow: ''; + font-size: 13px; + color: #1B3E6F; +} .single-line select:focus{ box-shadow: 0 0 0 0; } @@ -1685,6 +1871,7 @@ margin-bottom: 5px; } .single-custom-key{ width: 100%; + margin-bottom: 21px; } .single-line-custom-key{ width: 45%; @@ -1693,31 +1880,30 @@ margin-bottom: 5px; .single-line-custom-key-delete{ width: 10%; display: inline-block; - border-bottom: 1px solid #efefef; - padding: 12px; + border-bottom: 1px solid #FAFAFA; + padding: 13px 12px 14px; } .single-line-custom-key label{ width: 150px; margin-bottom: 0px; - border-bottom: 1px solid #efefef; + border-bottom: 1px solid #FAFAFA; padding: 15px 25px; } .single-line-custom-key input{ - - border-bottom: 1px solid #efefef !important; - padding: 15px 25px; + border-bottom: 1px solid #FAFAFA !important; + padding: 15px 25px 15px 0; } .single-line-custom-key input::placeholder{ font-size: 14px; color: #C3CDDB; - } - .single-line-custom-key .label-input{ - width: calc(100% - 150px); - } - .single-line-custom-key .label-name span{ - color: #C3CDDB !important; - margin-right: 20px; - } +} +.single-line-custom-key .label-input{ + width: calc(100% - 150px); +} +.single-line-custom-key .label-name span{ + color: #C3CDDB !important; + margin-right: 20px; +} .custom-key-delete{ background: transparent; color: #FF6469; @@ -1728,7 +1914,7 @@ margin-bottom: 5px; outline: 0px; border: 0px; } -hr { +hr{ margin-top: 0rem !important; margin-bottom: 0rem !important; border-top: 1px solid #efefef !important; @@ -1736,16 +1922,17 @@ hr { .creat-action-container{ position: fixed; right: 0px; - top: 160px; + top: 104px; width: 130px; text-align: center; } .action-button{ + margin-bottom: 12px; + padding: 3px 30px; color: #BABBC3; font-size: 10px; font-weight: bold; display: inline-block; - margin-bottom: 12px; } .action-button:hover{ text-decoration: none; @@ -1762,6 +1949,18 @@ hr { font-size: 17px; display: inline-block; } +.action-button i.icon-save-sm{ + background: #1273EB; + color: #fff; + font-size: 11px; +} +.action-button i.icon-discard-sm{ + font-size: 11px; + color: #C3CDDB; +} +.action-button.save{ + color: #1273EB; +} .action-button.delete{ color: #BABBC3; } @@ -1774,11 +1973,70 @@ hr { .mode-icon{ font-size: 20px; } + +/*MODAL*/ +.modal-dialog{ + margin-top: 60px !important; +} +.modal{ + z-index: 11000000 !important; + background: rgba(27, 62, 111, 0.10) !important; +} +.modal-content{ + border-radius: 2px !important; + border: 0 !important; + box-shadow: 0 2px 6px rgba(47, 83, 151, .10);; +} +.modal-title{ + font-size: 14px !important; +} +.modal-body{ + padding: 1.5rem 1.5rem 1rem !important; +} +.modal-body p{ + font-size: 14px; +} +.modal-body p span{ + color: #FF6469; +} +.modal-header{ + border-bottom-color: #ECEDF2 !important; + padding: .7rem 1.5rem !important; +} +.modal-footer{ + border-top: 0 !important; +} +.modal-footer .btn{ + padding: 8px 15px; + font-weight: bold; + font-size: 12px; + border: 0 !important; +} +.modal-footer .btn-primary{ + background-color: #1B3E6F !important; +} +.modal-footer .btn-secondary, +.modal-footer .btn-secondary:hover{ + background-color: transparent; + color: #1273EB; + opacity: .8; +} +.modal-footer .btn-secondary:hover{ + opacity: 1; +} +.modal-footer .btn-secondary:active{ + background-color: #E7F1FC !important; + color: #1B3E6F !important; +} .action-button span{ width: 100%; display: inline-block; margin-top: 5px; } +.creat-action-container hr{ + margin: 0 46px; + padding-bottom: 18px; +} .btn-link:hover, .btn-link:focus{ text-decoration: none !important; } @@ -1805,12 +2063,13 @@ hr { width: 100%; } .ngx-file-drop__drop-zone{ - border: 2px dotted #F4F9FE !important; + border: 1px dashed #D7E7F9 !important; border-radius: 0px !important; height: auto !important; } .folder-upload{ width: 100%; + margin: 15px auto 18px; display: inline-block; text-align: center; } @@ -1818,7 +2077,9 @@ hr { font-size: 12px; } .create-title{ + margin-bottom: 15px; font-size: 14px; + font-weight: bold; } .folder-upload-text{ margin-top: 10px; @@ -1835,13 +2096,28 @@ hr { .folder-upload-type{ color:#A4B2C6 ; font-size: 10px; + font-weight: bold; width: 100%; display: inline-block; text-align: center; } +.upload-table{ + margin: 15px 0 0; +} +.upload-table tr{ + border: dashed 1px #D7E7F9; +} +.upload-table tr th{ + border-bottom: solid 1px #F4F9FE !important; +} .upload-table .table thead th{ + padding: 6px 9px; border-top: 0px !important; - border-bottom: 0px !important; + font-weight: normal; + font-size: 13px; +} +.upload-table tr:last-child th{ + border-bottom: 0 !important; } .upload-table .table{ margin-bottom: 0px !important; @@ -1926,8 +2202,9 @@ hr { color: #1B3E6F; width: 100%; text-align: left; - padding-left: 0px !important; - font-size: 14px; + padding: 9px 0px !important; + font-size: 13px; + font-weight: bold; } .authentication-accordion .custom-control{ display: inline-block; @@ -1953,16 +2230,17 @@ hr { border-radius: 0px !important; border-bottom: 1px solid #ECEDF2 !important; } -.card-body { - padding: 20px 25px !important; +.template-mapping-accordion .card-body{ + padding: 20px 26px 0 !important; font-size: 14px; } .card-header .btn-link{ color: #1B3E6F; width: 100%; text-align: left; - padding-left: 0px !important; - font-size:14px; + padding: 9px 0px !important; + font-size: 13px; + font-weight: bold; } .accordion .card{ margin-bottom: 0px !important; @@ -1987,7 +2265,8 @@ hr { font-size: 15px; } .modal-title { - font-size: 14px; + font-size: 13px; + font-weight: bold; } .select-type{ background: #F4F9FE; @@ -2033,21 +2312,33 @@ hr { top: 13px; } .ace-tomorrow-night-bright .ace_print-margin{ + left: 100% !important; background: #eee !important; } +.ace_content{ + width: 100%; +} +.ace_line, +.ace-eclipse .ace_print-margin{ + background: #fff; +} .ace_editor{ + height: 55vh !important; line-height: 25px; border: 1px solid #ECEDF2; background-color: #fff; color: #1B3E6F; } -.ace-tomorrow-night-bright .ace_gutter{ - background: #1B3E6F !important; - border-right: 0px !important; - color: #fff !important; +.ace-tomorrow-night-bright .ace_gutter, +.ace-eclipse .ace_gutter{ + background: #E0E8F2 !important; + border-right: 0px !important; + color: #1B3E6F !important; } -.ace-tomorrow-night-bright .ace_gutter-active-line { +.ace-tomorrow-night-bright .ace_gutter-active-line, +.ace-eclipse .ace_gutter-active-line{ background-color: #265699; + color: #fff; } .ace-tomorrow-night-bright .ace_cursor{ color: #265699; @@ -2064,30 +2355,25 @@ hr { display: inline-block; font-size: 12px; } -.breadcrumb-header li::after{ - content: "/"; - padding: 0px 10px; - font-size: 16px; - color: #C3CDDB; -} + .breadcrumb-header li:last-child::after{ display: none; } .breadcrumb-header li:last-child{ -background: #F4F9FE; +/* background: #F4F9FE; */ border-radius: 50px; color: #C3CDDB; -padding: 4px 10px; +padding: 0 10px 0 0; } -.breadcrumb-header li:first-child{ +.breadcrumb-header li:first-child, +.breadcrumb-header li:first-child a{ font-size: 16px; font-weight: bold; - padding: 0px; - color: #1B3E6F; + padding: 0px; + color: #1B3E6F !important; border-radius: 0px; background: transparent; - padding: 4px 0px 3px; } .create-template-import{ width: 100%; @@ -2097,14 +2383,14 @@ padding: 4px 10px; .create-template-import a:hover{ text-decoration: none; } -.mapping-source-load { +.mapping-source-load{ color: #1B3E6F; font-size: 10px; font-weight: bold; display: inline-table; margin-top: 20px; margin-bottom: 10px; - margin:15px 30px 10px; + margin:15px 30px 20px; } .mapping-source-load:hover{ text-decoration: none; @@ -2113,7 +2399,6 @@ padding: 4px 10px; color: #1B3E6F; font-size: 36px; padding: 10px; - background: #F4F9FE; border-radius: 100px; width: 70px; height: 70px; @@ -2121,6 +2406,12 @@ padding: 4px 10px; line-height: 52px; margin-bottom: 20px; } +.mapping-source-load:hover i{ + background: #F4F9FE; +} +.mapping-source-load:hover span{ + color: #1273EB; +} .source-load-note{ color:#C3CDDB ; font-size: 8px; @@ -2138,16 +2429,21 @@ padding: 4px 10px; .template-mapping-list:hover, .template-mapping-list.active { background: #1B3E6F; text-decoration: none; - color: #fff; + color: #fff !important; + border-radius: 4px; + } +.template-mapping-list:hover{ + opacity: .9; +} + .template-mapping-list span{ background: #fff; color: #2A81ED; font-size: 8px; float: right; border-radius: 50px; - padding: 3px 10px; - margin-top: 1px; + padding: 4px 10px; margin-left: 5px; } @@ -2169,47 +2465,82 @@ margin-bottom: 20px; margin-right: 5px; } .view-package-container{ - padding: 20px; + padding: 20px 56px; } .package-type-icon{ - color: #fff; - background: #1B3E6F; - width: 40px; - height: 40px; - border-radius: 40px; + color: #1B3E6F; + background: #C1CDDD; + width: 48px; + height: 48px; + border-radius: 48px; display: inline-block; text-align: center; - line-height: 38px; + line-height: 48px; font-size: 20px; - margin-right: 20px; + /* margin-right: 20px; */ +} +.defintionsNote{ + padding-left: 0; +} +.defintionsNote li{ + line-height: 24px; + list-style: none; + font-size: 13px; } .package-name-container{ width: calc(100% - 60px); display: inline-block; } .package-name{ -font-size: 14px; -color: #1B3E6F; -font-weight: bold; -margin-top: 3px; + font-size: 16px; + color: #1B3E6F; + font-weight: bold; + margin-top: 3px; } .package-name span{ - font-size: 10px; - color: #C3CDDB; + font-size: 11px; } .package-name i{ font-size: 12px; color: #C3CDDB; margin-left: 5px; } -.package-name.deployed i{ - color: #66BB00; +.deply-status-icon{ + margin-left: 6px; + width: 1.6%; + vertical-align: baseline; } .package-description{ color: #D0D7E4; font-size: 12px; font-weight: normal; } +.package-auth-info{ + font-size: 11px; +} +.package-auth-info p{ + margin-bottom: 5px; +} +.package-auth-info div{ + padding-left: 25px; + border-right: solid 1px #F4F9FE; +} +.package-auth-info div:first-child{ + padding-left: 15px; +} +.package-auth-info .col-4:first-child{ + padding-left: 15px; +} +.package-auth-info div:last-child{ + border-right: 0; +} +.package-auth-info .package-contributers{ + margin-bottom: 0 !important; +} +.package-auth-info .package-contributers button img{ + width: 20px; + height: 20px; +} .template-mapping-action{ width: 100%; text-align: center; @@ -2217,6 +2548,8 @@ margin-top: 3px; } .template-mapping-action button{ border-radius: 50px; + padding: 6px 20px; + font-size: 14px; } .template-mapping-action .btn-primary{ background:#5DBDBA !important ; @@ -2244,7 +2577,116 @@ margin-top: 3px; .dataTables_empty { display: none; } +.dataTables_length, +.dataTables_filter{ + margin-bottom: 6px; + color: #1B3E6F !important; + font-size: 13px; + font-weight: bold; +} +.dataTables_filter input{ + color: #1B3E6F; + background: url(../src/assets/img/icon-search.svg) 9px center no-repeat; + padding: 4px 9px 4px 24px; + border: solid 1px #ECEDF2; + border-radius: 4px; +} +.dataTables_filter input:focus{ + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.1); +} +#mapping-table th, +#mapping-table td{ + width: auto !important; + padding: 7px 20px 7px 0; + border-bottom: solid 1px #ECEDF2; + font-size: 13px; +} +#mapping-table th:first-child, +#mapping-table td:first-child{ + padding-left: 20px; +} +#mapping-table tbody tr:hover{ + background-color: #F4F9FE; +} +#mapping-table th{ + padding-top: 10px; + padding-bottom: 10px; + background: #F4F9FE; +} +#mapping-table td{ + border-top: 0; +} +table.dataTable.no-footer{ + margin-bottom: 9px; + border-bottom: solid 1px #ECEDF2 !important; +} +.dataTables_info{ + padding-top: 12px; + color: #1B3E6F !important; + font-size: 13px; + font-weight: bold; +} +.dataTables_wrapper .dataTables_paginate, +.dataTables_wrapper .dataTables_paginate a.paginate_button, +.dataTables_wrapper .dataTables_paginate a.paginate_button.current, +.dataTables_wrapper .dataTables_paginate a.paginate_button.disabled{ + margin-bottom: 3px; + color: #1B3E6F !important; + font-size: 13px; + font-weight: bold; + border: 0 !important; +} +.dataTables_wrapper .dataTables_paginate a.paginate_button:hover{ + border: 0; + color: #1B3E6F !important; + background: none !important; +} +.dataTables_wrapper .dataTables_paginate a.paginate_button{ + padding: 0.4em .9em !important; +} +.dataTables_wrapper .dataTables_paginate a.paginate_button.current{ + color: #1B3E6F !important; + background: #F4F9FE !important; + border: solid 1px #EEF4F9 !important; + border-radius: 100% !important; + box-shadow: 0 2px 6px 0 rgba(47, 83, 151, 0.1); + outline: 0; +} +.dataTables_wrapper .dataTables_paginate a.paginate_button.disabled{ + opacity: .6; +} +.dataTables_wrapper .dataTables_paginate a.paginate_button.disabled:hover{ + cursor: default; + background: none !important; + border: 0 !important; +} +#mapping-table .form-control, +#mapping-table .custom-select{ + padding: 10px 6px; + border-color: #EEF4F9; + font-size: 14px; + line-height: 12px; + color: #1B3E6F; +} +#mapping-table .form-control{ + box-shadow: 0 2px 4px rgba(47,83,151,0.1); +} +#mapping-table tbody tr:hover .form-control:focus, +#mapping-table tbody tr:hover .custom-select{ + background-color: #fff !important; +} +#mapping-table .custom-select{ + background-color: #F4F9FE; + color: #1B3E6F; +} +#mapping-table .form-control:disabled{ + padding-left: 0; + box-shadow: none; + border: 0; + background: transparent; + color: #1B3E6F; +} /* Extra small devices (portrait phones, less than 576px) */ @media (max-width: 575.98px) { .page-title{ diff --git a/cds-ui/pom.xml b/cds-ui/pom.xml index fd505b4a4..68667a1a8 100644 --- a/cds-ui/pom.xml +++ b/cds-ui/pom.xml @@ -18,19 +18,20 @@ 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============================================ --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.parent</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>1.5.2</version> + <version>2.0.0-SNAPSHOT</version> <relativePath/> </parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ui</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CDS UI Parent</name> diff --git a/cds-ui/server/pom.xml b/cds-ui/server/pom.xml index c36139e07..11bfd9fd7 100644 --- a/cds-ui/server/pom.xml +++ b/cds-ui/server/pom.xml @@ -18,18 +18,19 @@ 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============================================ --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ui</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <artifactId>ui-server</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CDS UI Server</name> diff --git a/cds-ui/server/src/controllers/controller-catalog.controller.ts b/cds-ui/server/src/controllers/controller-catalog.controller.ts index 20e1cded6..b55785dcc 100644 --- a/cds-ui/server/src/controllers/controller-catalog.controller.ts +++ b/cds-ui/server/src/controllers/controller-catalog.controller.ts @@ -60,14 +60,14 @@ export class ControllerCatalogController { return await this.Ccservice.getDefinitionTypes(definitionType); } - @del('/controllercatalog/model-type/{name}', { - responses: { - '200': { - content: { 'application/json': {} } - } - }, - }) - async delete(@param.path.string('name') name: string): Promise<JSON> { - return await this.Ccservice.deleteCatalog(name); - } + @del('/controllercatalog/{name}', { + responses: { + '200': { + content: { 'application/json': {} } + } + }, + }) + async delete(@param.path.string('name') name: string) { + return await this.Ccservice.delete(name); + } } diff --git a/cds-ui/server/src/datasources/controller-catalog.datasource-template.ts b/cds-ui/server/src/datasources/controller-catalog.datasource-template.ts index e45741576..dcd732a1b 100644 --- a/cds-ui/server/src/datasources/controller-catalog.datasource-template.ts +++ b/cds-ui/server/src/datasources/controller-catalog.datasource-template.ts @@ -57,20 +57,20 @@ export default { }
},
- {
- "template": {
- "method": "DEL",
- "url": processorApiConfig.http.url + "/model-type/{name}",
- "headers": {
- "accepts": "application/json",
- "content-type": "application/json",
- "authorization": processorApiConfig.http.authToken
- },
- "responsePath": "$.*"
- },
- "functions": {
- "delete": ["name"]
- }
- }
+ {
+ "template": {
+ "method": "DELETE",
+ "url": processorApiConfig.http.url + "/model-type/{name}",
+ "headers": {
+ "accepts": "application/json",
+ "content-type": "application/json",
+ "authorization": processorApiConfig.http.authToken
+ },
+ "responsePath": "$.*"
+ },
+ "functions": {
+ "delete": ["name"]
+ }
+ }
]
};
\ No newline at end of file diff --git a/cds-ui/server/src/services/controller-catalog.service.ts b/cds-ui/server/src/services/controller-catalog.service.ts index 9b4880543..db8d8560c 100644 --- a/cds-ui/server/src/services/controller-catalog.service.ts +++ b/cds-ui/server/src/services/controller-catalog.service.ts @@ -6,7 +6,7 @@ export interface ControllerCatalogService { getByTags(tags: string): Promise<JSON>;
save(controllerCatalog: JSON): Promise<JSON>;
getDefinitionTypes(definitionType: string): Promise<JSON>;
- deleteCatalog(name: string): Promise<JSON>;
+ delete(name: string): Promise<JSON>;
}
export class ControllerCatalogServiceProvider implements Provider<ControllerCatalogService> {
diff --git a/components/model-catalog/blueprint-model/pom.xml b/components/model-catalog/blueprint-model/pom.xml index e84ae31bb..7eaeda290 100644 --- a/components/model-catalog/blueprint-model/pom.xml +++ b/components/model-catalog/blueprint-model/pom.xml @@ -14,19 +14,20 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>cba-parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../../../ms/blueprintsprocessor/cba-parent</relativePath> </parent> <groupId>org.onap.ccsdk.cds.cba</groupId> <artifactId>blueprint-model</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CBA - Blueprints</name> diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml index cdc3964b7..f2f51964b 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml +++ b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.cba</groupId> <artifactId>test-blueprint-model</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>capability_cli</artifactId> diff --git a/components/model-catalog/blueprint-model/test-blueprint/pom.xml b/components/model-catalog/blueprint-model/test-blueprint/pom.xml index 023ca09f3..8367d6b4b 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/pom.xml +++ b/components/model-catalog/blueprint-model/test-blueprint/pom.xml @@ -14,17 +14,18 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.cba</groupId> <artifactId>blueprint-model</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>test-blueprint-model</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CBA - Test Blueprints</name> diff --git a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml index 654ccb385..21d9b8df5 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml +++ b/components/model-catalog/blueprint-model/test-blueprint/resource-audit/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.cba</groupId> <artifactId>test-blueprint-model</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.components.cba</groupId> diff --git a/components/pom.xml b/components/pom.xml index e6ff71629..184c2cac8 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <artifactId>components</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>Components Root</name> diff --git a/docs/index.rst b/docs/index.rst index 0e43fd51c..93ebe9015 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,7 @@ .. This work is licensed under a Creative Commons Attribution 4.0 .. International License. http://creativecommons.org/licenses/by/4.0 .. Copyright (C) 2019 IBM. +.. _master_index: .. _cds_main-doc: diff --git a/docs/release-notes.rst b/docs/release-notes.rst index a53419f67..428866a8d 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -1,8 +1,9 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 .. Copyright (C) 2019 IBM. +.. _release_notes: Release-Notes ------------- .. toctree:: - :maxdepth: 1
\ No newline at end of file + :maxdepth: 1 diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml index f6ef2ed29..16a2d456e 100755 --- a/ms/blueprintsprocessor/application/pom.xml +++ b/ms/blueprintsprocessor/application/pom.xml @@ -17,13 +17,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../parent</relativePath> </parent> diff --git a/ms/blueprintsprocessor/application/src/main/docker/Dockerfile b/ms/blueprintsprocessor/application/src/main/docker/Dockerfile index 1035915f1..bd1b3804a 100755 --- a/ms/blueprintsprocessor/application/src/main/docker/Dockerfile +++ b/ms/blueprintsprocessor/application/src/main/docker/Dockerfile @@ -9,9 +9,16 @@ FROM omahoco1/alpine-java-python # add entrypoint COPY startService.sh /startService.sh +RUN addgroup -S onap && adduser -S onap -G onap +RUN chown onap:onap /startService.sh +RUN touch /velocity.log && chmod 777 /velocity.log +RUN chown onap:onap /velocity.log RUN chmod 777 /startService.sh && dos2unix /startService.sh # add application COPY --from=extractor /opt /opt +RUN mkdir -p /opt/app/onap/blueprints/deploy +RUN chown onap:onap /opt -R +USER onap ENTRYPOINT [ "/startService.sh" ] diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties index 5beebd8e8..bf5e23bc9 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties @@ -129,13 +129,32 @@ blueprintsprocessor.messageconsumer.self-service-api.type=kafka-basic-auth blueprintsprocessor.messageconsumer.self-service-api.bootstrapServers=127.0.0.1:9092 blueprintsprocessor.messageconsumer.self-service-api.groupId=receiver-id blueprintsprocessor.messageconsumer.self-service-api.topic=receiver.t -blueprintsprocessor.messageconsumer.self-service-api.clientId=default-client-id +blueprintsprocessor.messageconsumer.self-service-api.clientId=request-receiver-client-id blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=1000 +#### Security settings +#### SSL +#blueprintsprocessor.messageconsumer.self-service-api.truststore=/path/to/truststore.jks +#blueprintsprocessor.messageconsumer.self-service-api.truststorePassword=truststorePassword +#blueprintsprocessor.messageconsumer.self-service-api.keystore=/path/to/keystore.jks +#blueprintsprocessor.messageconsumer.self-service-api.keystorePassword=keystorePassword +#### SCRAM +#blueprintsprocessor.messageconsumer.self-service-api.scramUsername=test-user +#blueprintsprocessor.messageconsumer.self-service-api.scramPassword=testUserPassword + +# Kafka audit service Configurations +## Audit request +blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable=false +blueprintsprocessor.messageproducer.self-service-api.audit.request.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.request.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.request.clientId=audit-request-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.request.topic=audit-request-producer.t + +## Audit response +blueprintsprocessor.messageproducer.self-service-api.audit.response.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.response.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.response.clientId=audit-response-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.response.topic=audit-response-producer.t -blueprintsprocessor.messageproducer.self-service-api.type=kafka-basic-auth -blueprintsprocessor.messageproducer.self-service-api.bootstrapServers=127.0.0.1:9092 -blueprintsprocessor.messageproducer.self-service-api.clientId=default-client-id -blueprintsprocessor.messageproducer.self-service-api.topic=producer.t # Message prioritization kakfa properties, Enable if Prioritization service is needed # Deploy message-prioritization function along with blueprintsprocessor application. diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties index 74549b0ae..6fb737edc 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties @@ -103,20 +103,35 @@ blueprintsprocessor.restclient.aai-data.additionalHeaders.X-TransactionId=cds-tr blueprintsprocessor.restclient.aai-data.additionalHeaders.X-FromAppId=cds-app-id blueprintsprocessor.restclient.aai-data.additionalHeaders.Accept=application/json -# Kafka-message-lib Configuration -blueprintsprocessor.messageconsumer.self-service-api.kafkaEnable=false -blueprintsprocessor.messageconsumer.self-service-api.type=kafka-basic-auth -blueprintsprocessor.messageconsumer.self-service-api.bootstrapServers=127.0.0.1:9092 -blueprintsprocessor.messageconsumer.self-service-api.topic=receiver.t -blueprintsprocessor.messageconsumer.self-service-api.groupId=receiver-id -blueprintsprocessor.messageconsumer.self-service-api.clientId=default-client-id -blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=1000 - -blueprintsprocessor.messageproducer.self-service-api.type=kafka-basic-auth -blueprintsprocessor.messageproducer.self-service-api.bootstrapServers=127.0.0.1:9092 -blueprintsprocessor.messageproducer.self-service-api.clientId=default-client-id -blueprintsprocessor.messageproducer.self-service-api.topic=producer.t - +# Kafka audit service Configurations +## Audit request +blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable=false +blueprintsprocessor.messageproducer.self-service-api.audit.request.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.request.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.request.clientId=audit-request-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.request.topic=audit-request-producer.t +#### Security settings +#### SSL +#blueprintsprocessor.messageproducer.self-service-api.audit.request.truststore=/path/to/truststore.jks +#blueprintsprocessor.messageproducer.self-service-api.audit.request.truststorePassword=truststorePassword +#blueprintsprocessor.messageproducer.self-service-api.audit.request.keystore=/path/to/keystore.jks +#blueprintsprocessor.messageproducer.self-service-api.audit.request.keystorePassword=keystorePassword +#### SCRAM +#blueprintsprocessor.messageproducer.self-service-api.audit.request.scramUsername=test-user +#blueprintsprocessor.messageproducer.self-service-api.audit.request.scramPassword=testUserPassword + +## Audit response +blueprintsprocessor.messageproducer.self-service-api.audit.response.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.response.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.response.clientId=audit-response-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.response.topic=audit-response-producer.t + +# Message prioritization kakfa properties, Enable if Prioritization service is needed +# Deploy message-prioritization function along with blueprintsprocessor application. +#blueprintsprocessor.messageconsumer.prioritize-input.type=kafka-streams-basic-auth +#blueprintsprocessor.messageconsumer.prioritize-input.bootstrapServers=127.0.0.1:9092 +#blueprintsprocessor.messageconsumer.prioritize-input.applicationId=cds-controller +#blueprintsprocessor.messageconsumer.prioritize-input.topic=prioritize-input-topic blueprintprocessor.remoteScriptCommand.enabled=true diff --git a/ms/blueprintsprocessor/application/src/test/resources/application.properties b/ms/blueprintsprocessor/application/src/test/resources/application.properties index cb3419397..c6e957b32 100644 --- a/ms/blueprintsprocessor/application/src/test/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/test/resources/application.properties @@ -74,14 +74,26 @@ blueprintsprocessor.cliExecutor.enabled=true blueprintsprocessor.remoteScriptCommand.enabled=false -# Kafka-message-lib Configuration -blueprintsprocessor.messageclient.self-service-api.topic=producer.t -blueprintsprocessor.messageclient.self-service-api.type=kafka-basic-auth -blueprintsprocessor.messageclient.self-service-api.bootstrapServers=127.0.0.1:9092 -blueprintsprocessor.messageclient.self-service-api.consumerTopic=receiver.t -blueprintsprocessor.messageclient.self-service-api.groupId=receiver-id -blueprintsprocessor.messageclient.self-service-api.clientId=default-client-id -blueprintsprocessor.messageclient.self-service-api.kafkaEnable=false +# Kafka-message-lib Configurations +blueprintsprocessor.messageconsumer.self-service-api.kafkaEnable=false +blueprintsprocessor.messageconsumer.self-service-api.type=kafka-basic-auth +blueprintsprocessor.messageconsumer.self-service-api.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageconsumer.self-service-api.groupId=receiver-id +blueprintsprocessor.messageconsumer.self-service-api.topic=receiver.t +blueprintsprocessor.messageconsumer.self-service-api.clientId=request-receiver-client-id +blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=1000 + +# Kafka audit service Configurations +blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable=false +blueprintsprocessor.messageproducer.self-service-api.audit.request.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.request.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.request.clientId=audit-request-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.request.topic=audit-request-producer.t + +blueprintsprocessor.messageproducer.self-service-api.audit.response.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.response.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.response.clientId=audit-response-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.response.topic=audit-response-producer.t endpoints.user.name=eHbVUbJAj4AG2522cSbrOQ== diff --git a/ms/blueprintsprocessor/cba-parent/pom.xml b/ms/blueprintsprocessor/cba-parent/pom.xml index e0ad43a8e..7b57962c2 100644 --- a/ms/blueprintsprocessor/cba-parent/pom.xml +++ b/ms/blueprintsprocessor/cba-parent/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../parent</relativePath> </parent> diff --git a/ms/blueprintsprocessor/functions/ansible-awx-executor/pom.xml b/ms/blueprintsprocessor/functions/ansible-awx-executor/pom.xml index 9c699bab6..7be13dece 100644 --- a/ms/blueprintsprocessor/functions/ansible-awx-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/ansible-awx-executor/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>ansible-awx-executor</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <name>Blueprints Processor Function - Ansible AWX Executor</name> <description>Blueprints Processor Function - Ansible Executor</description> diff --git a/ms/blueprintsprocessor/functions/cli-executor/pom.xml b/ms/blueprintsprocessor/functions/cli-executor/pom.xml index 28d96ad73..867809479 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/cli-executor/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>cli-executor</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <name>Blueprints Processor Function - CLI Executor</name> <description>Blueprints Processor Function - CLI Executor</description> diff --git a/ms/blueprintsprocessor/functions/config-snapshots/pom.xml b/ms/blueprintsprocessor/functions/config-snapshots/pom.xml index 0f6c10e89..4aa3ebbb1 100644 --- a/ms/blueprintsprocessor/functions/config-snapshots/pom.xml +++ b/ms/blueprintsprocessor/functions/config-snapshots/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>config-snapshots</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <name>Blueprints Processor Function - Config Snapshots</name> <description>Blueprints Processor Function - Config Snapshots</description> diff --git a/ms/blueprintsprocessor/functions/config-snapshots/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/ComponentConfigSnapshotsExecutor.kt b/ms/blueprintsprocessor/functions/config-snapshots/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/ComponentConfigSnapshotsExecutor.kt index 0bf4e5f32..311e95bc2 100644 --- a/ms/blueprintsprocessor/functions/config-snapshots/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/ComponentConfigSnapshotsExecutor.kt +++ b/ms/blueprintsprocessor/functions/config-snapshots/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/config/snapshots/ComponentConfigSnapshotsExecutor.kt @@ -194,7 +194,7 @@ open class ComponentConfigSnapshotsExecutor(private val cfgSnapshotService: Reso private fun setNodeOutputProperties(status: String, snapshot: String) { setAttribute(OUTPUT_STATUS, status.asJsonPrimitive()) setAttribute(OUTPUT_SNAPSHOT, snapshot.asJsonPrimitive()) - log.info("Setting output $OUTPUT_STATUS=$status, $OUTPUT_SNAPSHOT=$snapshot ") + log.debug("Setting output $OUTPUT_STATUS=$status") } /** diff --git a/ms/blueprintsprocessor/functions/message-prioritizaion/pom.xml b/ms/blueprintsprocessor/functions/message-prioritizaion/pom.xml index d12a1f2b3..4c38c53d2 100644 --- a/ms/blueprintsprocessor/functions/message-prioritizaion/pom.xml +++ b/ms/blueprintsprocessor/functions/message-prioritizaion/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> diff --git a/ms/blueprintsprocessor/functions/message-prioritizaion/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/message/prioritization/MessagePrioritizationConsumerTest.kt b/ms/blueprintsprocessor/functions/message-prioritizaion/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/message/prioritization/MessagePrioritizationConsumerTest.kt index 35bc49402..7e6bf68be 100644 --- a/ms/blueprintsprocessor/functions/message-prioritizaion/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/message/prioritization/MessagePrioritizationConsumerTest.kt +++ b/ms/blueprintsprocessor/functions/message-prioritizaion/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/message/prioritization/MessagePrioritizationConsumerTest.kt @@ -38,7 +38,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.message.prioritization.s import org.onap.ccsdk.cds.blueprintsprocessor.functions.message.prioritization.utils.MessagePrioritizationSample import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BluePrintMessageLibPropertyService -import org.onap.ccsdk.cds.blueprintsprocessor.message.service.KafkaBasicAuthMessageProducerService +import org.onap.ccsdk.cds.blueprintsprocessor.message.service.KafkaMessageProducerService import org.onap.ccsdk.cds.blueprintsprocessor.nats.BluePrintNatsLibConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.nats.service.BluePrintNatsLibPropertyService import org.onap.ccsdk.cds.blueprintsprocessor.nats.utils.NatsClusterUtils @@ -72,15 +72,27 @@ import kotlin.test.assertNotNull "spring.jpa.properties.hibernate.show_sql=false", "spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl", - "blueprintsprocessor.messageconsumer.prioritize-input.type=kafka-streams-basic-auth", + "blueprintsprocessor.messageconsumer.prioritize-input.type=kafka-streams-scram-ssl-auth", "blueprintsprocessor.messageconsumer.prioritize-input.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageconsumer.prioritize-input.applicationId=test-prioritize-application", "blueprintsprocessor.messageconsumer.prioritize-input.topic=prioritize-input-topic", + "blueprintsprocessor.messageconsumer.prioritize-input.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageconsumer.prioritize-input.truststorePassword=truststorePassword", + "blueprintsprocessor.messageconsumer.prioritize-input.keystore=/path/to/keystore.jks", + "blueprintsprocessor.messageconsumer.prioritize-input.keystorePassword=keystorePassword", + "blueprintsprocessor.messageconsumer.prioritize-input.scramUsername=test-user", + "blueprintsprocessor.messageconsumer.prioritize-input.scramPassword=testUserPassword", // To send initial test message - "blueprintsprocessor.messageproducer.prioritize-input.type=kafka-basic-auth", + "blueprintsprocessor.messageproducer.prioritize-input.type=kafka-scram-ssl-auth", "blueprintsprocessor.messageproducer.prioritize-input.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageproducer.prioritize-input.topic=prioritize-input-topic", + "blueprintsprocessor.messageproducer.prioritize-input.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageproducer.prioritize-input.truststorePassword=truststorePassword", + "blueprintsprocessor.messageproducer.prioritize-input.keystore=/path/to/keystore.jks", + "blueprintsprocessor.messageproducer.prioritize-input.keystorePassword=keystorePassword", + "blueprintsprocessor.messageproducer.prioritize-input.scramUsername=test-user", + "blueprintsprocessor.messageproducer.prioritize-input.scramPassword=testUserPassword", "blueprintsprocessor.nats.cds-controller.type=token-auth", "blueprintsprocessor.nats.cds-controller.host=nats://localhost:4222", @@ -241,7 +253,7 @@ open class MessagePrioritizationConsumerTest { /** Send sample message with every 1 sec */ val blueprintMessageProducerService = bluePrintMessageLibPropertyService - .blueprintMessageProducerService("prioritize-input") as KafkaBasicAuthMessageProducerService + .blueprintMessageProducerService("prioritize-input") as KafkaMessageProducerService launch { MessagePrioritizationSample.sampleMessages(MessageState.NEW.name, 2).forEach { delay(100) diff --git a/ms/blueprintsprocessor/functions/netconf-executor/pom.xml b/ms/blueprintsprocessor/functions/netconf-executor/pom.xml index 2ff7106ec..69b42e016 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/netconf-executor/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>netconf-executor</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <name>Blueprints Processor Function - Netconf Executor</name> <description>Blueprints Processor Function - Netconf Executor</description> diff --git a/ms/blueprintsprocessor/functions/pom.xml b/ms/blueprintsprocessor/functions/pom.xml index de21f40f1..4d417f38b 100755 --- a/ms/blueprintsprocessor/functions/pom.xml +++ b/ms/blueprintsprocessor/functions/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../parent</relativePath> </parent> diff --git a/ms/blueprintsprocessor/functions/python-executor/pom.xml b/ms/blueprintsprocessor/functions/python-executor/pom.xml index 0cd8a11ae..c6480fade 100644 --- a/ms/blueprintsprocessor/functions/python-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/python-executor/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt index ddfaf9ac2..d66e8b374 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2019 IBM. + * 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,6 +17,10 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor import com.fasterxml.jackson.databind.JsonNode +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.TimeoutCancellationException +import kotlinx.coroutines.async +import kotlinx.coroutines.withTimeout import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.PrepareRemoteEnvInput import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.RemoteIdentifier @@ -51,14 +55,19 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic const val INPUT_ENDPOINT_SELECTOR = "endpoint-selector" const val INPUT_DYNAMIC_PROPERTIES = "dynamic-properties" const val INPUT_ARGUMENT_PROPERTIES = "argument-properties" + const val INPUT_COMMAND = "command" const val INPUT_PACKAGES = "packages" const val DEFAULT_SELECTOR = "remote-python" + const val INPUT_ENV_PREPARE_TIMEOUT = "env-prepare-timeout" + const val INPUT_EXECUTE_TIMEOUT = "execution-timeout" const val ATTRIBUTE_EXEC_CMD_STATUS = "status" const val ATTRIBUTE_PREPARE_ENV_LOG = "prepare-environment-logs" const val ATTRIBUTE_EXEC_CMD_LOG = "execute-command-logs" const val ATTRIBUTE_RESPONSE_DATA = "response-data" + const val DEFAULT_ENV_PREPARE_TIMEOUT_IN_SEC = 120 + const val DEFAULT_EXECUTE_TIMEOUT_IN_SEC = 180 } override suspend fun processNB(executionRequest: ExecutionServiceInput) { @@ -95,6 +104,16 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic ?.rootFieldsToMap()?.toSortedMap()?.values?.joinToString(" ") { formatNestedJsonNode(it) } val command = getOperationInput(INPUT_COMMAND).asText() + + /** + * Timeouts that are specific to the command executor. + * Note: the interface->input->timeout is the component level timeout. + */ + val envPrepTimeout = getOptionalOperationInput(INPUT_ENV_PREPARE_TIMEOUT)?.asInt() + ?: DEFAULT_ENV_PREPARE_TIMEOUT_IN_SEC + val executionTimeout = getOptionalOperationInput(INPUT_EXECUTE_TIMEOUT)?.asInt() + ?: DEFAULT_EXECUTE_TIMEOUT_IN_SEC + var scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath) if (args != null && args.isNotEmpty()) { scriptCommand = scriptCommand.plus(" ").plus(args) @@ -116,9 +135,10 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic requestId = processId, remoteIdentifier = RemoteIdentifier( blueprintName = blueprintName, - blueprintVersion = blueprintVersion - ), - packages = packages + blueprintVersion = blueprintVersion), + packages = packages, + timeOut = envPrepTimeout.toLong() + ) val prepareEnvOutput = remoteScriptExecutionService.prepareEnv(prepareEnvInput) log.info("$ATTRIBUTE_PREPARE_ENV_LOG - ${prepareEnvOutput.response}") @@ -132,10 +152,26 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic } else { setNodeOutputProperties(prepareEnvOutput.status.name.asJsonPrimitive(), logsEnv, "".asJsonPrimitive()) } + } else { + // set env preparation log to empty... + setAttribute(ATTRIBUTE_PREPARE_ENV_LOG, "".asJsonPrimitive()) } - - // if Env preparation was successful, then proceed with command execution in this Env - if (bluePrintRuntimeService.getBluePrintError().errors.isEmpty()) { + } catch (grpcEx: io.grpc.StatusRuntimeException) { + val grpcErrMsg = "Command failed during env. preparation... timeout($envPrepTimeout) requestId ($processId)." + setAttribute(ATTRIBUTE_PREPARE_ENV_LOG, grpcErrMsg.asJsonPrimitive()) + setNodeOutputErrors(status = grpcErrMsg, message = "${grpcEx.status}".asJsonPrimitive()) + log.error(grpcErrMsg, grpcEx) + addError(grpcErrMsg) + } catch (e: Exception) { + val timeoutErrMsg = "Command executor failed during env. preparation.. timeout($envPrepTimeout) requestId ($processId)." + setAttribute(ATTRIBUTE_PREPARE_ENV_LOG, e.message.asJsonPrimitive()) + setNodeOutputErrors(status = timeoutErrMsg, message = "${e.message}".asJsonPrimitive()) + log.error("Failed to process on remote executor requestId ($processId)", e) + addError(timeoutErrMsg) + } + // if Env preparation was successful, then proceed with command execution in this Env + if (bluePrintRuntimeService.getBluePrintError().errors.isEmpty()) { + try { // Populate command execution properties and pass it to the remote server val properties = dynamicProperties?.returnNullIfMissing()?.rootFieldsToMap() ?: hashMapOf() @@ -143,25 +179,41 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic requestId = processId, remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, blueprintVersion = blueprintVersion), command = scriptCommand, - properties = properties - ) - val remoteExecutionOutput = remoteScriptExecutionService.executeCommand(remoteExecutionInput) + properties = properties, + timeOut = implementation.timeout.toLong()) + + val remoteExecutionOutputDeferred = GlobalScope.async { + remoteScriptExecutionService.executeCommand(remoteExecutionInput) + } + + val remoteExecutionOutput = withTimeout(implementation.timeout * 1000L) { + remoteExecutionOutputDeferred.await() + } + checkNotNull(remoteExecutionOutput) { + "Error: Request-id $processId did not return a restul from remote command execution." + } val logs = JacksonUtils.jsonNodeFromObject(remoteExecutionOutput.response) if (remoteExecutionOutput.status != StatusType.SUCCESS) { setNodeOutputErrors(remoteExecutionOutput.status.name, logs, remoteExecutionOutput.payload) } else { - setNodeOutputProperties( - remoteExecutionOutput.status.name.asJsonPrimitive(), logs, - remoteExecutionOutput.payload - ) + setNodeOutputProperties(remoteExecutionOutput.status.name.asJsonPrimitive(), logs, + remoteExecutionOutput.payload) } + } catch (timeoutEx: TimeoutCancellationException) { + val timeoutErrMsg = "Command executor timed out executing after $executionTimeout seconds requestId ($processId)" + setNodeOutputErrors(status = timeoutErrMsg, message = "".asJsonPrimitive()) + log.error(timeoutErrMsg, timeoutEx) + } catch (grpcEx: io.grpc.StatusRuntimeException) { + val timeoutErrMsg = "Command executor timed out executing after $executionTimeout seconds requestId ($processId)" + setNodeOutputErrors(status = timeoutErrMsg, message = "".asJsonPrimitive()) + log.error("Command executor time out during GRPC call", grpcEx) + } catch (e: Exception) { + log.error("Failed to process on remote executor requestId ($processId)", e) } - } catch (e: Exception) { - log.error("Failed to process on remote executor", e) - } finally { - remoteScriptExecutionService.close() } + log.debug("Trying to close GRPC channel. request ($processId)") + remoteScriptExecutionService.close() } override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { @@ -201,7 +253,6 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic log.info("Executor message : $message") setAttribute(ATTRIBUTE_RESPONSE_DATA, artifacts) log.info("Executor artifacts: $artifacts") - addError(status, ATTRIBUTE_EXEC_CMD_LOG, message.toString()) } } diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintPythonHost.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintPythonHost.kt index 93fe2b1f5..3d2f10ec0 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintPythonHost.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintPythonHost.kt @@ -15,7 +15,9 @@ */ package org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor.scripts +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceDomains import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage import org.python.core.PyObject import org.python.util.PythonInterpreter @@ -42,6 +44,10 @@ open class BlueprintPythonHost(private val bluePrintPython: BluePrintPython) { bluePrintPython.moduleName = "Blueprint Python Script [Class Name = $interfaceName]" try { return blueprintPythonInterpreterProxy.getPythonInstance(properties) + } catch (e: BluePrintProcessorException) { + val errorMsg = "Failed to get python instance." + throw e.updateErrorMessage(ExecutionServiceDomains.PYTHON_EXECUTOR, errorMsg, + "Error in environment properties") } catch (e: Exception) { throw BluePrintProcessorException("Failed to execute Jython component $e", e) } diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt index 3d58afad8..5e57b9eb7 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt @@ -30,6 +30,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StatusType import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.RemoteScriptExecutionService import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintError import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType import org.onap.ccsdk.cds.controllerblueprints.core.putJsonElement @@ -90,6 +91,7 @@ class ComponentRemotePythonExecutorTest { val componentRemotePythonExecutor = ComponentRemotePythonExecutor(remoteScriptExecutionService) val bluePrintRuntime = mockk<DefaultBluePrintRuntimeService>("123456-1000") + every { bluePrintRuntime.getBluePrintError() } answers { BluePrintError() } // successful case. every { bluePrintRuntime.setNodeTemplateAttributeValue(any(), any(), any()) } answers {} val input = getMockedOutput(bluePrintRuntime) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/pom.xml b/ms/blueprintsprocessor/functions/resource-resolution/pom.xml index d2aecf0cf..8b0b7e798 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/pom.xml +++ b/ms/blueprintsprocessor/functions/resource-resolution/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>resource-resolution</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Blueprints Processor Function - Resource Resolution</name> diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt index a65ec585b..8087f7e3f 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt @@ -23,6 +23,10 @@ class ResourceAssignmentRuntimeService(private var id: String, private var blueP resourceStore[key] = value } + fun getResolutionStore(): MutableMap<String, JsonNode> { + return resourceStore.mapValues { e -> e.value.deepCopy() as JsonNode }.toMutableMap() + } + fun getResolutionStore(key: String): JsonNode { return resourceStore[key] ?: throw BluePrintProcessorException("failed to get execution property ($key)") diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt index 8f6069160..b934940b1 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt @@ -30,4 +30,5 @@ object ResourceResolutionConstants { const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id" const val RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE = "resource-type" const val RESOURCE_RESOLUTION_INPUT_RESOLUTION_SUMMARY = "resolution-summary" + const val METADATA_TRANSFORM_TEMPLATE = "transform-template" } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceProperties.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceProperties.kt index 636e81dda..7a7edc92b 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceProperties.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceSourceProperties.kt @@ -51,6 +51,8 @@ open class RestResourceSource : ResourceSourceProperties() { lateinit var verb: String @get:JsonProperty("payload") var payload: String? = null + @get:JsonProperty("resolved-payload") + var resolvedPayload: String? = null lateinit var type: String @get:JsonProperty("endpoint-selector") var endpointSelector: String? = null diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt index 0bfd7e4e2..2640b5b85 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt @@ -23,10 +23,12 @@ import org.onap.ccsdk.cds.blueprintsprocessor.db.PrimaryDBLibGenericService import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.DatabaseResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceDomains import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException -import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.KeyIdentifier import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment @@ -64,6 +66,10 @@ open class DatabaseResourceAssignmentProcessor( } // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) + } catch (e: BluePrintProcessorException) { + val errorMsg = "Failed to process Database resource resolution in template key ($resourceAssignment) assignments." + throw e.updateErrorMessage(ExecutionServiceDomains.RESOURCE_RESOLUTION, errorMsg, + "Wrong resource definition or DB resolution failed.") } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", e) @@ -101,7 +107,7 @@ open class DatabaseResourceAssignmentProcessor( "DatabaseResource ($dSource) dictionary information: " + "Query:($sql), input-key-mapping:($inputKeyMapping), output-key-mapping:(${sourceProperties.outputKeyMapping})" ) - val jdbcTemplate = blueprintDBLibService(sourceProperties) + val jdbcTemplate = blueprintDBLibService(sourceProperties, dSource) val rows = jdbcTemplate.query(sql, populateNamedParameter(inputKeyMapping)) if (rows.isNullOrEmpty()) { @@ -111,12 +117,12 @@ open class DatabaseResourceAssignmentProcessor( } } - private fun blueprintDBLibService(sourceProperties: DatabaseResourceSource): BluePrintDBLibGenericService { + private fun blueprintDBLibService(sourceProperties: DatabaseResourceSource, selector: String): BluePrintDBLibGenericService { return if (isNotEmpty(sourceProperties.endpointSelector)) { val dbPropertiesJson = raRuntimeService.resolveDSLExpression(sourceProperties.endpointSelector!!) bluePrintDBLibPropertyService.JdbcTemplate(dbPropertiesJson) } else { - primaryDBLibGenericService + bluePrintDBLibPropertyService.JdbcTemplate(selector) } } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt index 7705c1102..2921cb6fb 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt @@ -19,7 +19,9 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.pro import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceDomains import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.slf4j.LoggerFactory import org.springframework.beans.factory.config.ConfigurableBeanFactory @@ -49,6 +51,10 @@ open class DefaultResourceResolutionProcessor : ResourceAssignmentProcessor() { } // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) + } catch (e: BluePrintProcessorException) { + val errorMsg = "Failed to process default resource resolution in template key ($resourceAssignment) assignments." + throw e.updateErrorMessage(ExecutionServiceDomains.RESOURCE_RESOLUTION, errorMsg, + "Wrong default value was set.") } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", e) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt index f04a787db..d078a2d70 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt @@ -20,8 +20,10 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.pro import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.DatabaseResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceDomains import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.springframework.beans.factory.config.ConfigurableBeanFactory @@ -48,6 +50,10 @@ open class InputResourceResolutionProcessor : ResourceAssignmentProcessor() { } // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) + } catch (e: BluePrintProcessorException) { + val errorMsg = "Failed to process input resource resolution in template key ($resourceAssignment) assignments." + throw e.updateErrorMessage(ExecutionServiceDomains.RESOURCE_RESOLUTION, errorMsg, + "Wrong input value was set.") } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with : (${e.message})", e) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt index 5d9226876..7596d7d8c 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt @@ -1,6 +1,6 @@ /* - * Copyright © 2018 IBM. - * Modifications Copyright © 2017-2019 AT&T, Bell Canada + * Copyright © 2018 - 2020 IBM. + * Modifications Copyright © 2017-2020 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. @@ -22,10 +22,12 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.Rest import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceDomains import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException -import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.KeyIdentifier import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment @@ -76,8 +78,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" } val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping).toMutableMap() - sourceProperties.inputKeyMapping - ?.mapValues { raRuntimeService.getDictionaryStore(it.value) } + inputKeyMapping?.mapValues { raRuntimeService.getDictionaryStore(it.value) } ?.map { KeyIdentifier(it.key, it.value) } ?.let { resourceAssignment.keyIdentifiers.addAll(it) } @@ -114,6 +115,10 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS } // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) + } catch (e: BluePrintProcessorException) { + val errorMsg = "Failed to process REST resource resolution in template key ($resourceAssignment) assignments." + throw e.updateErrorMessage(ExecutionServiceDomains.RESOURCE_RESOLUTION, errorMsg, + "Wrong resource definition or resolution failed.") } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", e) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt index 7bb757b8e..497b26803 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt @@ -39,6 +39,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty import org.onap.ccsdk.cds.controllerblueprints.core.rootFieldsToMap import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonReactorUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.PropertyDefinitionUtils.Companion.hasLogProtect @@ -127,6 +128,32 @@ class ResourceAssignmentUtils { raRuntimeService.putResolutionStore(resourceAssignment.name, value) raRuntimeService.putDictionaryStore(resourceAssignment.dictionaryName!!, value) resourceAssignment.property!!.value = value + + val metadata = resourceAssignment.property?.metadata + metadata?.get(ResourceResolutionConstants.METADATA_TRANSFORM_TEMPLATE) + ?.let { if (it.contains("$")) it else null } + ?.let { template -> + val resolutionStore = raRuntimeService.getResolutionStore() + .mapValues { e -> e.value.asText() } as MutableMap<String, Any> + val newValue: JsonNode + try { + newValue = BluePrintVelocityTemplateService + .generateContent(template, null, true, resolutionStore) + .also { if (hasLogProtect(metadata)) + logger.info("Transformed value: $resourceAssignment.name") + else + logger.info("Transformed value: $value -> $it") } + .let { v -> v.asJsonType() } + } catch (e: Exception) { + throw BluePrintProcessorException( + "transform-template failed: $template", e) + } + with(resourceAssignment) { + raRuntimeService.putResolutionStore(this.name, newValue) + raRuntimeService.putDictionaryStore(this.dictionaryName!!, newValue) + this.property!!.value = newValue + } + } } fun setFailedResourceDataValue(resourceAssignment: ResourceAssignment, message: String?) { @@ -203,18 +230,40 @@ class ResourceAssignmentUtils { resourceAssignments: List<ResourceAssignment>, resourceDefinitions: Map<String, ResourceDefinition> ): String { + val emptyTextNode = TextNode.valueOf("") val resolutionSummaryList = resourceAssignments.map { val definition = resourceDefinitions[it.name] - val payload = definition?.sources?.get(it.dictionarySource) + val description = definition?.property?.description ?: "" + val value = it.property?.value + ?.let { v -> if (v.isNullOrMissing()) emptyTextNode else v } + ?: emptyTextNode + + var payload: JsonNode = definition?.sources?.get(it.dictionarySource) ?.properties?.get("resolved-payload") + ?.let { p -> if (p.isNullOrMissing()) emptyTextNode else p } + ?: emptyTextNode + val metadata = definition?.property?.metadata ?.map { e -> DictionaryMetadataEntry(e.key, e.value) } ?.toMutableList() ?: mutableListOf() - val description = definition?.property?.description + + val keyIdentifiers: MutableList<KeyIdentifier> = it.keyIdentifiers.map { k -> + if (k.value.isNullOrMissing()) KeyIdentifier(k.name, emptyTextNode) else k + }.toMutableList() + ResolutionSummary( - it.name, it.property?.value, it.property?.required, it.property?.type, - it.keyIdentifiers, description, metadata, it.dictionaryName, - it.dictionarySource, payload, it.status, it.message + it.name, + value, + it.property?.required ?: false, + it.property?.type ?: "", + keyIdentifiers, + description, + metadata, + it.dictionaryName ?: "", + it.dictionarySource ?: "", + payload, + it.status ?: "", + it.message ?: "" ) } // Wrapper needed for integration with SDNC diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt index 9df8fb7d7..7746b5c41 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Test import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.METADATA_TRANSFORM_TEMPLATE import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType @@ -180,8 +181,8 @@ class ResourceAssignmentUtilsTest { "resolution-summary":[ { "name":"pnf-id", - "value":null, - "required":null, + "value":"", + "required":false, "type":"string", "key-identifiers":[], "dictionary-description":"pnf-id", @@ -191,8 +192,8 @@ class ResourceAssignmentUtilsTest { "dictionary-name":"pnf-id", "dictionary-source":"input", "request-payload":{"mock":true}, - "status":null, - "message":null + "status":"", + "message":"" } ] } @@ -333,6 +334,26 @@ class ResourceAssignmentUtilsTest { ) } + @Test + fun `transform resolved value with inline template`() { + resourceAssignmentRuntimeService.putResolutionStore("vnf_name", "abc-vnf".asJsonType()) + resourceAssignment = ResourceAssignment() + resourceAssignment.name = "int_pktgen_private_net_id" + resourceAssignment.property = PropertyDefinition() + resourceAssignment.property!!.type = "string" + val value = "".asJsonType() + + // Enable transform template + resourceAssignment.property!!.metadata = + mutableMapOf(METADATA_TRANSFORM_TEMPLATE to "\${vnf_name}_private2") + + ResourceAssignmentUtils + .setResourceDataValue(resourceAssignment, resourceAssignmentRuntimeService, value) + + assertEquals("abc-vnf_private2", + resourceAssignment.property!!.value!!.asText()) + } + private fun initInputMapAndExpectedValuesForPrimitiveType() { inputMapToTestPrimitiveTypeWithValue = "1.2.3.1".asJsonType() val keyValue = mutableMapOf<String, String>() diff --git a/ms/blueprintsprocessor/functions/restconf-executor/pom.xml b/ms/blueprintsprocessor/functions/restconf-executor/pom.xml index 8208f5f4e..fdc72b2bd 100644 --- a/ms/blueprintsprocessor/functions/restconf-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/restconf-executor/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>restconf-executor</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <name>Blueprints Processor Function - Restconf Executor</name> <description>Blueprints Processor Function - Restconf Executor</description> diff --git a/ms/blueprintsprocessor/functions/restful-executor/pom.xml b/ms/blueprintsprocessor/functions/restful-executor/pom.xml index fa4acf641..f5dce168e 100644 --- a/ms/blueprintsprocessor/functions/restful-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/restful-executor/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>functions</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml index def1ed0b3..6f0791c4e 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprints</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>blueprint-core</artifactId> diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt index acb158d89..310c9b05b 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintProcessorException.kt @@ -17,6 +17,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core +import org.apache.commons.lang.exception.ExceptionUtils import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogException import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogExceptionFluent import org.onap.ccsdk.cds.error.catalog.core.ErrorMessage @@ -56,6 +57,14 @@ open class BluePrintProcessorException : ErrorCatalogException, ErrorCatalogExce return this.updateGrpc(type) } + override fun convertToHttp(): BluePrintProcessorException { + return this.inverseToHttp() + } + + override fun convertToGrpc(): BluePrintProcessorException { + return this.inverseToHttp() + } + override fun payloadMessage(message: String): BluePrintProcessorException { return this.updatePayloadMessage(message) } @@ -82,10 +91,26 @@ fun processorException(message: String): BluePrintProcessorException { return BluePrintProcessorException(message) } +fun processorException(message: String, cause: Throwable): BluePrintProcessorException { + return BluePrintProcessorException(message, cause) +} + +fun processorException(cause: Throwable, message: String, vararg args: Any?): BluePrintProcessorException { + return BluePrintProcessorException(cause, message, args) +} + fun processorException(code: Int, message: String): BluePrintProcessorException { return processorException(message).code(code) } +fun processorException(code: Int, message: String, cause: Throwable): BluePrintProcessorException { + return processorException(message, cause).code(code) +} + +fun processorException(code: Int, cause: Throwable, message: String, vararg args: Any?): BluePrintProcessorException { + return processorException(cause, message, args).code(code) +} + fun httpProcessorException(type: String, message: String): BluePrintProcessorException { return processorException(message).http(type) } @@ -106,17 +131,29 @@ fun grpcProcessorException(type: String, domain: String, message: String): BlueP fun httpProcessorException(type: String, domain: String, message: String, cause: Throwable): BluePrintProcessorException { - val bluePrintProcessorException = processorException(message).http(type) - return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, cause) + val bluePrintProcessorException = processorException(message, cause).http(type) + return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, ExceptionUtils.getRootCauseMessage(cause)) } fun grpcProcessorException(type: String, domain: String, message: String, cause: Throwable): BluePrintProcessorException { - val bluePrintProcessorException = processorException(message).grpc(type) - return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, cause) + val bluePrintProcessorException = processorException(message, cause).grpc(type) + return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, ExceptionUtils.getRootCauseMessage(cause)) +} + +fun httpProcessorException(type: String, domain: String, message: String, cause: Throwable, vararg args: Any?): + BluePrintProcessorException { + val bluePrintProcessorException = processorException(cause, message, args).http(type) + return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, ExceptionUtils.getRootCauseMessage(cause)) +} + +fun grpcProcessorException(type: String, domain: String, message: String, cause: Throwable, vararg args: Any?): + BluePrintProcessorException { + val bluePrintProcessorException = processorException(cause, message, args).grpc(type) + return bluePrintProcessorException.addDomainAndErrorMessage(domain, message, ExceptionUtils.getRootCauseMessage(cause)) } -fun BluePrintProcessorException.updateErrorMessage(domain: String, message: String, cause: Throwable): +fun BluePrintProcessorException.updateErrorMessage(domain: String, message: String, cause: String): BluePrintProcessorException { return this.addDomainAndErrorMessage(domain, message, cause).domain(domain) .addErrorPayloadMessage(message) @@ -132,8 +169,7 @@ fun BluePrintProcessorException.updateErrorMessage(domain: String, message: Stri private fun BluePrintProcessorException.addDomainAndErrorMessage( domain: String, message: String, - cause: Throwable = Throwable() + cause: String = "" ): BluePrintProcessorException { - return this.addSubError(ErrorMessage(domain, message, cause.message - ?: "")).domain(domain) + return this.addSubError(ErrorMessage(domain, message, cause)).domain(domain) } diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-proto/pom.xml b/ms/blueprintsprocessor/modules/blueprints/blueprint-proto/pom.xml index 11ce0e27c..b71085f3d 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-proto/pom.xml +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-proto/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprints</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>blueprint-proto</artifactId> diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-validation/pom.xml b/ms/blueprintsprocessor/modules/blueprints/blueprint-validation/pom.xml index 0a5818ecd..d87f25a3c 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-validation/pom.xml +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-validation/pom.xml @@ -16,13 +16,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprints</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>blueprint-validation</artifactId> diff --git a/ms/blueprintsprocessor/modules/blueprints/pom.xml b/ms/blueprintsprocessor/modules/blueprints/pom.xml index 0ea6a1eee..a2b19ccec 100644 --- a/ms/blueprintsprocessor/modules/blueprints/pom.xml +++ b/ms/blueprintsprocessor/modules/blueprints/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>modules</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>blueprints</artifactId> diff --git a/ms/blueprintsprocessor/modules/blueprints/resource-dict/pom.xml b/ms/blueprintsprocessor/modules/blueprints/resource-dict/pom.xml index c26301a5a..6fa99c0fb 100644 --- a/ms/blueprintsprocessor/modules/blueprints/resource-dict/pom.xml +++ b/ms/blueprintsprocessor/modules/blueprints/resource-dict/pom.xml @@ -16,13 +16,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprints</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>resource-dict</artifactId> diff --git a/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt b/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt index 77025c5a4..70f151b66 100644 --- a/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt +++ b/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt @@ -112,25 +112,25 @@ data class DictionaryMetadataEntry(val name: String, val value: String) */ data class ResolutionSummary( val name: String, - val value: JsonNode?, - val required: Boolean?, - val type: String?, + val value: JsonNode, + val required: Boolean, + val type: String, @JsonProperty("key-identifiers") val keyIdentifiers: MutableList<KeyIdentifier>, @JsonProperty("dictionary-description") - val dictionaryDescription: String?, + val dictionaryDescription: String, @JsonProperty("dictionary-metadata") val dictionaryMetadata: MutableList<DictionaryMetadataEntry>, @JsonProperty("dictionary-name") - val dictionaryName: String?, + val dictionaryName: String, @JsonProperty("dictionary-source") - val dictionarySource: String?, + val dictionarySource: String, @JsonProperty("request-payload") - val requestPayload: JsonNode?, + val requestPayload: JsonNode, @JsonProperty("status") - val status: String?, + val status: String, @JsonProperty("message") - val message: String? + val message: String ) /** * Interface for Source Definitions (ex Input Source, diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/db-lib/pom.xml index c91cb5351..71ef22062 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/db-lib/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>db-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt index 0d737f4ca..637031972 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt @@ -66,7 +66,7 @@ class DBLibConstants { // list of database const val MARIA_DB: String = "maria-db" - const val PRIMARY_DB: String = "processor-db" + const val PROCESSOR_DB: String = "processor-db" const val MYSQL_DB: String = "mysql-db" const val ORACLE_DB: String = "oracle-db" const val POSTGRES_DB: String = "postgres-db" diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt index 35baf9314..e686e8396 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt @@ -20,10 +20,11 @@ import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertiesService import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibGenericService import org.onap.ccsdk.cds.blueprintsprocessor.db.DBDataSourceProperties -import org.onap.ccsdk.cds.blueprintsprocessor.db.DBLibConstants +import org.onap.ccsdk.cds.blueprintsprocessor.db.DBLibConstants.Companion.MARIA_DB +import org.onap.ccsdk.cds.blueprintsprocessor.db.DBLibConstants.Companion.MYSQL_DB +import org.onap.ccsdk.cds.blueprintsprocessor.db.DBLibConstants.Companion.PROCESSOR_DB import org.onap.ccsdk.cds.blueprintsprocessor.db.MariaDataSourceProperties import org.onap.ccsdk.cds.blueprintsprocessor.db.MySqlDataSourceProperties -import org.onap.ccsdk.cds.blueprintsprocessor.db.PrimaryDataSourceProperties import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.springframework.stereotype.Service @@ -31,79 +32,45 @@ import org.springframework.stereotype.Service @Service class BluePrintDBLibPropertyService(private var bluePrintPropertiesService: BluePrintPropertiesService) { - fun JdbcTemplate(jsonNode: JsonNode): BluePrintDBLibGenericService { - val dBConnetionProperties = dBDataSourceProperties(jsonNode) - return blueprintDBDataSourceService(dBConnetionProperties) - } + fun JdbcTemplate(jsonNode: JsonNode): BluePrintDBLibGenericService = + blueprintDBDataSourceService(dBDataSourceProperties(jsonNode)) - fun JdbcTemplate(selector: String): BluePrintDBLibGenericService { - val prefix = "blueprintsprocessor.db.$selector" - val dBConnetionProperties = dBDataSourceProperties(prefix) - return blueprintDBDataSourceService(dBConnetionProperties) - } + fun JdbcTemplate(selector: String): BluePrintDBLibGenericService = + blueprintDBDataSourceService(dBDataSourceProperties("blueprintsprocessor.db.$selector")) - private fun dBDataSourceProperties(jsonNode: JsonNode): DBDataSourceProperties { - val type = jsonNode.get("type").textValue() - return when (type) { - DBLibConstants.MYSQL_DB -> { - JacksonUtils.readValue(jsonNode, MySqlDataSourceProperties::class.java)!! - } - DBLibConstants.MARIA_DB -> { - JacksonUtils.readValue(jsonNode, MariaDataSourceProperties::class.java)!! - } - else -> { - throw BluePrintProcessorException("Rest adaptor($type) is not supported") - } - } - } + private fun dBDataSourceProperties(jsonNode: JsonNode): DBDataSourceProperties = + when (val type = jsonNode.get("type").textValue()) { + MYSQL_DB -> JacksonUtils.readValue(jsonNode, MySqlDataSourceProperties::class.java) + MARIA_DB -> JacksonUtils.readValue(jsonNode, MariaDataSourceProperties::class.java) + else -> { + throw BluePrintProcessorException( + "DB type ($type) is not supported. Valid types: $MARIA_DB, $MYSQL_DB") + } + }!! - private fun dBDataSourceProperties(prefix: String): DBDataSourceProperties { - val type = bluePrintPropertiesService.propertyBeanType("$prefix.type", String::class.java) - return when (type) { - DBLibConstants.MARIA_DB -> { - mariaDBConnectionProperties(prefix) - } - DBLibConstants.MYSQL_DB -> { - mySqlDBConnectionProperties(prefix) - } - DBLibConstants.ORACLE_DB -> { - TODO("not implemented") - } - DBLibConstants.POSTGRES_DB -> { - TODO("not implemented") + private fun dBDataSourceProperties(prefix: String): DBDataSourceProperties = + bluePrintPropertiesService.propertyBeanType("$prefix.type", String::class.java).let { + return when (it) { + MARIA_DB, PROCESSOR_DB -> mariaDBConnectionProperties(prefix) + MYSQL_DB -> mySqlDBConnectionProperties(prefix) + else -> { + throw BluePrintProcessorException( + "DB type ($it) is not supported. Valid types: $MARIA_DB, $MYSQL_DB, $PROCESSOR_DB") + } + } } - DBLibConstants.PRIMARY_DB -> { - primaryDBConnectionProperties(prefix) - } - else -> { - throw BluePrintProcessorException("Rest adaptor($type) is not supported") - } - } - } - private fun blueprintDBDataSourceService(dBConnetionProperties: DBDataSourceProperties): BluePrintDBLibGenericService { - when (dBConnetionProperties) { - is MariaDataSourceProperties -> { - return MariaDatabaseConfiguration(dBConnetionProperties) - } - is MySqlDataSourceProperties -> { - return MySqlDatabaseConfiguration(dBConnetionProperties) + private fun blueprintDBDataSourceService(dBConnetionProperties: DBDataSourceProperties): BluePrintDBLibGenericService = + when (dBConnetionProperties) { + is MariaDataSourceProperties -> MariaDatabaseConfiguration(dBConnetionProperties) + is MySqlDataSourceProperties -> MySqlDatabaseConfiguration(dBConnetionProperties) + else -> throw BluePrintProcessorException( + "Failed to create db configuration for ${dBConnetionProperties.url}") } - else -> { - throw BluePrintProcessorException("couldn't get rest service for") - } - } - } - - private fun mySqlDBConnectionProperties(prefix: String): MySqlDataSourceProperties { - return bluePrintPropertiesService.propertyBeanType(prefix, MySqlDataSourceProperties::class.java) - } - private fun mariaDBConnectionProperties(prefix: String): MariaDataSourceProperties { - return bluePrintPropertiesService.propertyBeanType(prefix, MariaDataSourceProperties::class.java) - } + private fun mySqlDBConnectionProperties(prefix: String): MySqlDataSourceProperties = + bluePrintPropertiesService.propertyBeanType(prefix, MySqlDataSourceProperties::class.java) - private fun primaryDBConnectionProperties(prefix: String): PrimaryDataSourceProperties { - return bluePrintPropertiesService.propertyBeanType(prefix, PrimaryDataSourceProperties::class.java) - } + private fun mariaDBConnectionProperties(prefix: String): MariaDataSourceProperties = + bluePrintPropertiesService.propertyBeanType(prefix, MariaDataSourceProperties::class.java) } diff --git a/ms/blueprintsprocessor/modules/commons/dmaap-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/dmaap-lib/pom.xml index a2fd4985a..2e54d3c51 100644 --- a/ms/blueprintsprocessor/modules/commons/dmaap-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/dmaap-lib/pom.xml @@ -18,13 +18,14 @@ ~ limitations under the License. ~ ============LICENSE_END========================================================= --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>dmaap-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml index 30067fb4e..af20c5d08 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>grpc-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml index 04dd73688..cf287e280 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>message-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt index cc4c7fa4a..c6587c799 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt @@ -61,6 +61,10 @@ class MessageLibConstants { const val PROPERTY_MESSAGE_CONSUMER_PREFIX = "blueprintsprocessor.messageconsumer." const val PROPERTY_MESSAGE_PRODUCER_PREFIX = "blueprintsprocessor.messageproducer." const val TYPE_KAFKA_BASIC_AUTH = "kafka-basic-auth" + const val TYPE_KAFKA_SCRAM_SSL_AUTH = "kafka-scram-ssl-auth" + const val TYPE_KAFKA_SSL_AUTH = "kafka-ssl-auth" const val TYPE_KAFKA_STREAMS_BASIC_AUTH = "kafka-streams-basic-auth" + const val TYPE_KAFKA_STREAMS_SSL_AUTH = "kafka-streams-ssl-auth" + const val TYPE_KAFKA_STREAMS_SCRAM_SSL_AUTH = "kafka-streams-scram-ssl-auth" } } diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt index 005223d9b..ac35fbf2c 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt @@ -17,49 +17,238 @@ package org.onap.ccsdk.cds.blueprintsprocessor.message +import org.apache.kafka.clients.CommonClientConfigs +import org.apache.kafka.clients.consumer.ConsumerConfig +import org.apache.kafka.clients.producer.ProducerConfig +import org.apache.kafka.common.config.SaslConfigs +import org.apache.kafka.common.config.SslConfigs +import org.apache.kafka.common.security.auth.SecurityProtocol +import org.apache.kafka.common.security.scram.ScramLoginModule +import org.apache.kafka.common.serialization.ByteArrayDeserializer +import org.apache.kafka.common.serialization.ByteArraySerializer +import org.apache.kafka.common.serialization.StringDeserializer +import org.apache.kafka.common.serialization.StringSerializer import org.apache.kafka.streams.StreamsConfig -/** Producer Properties **/ -open class MessageProducerProperties { +/** Common Properties **/ +abstract class CommonProperties { lateinit var type: String + lateinit var topic: String + lateinit var bootstrapServers: String + + open fun getConfig(): HashMap<String, Any> { + val configProps = hashMapOf<String, Any>() + configProps[ProducerConfig.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers + return configProps + } } +/** Message Producer */ +/** Message Producer Properties **/ +abstract class MessageProducerProperties : CommonProperties() + +/** Basic Auth */ open class KafkaBasicAuthMessageProducerProperties : MessageProducerProperties() { - lateinit var bootstrapServers: String - var topic: String? = null + var clientId: String? = null // strongest producing guarantee var acks: String = "all" var retries: Int = 0 // ensure we don't push duplicates var enableIdempotence: Boolean = true + + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java + configProps[ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG] = ByteArraySerializer::class.java + configProps[ProducerConfig.ACKS_CONFIG] = acks + configProps[ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG] = enableIdempotence + if (clientId != null) { + configProps[ProducerConfig.CLIENT_ID_CONFIG] = clientId!! + } + return configProps + } } -/** Consumer Properties **/ +/** SSL Auth */ +open class KafkaSslAuthMessageProducerProperties : KafkaBasicAuthMessageProducerProperties() { + lateinit var truststore: String + lateinit var truststorePassword: String + var truststoreType: String = SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE + var keystore: String? = null + var keystorePassword: String? = null + var keystoreType: String = SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE + var sslEndpointIdentificationAlgorithm: String = "" -open class MessageConsumerProperties { - lateinit var type: String + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[CommonClientConfigs.SECURITY_PROTOCOL_CONFIG] = SecurityProtocol.SSL.toString() + configProps[SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG] = truststoreType + configProps[SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG] = truststore!! + configProps[SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG] = truststorePassword!! + if (keystore != null) { + configProps[SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG] = keystore!! + configProps[SslConfigs.SSL_KEYSTORE_TYPE_CONFIG] = keystoreType + configProps[SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG] = keystorePassword!! + } + configProps[SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG] = sslEndpointIdentificationAlgorithm + + return configProps + } } -open class KafkaStreamsConsumerProperties : MessageConsumerProperties() { - lateinit var bootstrapServers: String +/** (SASL) SCRAM SSL Auth */ +class KafkaScramSslAuthMessageProducerProperties : KafkaSslAuthMessageProducerProperties() { + var saslMechanism: String = "SCRAM-SHA-512" + lateinit var scramUsername: String + lateinit var scramPassword: String + + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[CommonClientConfigs.SECURITY_PROTOCOL_CONFIG] = SecurityProtocol.SASL_SSL.toString() + configProps[SaslConfigs.SASL_MECHANISM] = saslMechanism + configProps[SaslConfigs.SASL_JAAS_CONFIG] = "${ScramLoginModule::class.java.canonicalName} required " + + "username=\"${scramUsername}\" " + + "password=\"${scramPassword}\";" + return configProps + } +} + +/** Consumer */ +abstract class MessageConsumerProperties : CommonProperties() +/** Kafka Streams */ +/** Streams properties */ + +/** Basic Auth */ +open class KafkaStreamsBasicAuthConsumerProperties : MessageConsumerProperties() { lateinit var applicationId: String - lateinit var topic: String var autoOffsetReset: String = "latest" var processingGuarantee: String = StreamsConfig.EXACTLY_ONCE + + override fun getConfig(): HashMap<String, Any> { + val configProperties = super.getConfig() + configProperties[StreamsConfig.APPLICATION_ID_CONFIG] = applicationId + configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = autoOffsetReset + configProperties[StreamsConfig.PROCESSING_GUARANTEE_CONFIG] = processingGuarantee + return configProperties + } } -open class KafkaStreamsBasicAuthConsumerProperties : KafkaStreamsConsumerProperties() +/** SSL Auth */ +open class KafkaStreamsSslAuthConsumerProperties : KafkaStreamsBasicAuthConsumerProperties() { + lateinit var truststore: String + lateinit var truststorePassword: String + var truststoreType: String = SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE + var keystore: String? = null + var keystorePassword: String? = null + var keystoreType: String = SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE + var sslEndpointIdentificationAlgorithm: String = "" -open class KafkaMessageConsumerProperties : MessageConsumerProperties() { - lateinit var bootstrapServers: String + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[CommonClientConfigs.SECURITY_PROTOCOL_CONFIG] = SecurityProtocol.SSL.toString() + configProps[SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG] = truststoreType + configProps[SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG] = truststore!! + configProps[SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG] = truststorePassword!! + if (keystore != null) { + configProps[SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG] = keystore!! + configProps[SslConfigs.SSL_KEYSTORE_TYPE_CONFIG] = keystoreType + configProps[SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG] = keystorePassword!! + } + configProps[SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG] = sslEndpointIdentificationAlgorithm + return configProps + } +} + +/** (SASL) SCRAM SSL Auth */ +class KafkaStreamsScramSslAuthConsumerProperties : KafkaStreamsSslAuthConsumerProperties() { + var saslMechanism: String = "SCRAM-SHA-512" + lateinit var scramUsername: String + lateinit var scramPassword: String + + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[CommonClientConfigs.SECURITY_PROTOCOL_CONFIG] = SecurityProtocol.SASL_SSL.toString() + configProps[SaslConfigs.SASL_MECHANISM] = saslMechanism + configProps[SaslConfigs.SASL_JAAS_CONFIG] = "${ScramLoginModule::class.java.canonicalName} required " + + "username=\"${scramUsername}\" " + + "password=\"${scramPassword}\";" + return configProps + } +} + +/** Message Consumer */ +/** Message Consumer Properties **/ +/** Basic Auth */ +open class KafkaBasicAuthMessageConsumerProperties : MessageConsumerProperties() { lateinit var groupId: String lateinit var clientId: String - var topic: String? = null var autoCommit: Boolean = true var autoOffsetReset: String = "latest" var pollMillSec: Long = 1000 var pollRecords: Int = -1 + + override fun getConfig(): HashMap<String, Any> { + val configProperties = super.getConfig() + configProperties[ConsumerConfig.GROUP_ID_CONFIG] = groupId + configProperties[ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG] = autoCommit + /** + * earliest: automatically reset the offset to the earliest offset + * latest: automatically reset the offset to the latest offset + */ + configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = autoOffsetReset + configProperties[ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java + configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = ByteArrayDeserializer::class.java + configProperties[ConsumerConfig.CLIENT_ID_CONFIG] = clientId + + /** To handle Back pressure, Get only configured record for processing */ + if (pollRecords > 0) { + configProperties[ConsumerConfig.MAX_POLL_RECORDS_CONFIG] = pollRecords + } + + return configProperties + } } -open class KafkaBasicAuthMessageConsumerProperties : KafkaMessageConsumerProperties() +/** SSL Auth */ +open class KafkaSslAuthMessageConsumerProperties : KafkaBasicAuthMessageConsumerProperties() { + lateinit var truststore: String + lateinit var truststorePassword: String + var truststoreType: String = SslConfigs.DEFAULT_SSL_TRUSTSTORE_TYPE + var keystore: String? = null + var keystorePassword: String? = null + var keystoreType: String = SslConfigs.DEFAULT_SSL_KEYSTORE_TYPE + var sslEndpointIdentificationAlgorithm: String = "" + + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[CommonClientConfigs.SECURITY_PROTOCOL_CONFIG] = SecurityProtocol.SSL.toString() + configProps[SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG] = truststoreType + configProps[SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG] = truststore!! + configProps[SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG] = truststorePassword!! + if (keystore != null) { + configProps[SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG] = keystore!! + configProps[SslConfigs.SSL_KEYSTORE_TYPE_CONFIG] = keystoreType + configProps[SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG] = keystorePassword!! + } + configProps[SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG] = sslEndpointIdentificationAlgorithm + return configProps + } +} + +/** (SASL) SCRAM SSL Auth */ +class KafkaScramSslAuthMessageConsumerProperties : KafkaSslAuthMessageConsumerProperties() { + var saslMechanism: String = "SCRAM-SHA-512" + lateinit var scramUsername: String + lateinit var scramPassword: String + + override fun getConfig(): HashMap<String, Any> { + val configProps = super.getConfig() + configProps[CommonClientConfigs.SECURITY_PROTOCOL_CONFIG] = SecurityProtocol.SASL_SSL.toString() + configProps[SaslConfigs.SASL_MECHANISM] = saslMechanism + configProps[SaslConfigs.SASL_JAAS_CONFIG] = "${ScramLoginModule::class.java.canonicalName} required " + + "username=\"${scramUsername}\" " + + "password=\"${scramPassword}\";" + return configProps + } +} diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSL.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSL.kt index 88039466d..c659fdb8b 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSL.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSL.kt @@ -99,6 +99,20 @@ class MessageProducerRelationshipTemplateBuilder(name: String, description: Stri BluePrintTypes.kafkaBasicAuthMessageProducerProperties(block) ) } + + fun kafkaSslAuth(block: KafkaSslAuthMessageProducerPropertiesAssignmentBuilder.() -> Unit) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintTypes.kafkaSslAuthMessageProducerProperties(block) + ) + } + + fun kafkaScramSslAuth(block: KafkaScramSslAuthMessageProducerPropertiesAssignmentBuilder.() -> Unit) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintTypes.kafkaScramSslAuthMessageProducerProperties(block) + ) + } } fun BluePrintTypes.kafkaBasicAuthMessageProducerProperties(block: KafkaBasicAuthMessageProducerPropertiesAssignmentBuilder.() -> Unit): JsonNode { @@ -108,9 +122,23 @@ fun BluePrintTypes.kafkaBasicAuthMessageProducerProperties(block: KafkaBasicAuth return assignments.asJsonType() } +fun BluePrintTypes.kafkaSslAuthMessageProducerProperties(block: KafkaSslAuthMessageProducerPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = KafkaSslAuthMessageProducerPropertiesAssignmentBuilder().apply(block).build() + assignments[KafkaSslAuthMessageProducerProperties::type.name] = + MessageLibConstants.TYPE_KAFKA_SSL_AUTH.asJsonPrimitive() + return assignments.asJsonType() +} + +fun BluePrintTypes.kafkaScramSslAuthMessageProducerProperties(block: KafkaScramSslAuthMessageProducerPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = KafkaScramSslAuthMessageProducerPropertiesAssignmentBuilder().apply(block).build() + assignments[KafkaScramSslAuthMessageProducerProperties::type.name] = + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH.asJsonPrimitive() + return assignments.asJsonType() +} + open class MessageProducerPropertiesAssignmentBuilder : PropertiesAssignmentBuilder() -class KafkaBasicAuthMessageProducerPropertiesAssignmentBuilder : MessageProducerPropertiesAssignmentBuilder() { +open class KafkaBasicAuthMessageProducerPropertiesAssignmentBuilder : MessageProducerPropertiesAssignmentBuilder() { fun bootstrapServers(bootstrapServers: String) = bootstrapServers(bootstrapServers.asJsonPrimitive()) @@ -141,6 +169,61 @@ class KafkaBasicAuthMessageProducerPropertiesAssignmentBuilder : MessageProducer property(KafkaBasicAuthMessageProducerProperties::enableIdempotence, enableIdempotence) } +open class KafkaSslAuthMessageProducerPropertiesAssignmentBuilder : KafkaBasicAuthMessageProducerPropertiesAssignmentBuilder() { + fun truststore(truststore: String) = truststore(truststore.asJsonPrimitive()) + + fun truststore(truststore: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::truststore, truststore) + + fun truststorePassword(truststorePassword: String) = truststorePassword(truststorePassword.asJsonPrimitive()) + + fun truststorePassword(truststorePassword: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::truststorePassword, truststorePassword) + + fun truststoreType(truststoreType: String) = truststoreType(truststoreType.asJsonPrimitive()) + + fun truststoreType(truststoreType: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::truststoreType, truststoreType) + + fun keystore(keystore: String) = keystore(keystore.asJsonPrimitive()) + + fun keystore(keystore: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystore, keystore) + + fun keystorePassword(keystorePassword: String) = keystorePassword(keystorePassword.asJsonPrimitive()) + + fun keystorePassword(keystorePassword: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystorePassword, keystorePassword) + + fun keystoreType(keystoreType: String) = keystoreType(keystoreType.asJsonPrimitive()) + + fun keystoreType(keystoreType: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystoreType, keystoreType) + + fun sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm: String) = + sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm.asJsonPrimitive()) + + fun sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::sslEndpointIdentificationAlgorithm, sslEndpointIdentificationAlgorithm) +} + +class KafkaScramSslAuthMessageProducerPropertiesAssignmentBuilder : KafkaSslAuthMessageProducerPropertiesAssignmentBuilder() { + fun saslMechanism(saslMechanism: String) = saslMechanism(saslMechanism.asJsonPrimitive()) + + fun saslMechanism(saslMechanism: JsonNode) = + property(KafkaScramSslAuthMessageProducerProperties::saslMechanism, saslMechanism) + + fun scramUsername(scramUsername: String) = scramUsername(scramUsername.asJsonPrimitive()) + + fun scramUsername(scramUsername: JsonNode) = + property(KafkaScramSslAuthMessageProducerProperties::scramUsername, scramUsername) + + fun scramPassword(scramPassword: String) = scramPassword(scramPassword.asJsonPrimitive()) + + fun scramPassword(scramPassword: JsonNode) = + property(KafkaScramSslAuthMessageProducerProperties::scramPassword, scramPassword) +} + /** Relationships Templates DSL for Message Consumer */ fun TopologyTemplateBuilder.relationshipTemplateMessageConsumer( name: String, @@ -166,12 +249,40 @@ class MessageConsumerRelationshipTemplateBuilder(name: String, description: Stri ) } + fun kafkaSslAuth(block: KafkaSslAuthMessageConsumerPropertiesAssignmentBuilder.() -> Unit) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintTypes.kafkaSslAuthMessageConsumerProperties(block) + ) + } + + fun kafkaScramSslAuth(block: KafkaScramSslAuthMessageConsumerPropertiesAssignmentBuilder.() -> Unit) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintTypes.kafkaScramSslAuthMessageConsumerProperties(block) + ) + } + fun kafkaStreamsBasicAuth(block: KafkaStreamsBasicAuthConsumerPropertiesAssignmentBuilder.() -> Unit) { property( BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.kafkaStreamsBasicAuthConsumerProperties(block) ) } + + fun kafkaStreamsSslAuth(block: KafkaStreamsSslAuthConsumerPropertiesAssignmentBuilder.() -> Unit) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintTypes.kafkaStreamsSslAuthConsumerProperties(block) + ) + } + + fun kafkaStreamsScramSslAuth(block: KafkaStreamsScramSslAuthConsumerPropertiesAssignmentBuilder.() -> Unit) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintTypes.kafkaStreamsScramSslAuthConsumerProperties(block) + ) + } } fun BluePrintTypes.kafkaBasicAuthMessageConsumerProperties(block: KafkaBasicAuthMessageConsumerPropertiesAssignmentBuilder.() -> Unit): JsonNode { @@ -181,6 +292,20 @@ fun BluePrintTypes.kafkaBasicAuthMessageConsumerProperties(block: KafkaBasicAuth return assignments.asJsonType() } +fun BluePrintTypes.kafkaSslAuthMessageConsumerProperties(block: KafkaSslAuthMessageConsumerPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = KafkaSslAuthMessageConsumerPropertiesAssignmentBuilder().apply(block).build() + assignments[KafkaSslAuthMessageConsumerProperties::type.name] = + MessageLibConstants.TYPE_KAFKA_SSL_AUTH.asJsonPrimitive() + return assignments.asJsonType() +} + +fun BluePrintTypes.kafkaScramSslAuthMessageConsumerProperties(block: KafkaScramSslAuthMessageConsumerPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = KafkaScramSslAuthMessageConsumerPropertiesAssignmentBuilder().apply(block).build() + assignments[KafkaScramSslAuthMessageConsumerProperties::type.name] = + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH.asJsonPrimitive() + return assignments.asJsonType() +} + fun BluePrintTypes.kafkaStreamsBasicAuthConsumerProperties(block: KafkaStreamsBasicAuthConsumerPropertiesAssignmentBuilder.() -> Unit): JsonNode { val assignments = KafkaStreamsBasicAuthConsumerPropertiesAssignmentBuilder().apply(block).build() assignments[KafkaStreamsBasicAuthConsumerProperties::type.name] = @@ -188,81 +313,201 @@ fun BluePrintTypes.kafkaStreamsBasicAuthConsumerProperties(block: KafkaStreamsBa return assignments.asJsonType() } +fun BluePrintTypes.kafkaStreamsSslAuthConsumerProperties(block: KafkaStreamsSslAuthConsumerPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = KafkaStreamsSslAuthConsumerPropertiesAssignmentBuilder().apply(block).build() + assignments[KafkaStreamsSslAuthConsumerProperties::type.name] = + MessageLibConstants.TYPE_KAFKA_STREAMS_SSL_AUTH.asJsonPrimitive() + return assignments.asJsonType() +} + +fun BluePrintTypes.kafkaStreamsScramSslAuthConsumerProperties(block: KafkaStreamsScramSslAuthConsumerPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = KafkaStreamsScramSslAuthConsumerPropertiesAssignmentBuilder().apply(block).build() + assignments[KafkaStreamsScramSslAuthConsumerProperties::type.name] = + MessageLibConstants.TYPE_KAFKA_STREAMS_SCRAM_SSL_AUTH.asJsonPrimitive() + return assignments.asJsonType() +} + open class MessageConsumerPropertiesAssignmentBuilder : PropertiesAssignmentBuilder() -open class KafkaMessageConsumerPropertiesAssignmentBuilder : MessageConsumerPropertiesAssignmentBuilder() { +/** KafkaBasicAuthMessageConsumerProperties assignment builder */ +open class KafkaBasicAuthMessageConsumerPropertiesAssignmentBuilder : MessageConsumerPropertiesAssignmentBuilder() { fun bootstrapServers(bootstrapServers: String) = bootstrapServers(bootstrapServers.asJsonPrimitive()) fun bootstrapServers(bootstrapServers: JsonNode) = - property(KafkaMessageConsumerProperties::bootstrapServers, bootstrapServers) + property(KafkaBasicAuthMessageConsumerProperties::bootstrapServers, bootstrapServers) fun groupId(groupId: String) = groupId(groupId.asJsonPrimitive()) fun groupId(groupId: JsonNode) = - property(KafkaMessageConsumerProperties::groupId, groupId) + property(KafkaBasicAuthMessageConsumerProperties::groupId, groupId) fun clientId(clientId: String) = clientId(clientId.asJsonPrimitive()) fun clientId(clientId: JsonNode) = - property(KafkaMessageConsumerProperties::clientId, clientId) + property(KafkaBasicAuthMessageConsumerProperties::clientId, clientId) fun topic(topic: String) = topic(topic.asJsonPrimitive()) fun topic(topic: JsonNode) = - property(KafkaMessageConsumerProperties::topic, topic) + property(KafkaBasicAuthMessageConsumerProperties::topic, topic) fun autoCommit(autoCommit: Boolean) = autoCommit(autoCommit.asJsonPrimitive()) fun autoCommit(autoCommit: JsonNode) = - property(KafkaMessageConsumerProperties::autoCommit, autoCommit) + property(KafkaBasicAuthMessageConsumerProperties::autoCommit, autoCommit) fun autoOffsetReset(autoOffsetReset: String) = autoOffsetReset(autoOffsetReset.asJsonPrimitive()) fun autoOffsetReset(autoOffsetReset: JsonNode) = - property(KafkaMessageConsumerProperties::autoOffsetReset, autoOffsetReset) + property(KafkaBasicAuthMessageConsumerProperties::autoOffsetReset, autoOffsetReset) fun pollMillSec(pollMillSec: Int) = pollMillSec(pollMillSec.asJsonPrimitive()) fun pollMillSec(pollMillSec: JsonNode) = - property(KafkaMessageConsumerProperties::pollMillSec, pollMillSec) + property(KafkaBasicAuthMessageConsumerProperties::pollMillSec, pollMillSec) fun pollRecords(pollRecords: Int) = pollRecords(pollRecords.asJsonPrimitive()) fun pollRecords(pollRecords: JsonNode) = - property(KafkaMessageConsumerProperties::pollRecords, pollRecords) + property(KafkaBasicAuthMessageConsumerProperties::pollRecords, pollRecords) } -/** KafkaBasicAuthMessageConsumerProperties assignment builder */ -class KafkaBasicAuthMessageConsumerPropertiesAssignmentBuilder : KafkaMessageConsumerPropertiesAssignmentBuilder() +open class KafkaSslAuthMessageConsumerPropertiesAssignmentBuilder : KafkaBasicAuthMessageConsumerPropertiesAssignmentBuilder() { + fun truststore(truststore: String) = truststore(truststore.asJsonPrimitive()) + + fun truststore(truststore: JsonNode) = + property(KafkaSslAuthMessageConsumerProperties::truststore, truststore) + + fun truststorePassword(truststorePassword: String) = truststorePassword(truststorePassword.asJsonPrimitive()) + + fun truststorePassword(truststorePassword: JsonNode) = + property(KafkaSslAuthMessageConsumerProperties::truststorePassword, truststorePassword) + + fun truststoreType(truststoreType: String) = truststoreType(truststoreType.asJsonPrimitive()) + + fun truststoreType(truststoreType: JsonNode) = + property(KafkaSslAuthMessageConsumerProperties::truststoreType, truststoreType) + + fun keystore(keystore: String) = keystore(keystore.asJsonPrimitive()) + + fun keystore(keystore: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystore, keystore) + + fun keystorePassword(keystorePassword: String) = keystorePassword(keystorePassword.asJsonPrimitive()) + + fun keystorePassword(keystorePassword: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystorePassword, keystorePassword) + + fun keystoreType(keystoreType: String) = keystoreType(keystoreType.asJsonPrimitive()) + + fun keystoreType(keystoreType: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystoreType, keystoreType) + + fun sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm: String) = + sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm.asJsonPrimitive()) + + fun sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm: JsonNode) = + property(KafkaSslAuthMessageConsumerProperties::sslEndpointIdentificationAlgorithm, sslEndpointIdentificationAlgorithm) +} + +class KafkaScramSslAuthMessageConsumerPropertiesAssignmentBuilder : KafkaSslAuthMessageConsumerPropertiesAssignmentBuilder() { + fun saslMechanism(saslMechanism: String) = saslMechanism(saslMechanism.asJsonPrimitive()) + + fun saslMechanism(saslMechanism: JsonNode) = + property(KafkaScramSslAuthMessageConsumerProperties::saslMechanism, saslMechanism) + + fun scramUsername(scramUsername: String) = scramUsername(scramUsername.asJsonPrimitive()) + + fun scramUsername(scramUsername: JsonNode) = + property(KafkaScramSslAuthMessageConsumerProperties::scramUsername, scramUsername) + + fun scramPassword(scramPassword: String) = scramPassword(scramPassword.asJsonPrimitive()) + + fun scramPassword(scramPassword: JsonNode) = + property(KafkaScramSslAuthMessageConsumerProperties::scramPassword, scramPassword) +} /** KafkaStreamsConsumerProperties assignment builder */ -open class KafkaStreamsConsumerPropertiesAssignmentBuilder : MessageConsumerPropertiesAssignmentBuilder() { +open class KafkaStreamsBasicAuthConsumerPropertiesAssignmentBuilder : MessageConsumerPropertiesAssignmentBuilder() { fun bootstrapServers(bootstrapServers: String) = bootstrapServers(bootstrapServers.asJsonPrimitive()) fun bootstrapServers(bootstrapServers: JsonNode) = - property(KafkaStreamsConsumerProperties::bootstrapServers, bootstrapServers) + property(KafkaStreamsBasicAuthConsumerProperties::bootstrapServers, bootstrapServers) fun applicationId(applicationId: String) = bootstrapServers(applicationId.asJsonPrimitive()) fun applicationId(applicationId: JsonNode) = - property(KafkaStreamsConsumerProperties::applicationId, applicationId) + property(KafkaStreamsBasicAuthConsumerProperties::applicationId, applicationId) fun topic(topic: String) = topic(topic.asJsonPrimitive()) fun topic(topic: JsonNode) = - property(KafkaStreamsConsumerProperties::topic, topic) + property(KafkaStreamsBasicAuthConsumerProperties::topic, topic) fun autoOffsetReset(autoOffsetReset: String) = autoOffsetReset(autoOffsetReset.asJsonPrimitive()) fun autoOffsetReset(autoOffsetReset: JsonNode) = - property(KafkaStreamsConsumerProperties::autoOffsetReset, autoOffsetReset) + property(KafkaStreamsBasicAuthConsumerProperties::autoOffsetReset, autoOffsetReset) fun processingGuarantee(processingGuarantee: String) = processingGuarantee(processingGuarantee.asJsonPrimitive()) fun processingGuarantee(processingGuarantee: JsonNode) = - property(KafkaStreamsConsumerProperties::processingGuarantee, processingGuarantee) + property(KafkaStreamsBasicAuthConsumerProperties::processingGuarantee, processingGuarantee) } -class KafkaStreamsBasicAuthConsumerPropertiesAssignmentBuilder : KafkaStreamsConsumerPropertiesAssignmentBuilder() +open class KafkaStreamsSslAuthConsumerPropertiesAssignmentBuilder : KafkaStreamsBasicAuthConsumerPropertiesAssignmentBuilder() { + fun truststore(truststore: String) = truststore(truststore.asJsonPrimitive()) + + fun truststore(truststore: JsonNode) = + property(KafkaStreamsSslAuthConsumerProperties::truststore, truststore) + + fun truststorePassword(truststorePassword: String) = truststorePassword(truststorePassword.asJsonPrimitive()) + + fun truststorePassword(truststorePassword: JsonNode) = + property(KafkaStreamsSslAuthConsumerProperties::truststorePassword, truststorePassword) + + fun truststoreType(truststoreType: String) = truststoreType(truststoreType.asJsonPrimitive()) + + fun truststoreType(truststoreType: JsonNode) = + property(KafkaStreamsSslAuthConsumerProperties::truststoreType, truststoreType) + + fun keystore(keystore: String) = keystore(keystore.asJsonPrimitive()) + + fun keystore(keystore: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystore, keystore) + + fun keystorePassword(keystorePassword: String) = keystorePassword(keystorePassword.asJsonPrimitive()) + + fun keystorePassword(keystorePassword: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystorePassword, keystorePassword) + + fun keystoreType(keystoreType: String) = keystoreType(keystoreType.asJsonPrimitive()) + + fun keystoreType(keystoreType: JsonNode) = + property(KafkaSslAuthMessageProducerProperties::keystoreType, keystoreType) + + fun sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm: String) = + sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm.asJsonPrimitive()) + + fun sslEndpointIdentificationAlgorithm(sslEndpointIdentificationAlgorithm: JsonNode) = + property(KafkaStreamsSslAuthConsumerProperties::sslEndpointIdentificationAlgorithm, sslEndpointIdentificationAlgorithm) +} + +class KafkaStreamsScramSslAuthConsumerPropertiesAssignmentBuilder : KafkaStreamsSslAuthConsumerPropertiesAssignmentBuilder() { + fun saslMechanism(saslMechanism: String) = saslMechanism(saslMechanism.asJsonPrimitive()) + + fun saslMechanism(saslMechanism: JsonNode) = + property(KafkaStreamsScramSslAuthConsumerProperties::saslMechanism, saslMechanism) + + fun scramUsername(scramUsername: String) = scramUsername(scramUsername.asJsonPrimitive()) + + fun scramUsername(scramUsername: JsonNode) = + property(KafkaStreamsScramSslAuthConsumerProperties::scramUsername, scramUsername) + + fun scramPassword(scramPassword: String) = scramPassword(scramPassword.asJsonPrimitive()) + + fun scramPassword(scramPassword: JsonNode) = + property(KafkaStreamsScramSslAuthConsumerProperties::scramPassword, scramPassword) +} diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt index 44b50af44..67fbef580 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt @@ -21,7 +21,13 @@ import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertiesService import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageConsumerProperties import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageProducerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaScramSslAuthMessageConsumerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaScramSslAuthMessageProducerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaSslAuthMessageConsumerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaSslAuthMessageProducerProperties import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaStreamsBasicAuthConsumerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaStreamsScramSslAuthConsumerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaStreamsSslAuthConsumerProperties import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageConsumerProperties import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageLibConstants import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageProducerProperties @@ -34,20 +40,32 @@ open class BluePrintMessageLibPropertyService(private var bluePrintPropertiesSer fun blueprintMessageProducerService(jsonNode: JsonNode): BlueprintMessageProducerService { val messageClientProperties = messageProducerProperties(jsonNode) - return blueprintMessageProducerService(messageClientProperties) + return KafkaMessageProducerService(messageClientProperties) } fun blueprintMessageProducerService(selector: String): BlueprintMessageProducerService { val prefix = "${MessageLibConstants.PROPERTY_MESSAGE_PRODUCER_PREFIX}$selector" val messageClientProperties = messageProducerProperties(prefix) - return blueprintMessageProducerService(messageClientProperties) + return KafkaMessageProducerService(messageClientProperties) } fun messageProducerProperties(prefix: String): MessageProducerProperties { val type = bluePrintPropertiesService.propertyBeanType("$prefix.type", String::class.java) return when (type) { MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { - kafkaBasicAuthMessageProducerProperties(prefix) + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaBasicAuthMessageProducerProperties::class.java + ) + } + MessageLibConstants.TYPE_KAFKA_SSL_AUTH -> { + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaSslAuthMessageProducerProperties::class.java + ) + } + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH -> { + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaScramSslAuthMessageProducerProperties::class.java + ) } else -> { throw BluePrintProcessorException("Message adaptor($type) is not supported") @@ -61,31 +79,18 @@ open class BluePrintMessageLibPropertyService(private var bluePrintPropertiesSer MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { JacksonUtils.readValue(jsonNode, KafkaBasicAuthMessageProducerProperties::class.java)!! } - else -> { - throw BluePrintProcessorException("Message adaptor($type) is not supported") + MessageLibConstants.TYPE_KAFKA_SSL_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaSslAuthMessageProducerProperties::class.java)!! } - } - } - - private fun blueprintMessageProducerService(MessageProducerProperties: MessageProducerProperties): - BlueprintMessageProducerService { - - when (MessageProducerProperties) { - is KafkaBasicAuthMessageProducerProperties -> { - return KafkaBasicAuthMessageProducerService(MessageProducerProperties) + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaScramSslAuthMessageProducerProperties::class.java)!! } else -> { - throw BluePrintProcessorException("couldn't get Message client service for") + throw BluePrintProcessorException("Message adaptor($type) is not supported") } } } - private fun kafkaBasicAuthMessageProducerProperties(prefix: String): KafkaBasicAuthMessageProducerProperties { - return bluePrintPropertiesService.propertyBeanType( - prefix, KafkaBasicAuthMessageProducerProperties::class.java - ) - } - /** Consumer Property Lib Service Implementation **/ /** Return Message Consumer Service for [jsonNode] definitions. */ @@ -105,11 +110,37 @@ open class BluePrintMessageLibPropertyService(private var bluePrintPropertiesSer fun messageConsumerProperties(prefix: String): MessageConsumerProperties { val type = bluePrintPropertiesService.propertyBeanType("$prefix.type", String::class.java) return when (type) { + /** Message Consumer */ MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { - kafkaBasicAuthMessageConsumerProperties(prefix) + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaBasicAuthMessageConsumerProperties::class.java + ) + } + MessageLibConstants.TYPE_KAFKA_SSL_AUTH -> { + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaSslAuthMessageConsumerProperties::class.java + ) } + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH -> { + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaScramSslAuthMessageConsumerProperties::class.java + ) + } + /** Stream Consumer */ MessageLibConstants.TYPE_KAFKA_STREAMS_BASIC_AUTH -> { - kafkaStreamsBasicAuthMessageConsumerProperties(prefix) + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaStreamsBasicAuthConsumerProperties::class.java + ) + } + MessageLibConstants.TYPE_KAFKA_STREAMS_SSL_AUTH -> { + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaStreamsSslAuthConsumerProperties::class.java + ) + } + MessageLibConstants.TYPE_KAFKA_STREAMS_SCRAM_SSL_AUTH -> { + bluePrintPropertiesService.propertyBeanType( + prefix, KafkaStreamsScramSslAuthConsumerProperties::class.java + ) } else -> { throw BluePrintProcessorException("Message adaptor($type) is not supported") @@ -120,12 +151,26 @@ open class BluePrintMessageLibPropertyService(private var bluePrintPropertiesSer fun messageConsumerProperties(jsonNode: JsonNode): MessageConsumerProperties { val type = jsonNode.get("type").textValue() return when (type) { + /** Message Consumer */ MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { JacksonUtils.readValue(jsonNode, KafkaBasicAuthMessageConsumerProperties::class.java)!! } + MessageLibConstants.TYPE_KAFKA_SSL_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaSslAuthMessageConsumerProperties::class.java)!! + } + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaScramSslAuthMessageConsumerProperties::class.java)!! + } + /** Stream Consumer */ MessageLibConstants.TYPE_KAFKA_STREAMS_BASIC_AUTH -> { JacksonUtils.readValue(jsonNode, KafkaStreamsBasicAuthConsumerProperties::class.java)!! } + MessageLibConstants.TYPE_KAFKA_STREAMS_SSL_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaStreamsSslAuthConsumerProperties::class.java)!! + } + MessageLibConstants.TYPE_KAFKA_STREAMS_SCRAM_SSL_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaStreamsScramSslAuthConsumerProperties::class.java)!! + } else -> { throw BluePrintProcessorException("Message adaptor($type) is not supported") } @@ -135,28 +180,42 @@ open class BluePrintMessageLibPropertyService(private var bluePrintPropertiesSer private fun blueprintMessageConsumerService(messageConsumerProperties: MessageConsumerProperties): BlueprintMessageConsumerService { - when (messageConsumerProperties) { - is KafkaBasicAuthMessageConsumerProperties -> { - return KafkaBasicAuthMessageConsumerService(messageConsumerProperties) + when (messageConsumerProperties.type) { + /** Message Consumer */ + MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { + return KafkaMessageConsumerService( + messageConsumerProperties as KafkaBasicAuthMessageConsumerProperties + ) + } + MessageLibConstants.TYPE_KAFKA_SSL_AUTH -> { + return KafkaMessageConsumerService( + messageConsumerProperties as KafkaSslAuthMessageConsumerProperties + ) + } + MessageLibConstants.TYPE_KAFKA_SCRAM_SSL_AUTH -> { + return KafkaMessageConsumerService( + messageConsumerProperties as KafkaScramSslAuthMessageConsumerProperties + ) } - is KafkaStreamsBasicAuthConsumerProperties -> { - return KafkaStreamsBasicAuthConsumerService(messageConsumerProperties) + /** Stream Consumer */ + MessageLibConstants.TYPE_KAFKA_STREAMS_BASIC_AUTH -> { + return KafkaStreamsConsumerService( + messageConsumerProperties as KafkaStreamsBasicAuthConsumerProperties + ) + } + MessageLibConstants.TYPE_KAFKA_STREAMS_SSL_AUTH -> { + return KafkaStreamsConsumerService( + messageConsumerProperties as KafkaStreamsSslAuthConsumerProperties + ) + } + MessageLibConstants.TYPE_KAFKA_STREAMS_SCRAM_SSL_AUTH -> { + return KafkaStreamsConsumerService( + messageConsumerProperties as KafkaStreamsScramSslAuthConsumerProperties + ) } else -> { - throw BluePrintProcessorException("couldn't get Message client service for") + throw BluePrintProcessorException("couldn't get message client service for ${messageConsumerProperties.type}") } } } - - private fun kafkaBasicAuthMessageConsumerProperties(prefix: String): KafkaBasicAuthMessageConsumerProperties { - return bluePrintPropertiesService.propertyBeanType( - prefix, KafkaBasicAuthMessageConsumerProperties::class.java - ) - } - - private fun kafkaStreamsBasicAuthMessageConsumerProperties(prefix: String): KafkaStreamsBasicAuthConsumerProperties { - return bluePrintPropertiesService.propertyBeanType( - prefix, KafkaStreamsBasicAuthConsumerProperties::class.java - ) - } } diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaMessageConsumerService.kt index 3415c8d0d..cdcd4197c 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaMessageConsumerService.kt @@ -21,24 +21,20 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import org.apache.kafka.clients.CommonClientConfigs import org.apache.kafka.clients.consumer.Consumer -import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.clients.consumer.KafkaConsumer -import org.apache.kafka.common.serialization.ByteArrayDeserializer -import org.apache.kafka.common.serialization.StringDeserializer import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageConsumerProperties import org.onap.ccsdk.cds.controllerblueprints.core.logger import java.nio.charset.Charset import java.time.Duration import kotlin.concurrent.thread -open class KafkaBasicAuthMessageConsumerService( +open class KafkaMessageConsumerService( private val messageConsumerProperties: KafkaBasicAuthMessageConsumerProperties ) : BlueprintMessageConsumerService { - val log = logger(KafkaBasicAuthMessageConsumerService::class) + val log = logger(KafkaMessageConsumerService::class) val channel = Channel<String>() var kafkaConsumer: Consumer<String, ByteArray>? = null @@ -46,24 +42,7 @@ open class KafkaBasicAuthMessageConsumerService( var keepGoing = true fun kafkaConsumer(additionalConfig: Map<String, Any>? = null): Consumer<String, ByteArray> { - val configProperties = hashMapOf<String, Any>() - configProperties[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = messageConsumerProperties.bootstrapServers - configProperties[ConsumerConfig.GROUP_ID_CONFIG] = messageConsumerProperties.groupId - configProperties[ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG] = messageConsumerProperties.autoCommit - /** - * earliest: automatically reset the offset to the earliest offset - * latest: automatically reset the offset to the latest offset - */ - configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = messageConsumerProperties.autoOffsetReset - configProperties[ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG] = StringDeserializer::class.java - configProperties[ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG] = ByteArrayDeserializer::class.java - configProperties[ConsumerConfig.CLIENT_ID_CONFIG] = messageConsumerProperties.clientId - - /** To handle Back pressure, Get only configured record for processing */ - if (messageConsumerProperties.pollRecords > 0) { - configProperties[ConsumerConfig.MAX_POLL_RECORDS_CONFIG] = messageConsumerProperties.pollRecords - } - // TODO("Security Implementation based on type") + val configProperties = messageConsumerProperties.getConfig() /** add or override already set properties */ additionalConfig?.let { configProperties.putAll(it) } /** Create Kafka consumer */ diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaMessageProducerService.kt index 8416282af..931f052ed 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaMessageProducerService.kt @@ -20,28 +20,20 @@ package org.onap.ccsdk.cds.blueprintsprocessor.message.service import org.apache.commons.lang.builder.ToStringBuilder import org.apache.kafka.clients.producer.Callback import org.apache.kafka.clients.producer.KafkaProducer -import org.apache.kafka.clients.producer.ProducerConfig.ACKS_CONFIG -import org.apache.kafka.clients.producer.ProducerConfig.BOOTSTRAP_SERVERS_CONFIG -import org.apache.kafka.clients.producer.ProducerConfig.CLIENT_ID_CONFIG -import org.apache.kafka.clients.producer.ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG -import org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG -import org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG import org.apache.kafka.clients.producer.ProducerRecord import org.apache.kafka.common.header.internals.RecordHeader -import org.apache.kafka.common.serialization.ByteArraySerializer -import org.apache.kafka.common.serialization.StringSerializer -import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageProducerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageProducerProperties import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString import org.onap.ccsdk.cds.controllerblueprints.core.defaultToUUID import org.slf4j.LoggerFactory import java.nio.charset.Charset -class KafkaBasicAuthMessageProducerService( - private val messageProducerProperties: KafkaBasicAuthMessageProducerProperties +class KafkaMessageProducerService( + private val messageProducerProperties: MessageProducerProperties ) : BlueprintMessageProducerService { - private val log = LoggerFactory.getLogger(KafkaBasicAuthMessageProducerService::class.java)!! + private val log = LoggerFactory.getLogger(KafkaMessageProducerService::class.java)!! private var kafkaProducer: KafkaProducer<String, ByteArray>? = null @@ -81,26 +73,16 @@ class KafkaBasicAuthMessageProducerService( } fun messageTemplate(additionalConfig: Map<String, ByteArray>? = null): KafkaProducer<String, ByteArray> { - log.trace("Client Properties : ${ToStringBuilder.reflectionToString(messageProducerProperties)}") - val configProps = hashMapOf<String, Any>() - configProps[BOOTSTRAP_SERVERS_CONFIG] = messageProducerProperties.bootstrapServers - configProps[KEY_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java - configProps[VALUE_SERIALIZER_CLASS_CONFIG] = ByteArraySerializer::class.java - configProps[ACKS_CONFIG] = messageProducerProperties.acks - configProps[ENABLE_IDEMPOTENCE_CONFIG] = messageProducerProperties.enableIdempotence - if (messageProducerProperties.clientId != null) { - configProps[CLIENT_ID_CONFIG] = messageProducerProperties.clientId!! - } - // TODO("Security Implementation based on type") + log.trace("Producer client properties : ${ToStringBuilder.reflectionToString(messageProducerProperties)}") + val configProps = messageProducerProperties.getConfig() - // Add additional Properties - if (additionalConfig != null) { + /** Add additional Properties */ + if (additionalConfig != null) configProps.putAll(additionalConfig) - } - if (kafkaProducer == null) { + if (kafkaProducer == null) kafkaProducer = KafkaProducer(configProps) - } + return kafkaProducer!! } } diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsBasicAuthConsumerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsConsumerService.kt index 0b353d58b..60f2dfa05 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsBasicAuthConsumerService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsConsumerService.kt @@ -17,27 +17,22 @@ package org.onap.ccsdk.cds.blueprintsprocessor.message.service import kotlinx.coroutines.channels.Channel -import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.streams.KafkaStreams -import org.apache.kafka.streams.StreamsConfig -import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaStreamsBasicAuthConsumerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageConsumerProperties import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.logger import java.util.Properties -open class KafkaStreamsBasicAuthConsumerService(private val messageConsumerProperties: KafkaStreamsBasicAuthConsumerProperties) : +open class KafkaStreamsConsumerService(private val messageConsumerProperties: MessageConsumerProperties) : BlueprintMessageConsumerService { - val log = logger(KafkaStreamsBasicAuthConsumerService::class) + val log = logger(KafkaStreamsConsumerService::class) lateinit var kafkaStreams: KafkaStreams private fun streamsConfig(additionalConfig: Map<String, Any>? = null): Properties { val configProperties = Properties() - configProperties[StreamsConfig.APPLICATION_ID_CONFIG] = messageConsumerProperties.applicationId - configProperties[StreamsConfig.BOOTSTRAP_SERVERS_CONFIG] = messageConsumerProperties.bootstrapServers - configProperties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = messageConsumerProperties.autoOffsetReset - configProperties[StreamsConfig.PROCESSING_GUARANTEE_CONFIG] = messageConsumerProperties.processingGuarantee - // TODO("Security Implementation based on type") + /** set consumer properties */ + messageConsumerProperties.getConfig().let { configProperties.putAll(it) } /** add or override already set properties */ additionalConfig?.let { configProperties.putAll(it) } /** Create Kafka consumer */ diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSLTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSLTest.kt index b10e1023b..612a57d23 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSLTest.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/MessagePropertiesDSLTest.kt @@ -27,17 +27,27 @@ import kotlin.test.assertNotNull class MessagePropertiesDSLTest { @Test - fun testMessageProducerDSL() { + fun testScramSslMessageProducerDSL() { val serviceTemplate = serviceTemplate("message-properties-test", "1.0.0", "xxx.@xx.com", "message") { topologyTemplate { - relationshipTemplateMessageProducer("sample-basic-auth", "Message Producer") { - kafkaBasicAuth { + relationshipTemplateMessageProducer("sample-scram-ssl-auth", "Message Producer") { + kafkaScramSslAuth { bootstrapServers("sample-bootstrapServers") clientId("sample-client-id") acks("all") retries(3) enableIdempotence(true) topic("sample-topic") + truststore("/path/to/truststore.jks") + truststorePassword("secretpassword") + truststoreType("JKS") + keystore("/path/to/keystore.jks") + keystorePassword("secretpassword") + keystoreType("JKS") + sslEndpointIdentificationAlgorithm("") + saslMechanism("SCRAM-SHA-512") + scramUsername("sample-user") + scramPassword("secretpassword") } } } @@ -50,27 +60,27 @@ class MessagePropertiesDSLTest { val relationshipTemplates = serviceTemplate.topologyTemplate?.relationshipTemplates assertNotNull(relationshipTemplates, "failed to get relationship templates") assertEquals(1, relationshipTemplates.size, "relationshipTemplates doesn't match") - assertNotNull(relationshipTemplates["sample-basic-auth"], "failed to get sample-basic-auth") + assertNotNull(relationshipTemplates["sample-scram-ssl-auth"], "failed to get sample-scram-ssl-auth") val relationshipTypes = serviceTemplate.relationshipTypes assertNotNull(relationshipTypes, "failed to get relationship types") assertEquals(2, relationshipTypes.size, "relationshipTypes doesn't match") assertNotNull( - relationshipTypes[BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO], - "failed to get ${BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO}" + relationshipTypes[BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO], + "failed to get ${BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO}" ) assertNotNull( - relationshipTypes[BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_MESSAGE_PRODUCER], - "failed to get ${BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_MESSAGE_PRODUCER}" + relationshipTypes[BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_MESSAGE_PRODUCER], + "failed to get ${BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_MESSAGE_PRODUCER}" ) } @Test - fun testMessageConsumerDSL() { + fun testScramSslAuthMessageConsumerDSL() { val serviceTemplate = serviceTemplate("message-properties-test", "1.0.0", "xxx.@xx.com", "message") { topologyTemplate { - relationshipTemplateMessageConsumer("sample-basic-auth", "Message Consumer") { - kafkaBasicAuth { + relationshipTemplateMessageConsumer("sample-scram-ssl-auth", "Message Consumer") { + kafkaScramSslAuth { bootstrapServers("sample-bootstrapServers") clientId("sample-client-id") groupId("sample-group-id") @@ -79,15 +89,35 @@ class MessagePropertiesDSLTest { autoOffsetReset("latest") pollMillSec(5000) pollRecords(20) + truststore("/path/to/truststore.jks") + truststorePassword("secretpassword") + truststoreType("JKS") + keystore("/path/to/keystore.jks") + keystorePassword("secretpassword") + keystoreType("JKS") + sslEndpointIdentificationAlgorithm("") + saslMechanism("SCRAM-SHA-512") + scramUsername("sample-user") + scramPassword("secretpassword") } } - relationshipTemplateMessageConsumer("sample-stream-basic-auth", "Message Consumer") { - kafkaStreamsBasicAuth { + relationshipTemplateMessageConsumer("sample-stream-scram-ssl-auth", "Message Consumer") { + kafkaStreamsScramSslAuth { bootstrapServers("sample-bootstrapServers") applicationId("sample-application-id") autoOffsetReset("latest") processingGuarantee(StreamsConfig.EXACTLY_ONCE) topic("sample-streaming-topic") + truststore("/path/to/truststore.jks") + truststorePassword("secretpassword") + truststoreType("JKS") + keystore("/path/to/keystore.jks") + keystorePassword("secretpassword") + keystoreType("JKS") + sslEndpointIdentificationAlgorithm("") + saslMechanism("SCRAM-SHA-512") + scramUsername("sample-user") + scramPassword("secretpassword") } } } @@ -100,8 +130,8 @@ class MessagePropertiesDSLTest { val relationshipTemplates = serviceTemplate.topologyTemplate?.relationshipTemplates assertNotNull(relationshipTemplates, "failed to get relationship templates") assertEquals(2, relationshipTemplates.size, "relationshipTemplates doesn't match") - assertNotNull(relationshipTemplates["sample-basic-auth"], "failed to get sample-basic-auth") - assertNotNull(relationshipTemplates["sample-stream-basic-auth"], "failed to get sample-stream-basic-auth") + assertNotNull(relationshipTemplates["sample-scram-ssl-auth"], "failed to get sample-scram-ssl-auth") + assertNotNull(relationshipTemplates["sample-stream-scram-ssl-auth"], "failed to get sample-stream-scram-ssl-auth") val relationshipTypes = serviceTemplate.relationshipTypes assertNotNull(relationshipTypes, "failed to get relationship types") diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt index 823ba7dee..ac08dc7b7 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt @@ -23,24 +23,35 @@ import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.apache.kafka.clients.CommonClientConfigs import org.apache.kafka.clients.consumer.Consumer +import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.clients.consumer.ConsumerRecord import org.apache.kafka.clients.consumer.ConsumerRecords import org.apache.kafka.clients.consumer.MockConsumer import org.apache.kafka.clients.consumer.OffsetResetStrategy +import org.apache.kafka.clients.producer.ProducerConfig import org.apache.kafka.common.TopicPartition +import org.apache.kafka.common.config.SaslConfigs +import org.apache.kafka.common.config.SslConfigs +import org.apache.kafka.common.security.auth.SecurityProtocol +import org.apache.kafka.common.security.scram.ScramLoginModule +import org.apache.kafka.common.serialization.ByteArrayDeserializer +import org.apache.kafka.common.serialization.StringDeserializer import org.junit.Test import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertiesService import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertyConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageConsumerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageLibConstants import org.onap.ccsdk.cds.controllerblueprints.core.logger import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner +import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue @@ -52,18 +63,30 @@ import kotlin.test.assertTrue ) @TestPropertySource( properties = - ["blueprintsprocessor.messageconsumer.sample.type=kafka-basic-auth", + ["blueprintsprocessor.messageconsumer.sample.type=kafka-scram-ssl-auth", "blueprintsprocessor.messageconsumer.sample.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageconsumer.sample.groupId=sample-group", "blueprintsprocessor.messageconsumer.sample.topic=default-topic", "blueprintsprocessor.messageconsumer.sample.clientId=default-client-id", "blueprintsprocessor.messageconsumer.sample.pollMillSec=10", "blueprintsprocessor.messageconsumer.sample.pollRecords=1", + "blueprintsprocessor.messageconsumer.sample.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageconsumer.sample.truststorePassword=secretpassword", + "blueprintsprocessor.messageconsumer.sample.keystore=/path/to/keystore.jks", + "blueprintsprocessor.messageconsumer.sample.keystorePassword=secretpassword", + "blueprintsprocessor.messageconsumer.sample.scramUsername=sample-user", + "blueprintsprocessor.messageconsumer.sample.scramPassword=secretpassword", - "blueprintsprocessor.messageproducer.sample.type=kafka-basic-auth", + "blueprintsprocessor.messageproducer.sample.type=kafka-scram-ssl-auth", "blueprintsprocessor.messageproducer.sample.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageproducer.sample.topic=default-topic", - "blueprintsprocessor.messageproducer.sample.clientId=default-client-id" + "blueprintsprocessor.messageproducer.sample.clientId=default-client-id", + "blueprintsprocessor.messageproducer.sample.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageproducer.sample.truststorePassword=secretpassword", + "blueprintsprocessor.messageproducer.sample.keystore=/path/to/keystore.jks", + "blueprintsprocessor.messageproducer.sample.keystorePassword=secretpassword", + "blueprintsprocessor.messageproducer.sample.scramUsername=sample-user", + "blueprintsprocessor.messageproducer.sample.scramPassword=secretpassword" ] ) open class BlueprintMessageConsumerServiceTest { @@ -77,7 +100,7 @@ open class BlueprintMessageConsumerServiceTest { fun testKafkaBasicAuthConsumerService() { runBlocking { val blueprintMessageConsumerService = bluePrintMessageLibPropertyService - .blueprintMessageConsumerService("sample") as KafkaBasicAuthMessageConsumerService + .blueprintMessageConsumerService("sample") as KafkaMessageConsumerService assertNotNull(blueprintMessageConsumerService, "failed to get blueprintMessageConsumerService") val spyBlueprintMessageConsumerService = spyk(blueprintMessageConsumerService, recordPrivateCalls = true) @@ -124,7 +147,7 @@ open class BlueprintMessageConsumerServiceTest { fun testKafkaBasicAuthConsumerWithDynamicFunction() { runBlocking { val blueprintMessageConsumerService = bluePrintMessageLibPropertyService - .blueprintMessageConsumerService("sample") as KafkaBasicAuthMessageConsumerService + .blueprintMessageConsumerService("sample") as KafkaMessageConsumerService assertNotNull(blueprintMessageConsumerService, "failed to get blueprintMessageConsumerService") val spyBlueprintMessageConsumerService = spyk(blueprintMessageConsumerService, recordPrivateCalls = true) @@ -173,12 +196,60 @@ open class BlueprintMessageConsumerServiceTest { } } + @Test + fun testKafkaScramSslAuthConfig() { + + val expectedConfig = mapOf<String, Any>( + ProducerConfig.BOOTSTRAP_SERVERS_CONFIG to "127.0.0.1:9092", + ConsumerConfig.GROUP_ID_CONFIG to "sample-group", + ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG to true, + ConsumerConfig.AUTO_OFFSET_RESET_CONFIG to "latest", + ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG to StringDeserializer::class.java, + ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG to ByteArrayDeserializer::class.java, + ConsumerConfig.CLIENT_ID_CONFIG to "default-client-id", + CommonClientConfigs.SECURITY_PROTOCOL_CONFIG to SecurityProtocol.SASL_SSL.toString(), + SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG to "JKS", + SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG to "/path/to/truststore.jks", + SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG to "secretpassword", + SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG to "/path/to/keystore.jks", + SslConfigs.SSL_KEYSTORE_TYPE_CONFIG to "JKS", + SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG to "secretpassword", + SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG to "", + SaslConfigs.SASL_MECHANISM to "SCRAM-SHA-512", + SaslConfigs.SASL_JAAS_CONFIG to "${ScramLoginModule::class.java.canonicalName} required " + + "username=\"sample-user\" " + + "password=\"secretpassword\";" + ) + + val messageConsumerProperties = bluePrintMessageLibPropertyService + .messageConsumerProperties("${MessageLibConstants.PROPERTY_MESSAGE_CONSUMER_PREFIX}sample") + + val configProps = messageConsumerProperties.getConfig() + + assertEquals(messageConsumerProperties.topic, + "default-topic", + "Topic doesn't match the expected value" + ) + assertEquals(messageConsumerProperties.type, + "kafka-scram-ssl-auth", + "Authentication type doesn't match the expected value") + + expectedConfig.forEach { + assertTrue(configProps.containsKey(it.key), + "Missing expected kafka config key : ${it.key}") + assertEquals(configProps[it.key], + it.value, + "Unexpected value for ${it.key} got ${configProps[it.key]} instead of ${it.value}" + ) + } + } + /** Integration Kafka Testing, Enable and use this test case only for local desktop testing with real kafka broker */ // @Test fun testKafkaIntegration() { runBlocking { val blueprintMessageConsumerService = bluePrintMessageLibPropertyService - .blueprintMessageConsumerService("sample") as KafkaBasicAuthMessageConsumerService + .blueprintMessageConsumerService("sample") as KafkaMessageConsumerService assertNotNull(blueprintMessageConsumerService, "failed to get blueprintMessageConsumerService") val channel = blueprintMessageConsumerService.subscribe(null) @@ -190,7 +261,7 @@ open class BlueprintMessageConsumerServiceTest { /** Send message with every 1 sec */ val blueprintMessageProducerService = bluePrintMessageLibPropertyService - .blueprintMessageProducerService("sample") as KafkaBasicAuthMessageProducerService + .blueprintMessageProducerService("sample") as KafkaMessageProducerService launch { repeat(5) { delay(100) diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt index b824189d2..72a47ed56 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt @@ -20,12 +20,22 @@ import io.mockk.every import io.mockk.mockk import io.mockk.spyk import kotlinx.coroutines.runBlocking +import org.apache.kafka.clients.CommonClientConfigs +import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.clients.producer.KafkaProducer +import org.apache.kafka.clients.producer.ProducerConfig import org.apache.kafka.clients.producer.RecordMetadata +import org.apache.kafka.common.config.SaslConfigs +import org.apache.kafka.common.config.SslConfigs +import org.apache.kafka.common.security.auth.SecurityProtocol +import org.apache.kafka.common.security.scram.ScramLoginModule +import org.apache.kafka.common.serialization.ByteArraySerializer +import org.apache.kafka.common.serialization.StringSerializer import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertiesService import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertyConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageLibConstants import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ContextConfiguration @@ -33,6 +43,7 @@ import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner import java.util.concurrent.Future import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.test.assertTrue @RunWith(SpringRunner::class) @@ -43,10 +54,16 @@ import kotlin.test.assertTrue ) @TestPropertySource( properties = - ["blueprintsprocessor.messageproducer.sample.type=kafka-basic-auth", + ["blueprintsprocessor.messageproducer.sample.type=kafka-scram-ssl-auth", "blueprintsprocessor.messageproducer.sample.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageproducer.sample.topic=default-topic", - "blueprintsprocessor.messageproducer.sample.clientId=default-client-id" + "blueprintsprocessor.messageproducer.sample.clientId=default-client-id", + "blueprintsprocessor.messageproducer.sample.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageproducer.sample.truststorePassword=secretpassword", + "blueprintsprocessor.messageproducer.sample.keystore=/path/to/keystore.jks", + "blueprintsprocessor.messageproducer.sample.keystorePassword=secretpassword", + "blueprintsprocessor.messageproducer.sample.scramUsername=sample-user", + "blueprintsprocessor.messageproducer.sample.scramPassword=secretpassword" ] ) open class BlueprintMessageProducerServiceTest { @@ -55,10 +72,10 @@ open class BlueprintMessageProducerServiceTest { lateinit var bluePrintMessageLibPropertyService: BluePrintMessageLibPropertyService @Test - fun testKafkaBasicAuthProducertService() { + fun testKafkaScramSslAuthProducerService() { runBlocking { val blueprintMessageProducerService = bluePrintMessageLibPropertyService - .blueprintMessageProducerService("sample") as KafkaBasicAuthMessageProducerService + .blueprintMessageProducerService("sample") as KafkaMessageProducerService val mockKafkaTemplate = mockk<KafkaProducer<String, ByteArray>>() @@ -75,4 +92,51 @@ open class BlueprintMessageProducerServiceTest { assertTrue(response, "failed to get command response") } } + + @Test + fun testKafkaScramSslAuthConfig() { + val expectedConfig = mapOf<String, Any>( + ProducerConfig.BOOTSTRAP_SERVERS_CONFIG to "127.0.0.1:9092", + ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG to StringSerializer::class.java, + ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG to ByteArraySerializer::class.java, + ProducerConfig.ACKS_CONFIG to "all", + ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG to true, + ConsumerConfig.CLIENT_ID_CONFIG to "default-client-id", + CommonClientConfigs.SECURITY_PROTOCOL_CONFIG to SecurityProtocol.SASL_SSL.toString(), + SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG to "JKS", + SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG to "/path/to/truststore.jks", + SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG to "secretpassword", + SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG to "/path/to/keystore.jks", + SslConfigs.SSL_KEYSTORE_TYPE_CONFIG to "JKS", + SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG to "secretpassword", + SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG to "", + SaslConfigs.SASL_MECHANISM to "SCRAM-SHA-512", + SaslConfigs.SASL_JAAS_CONFIG to "${ScramLoginModule::class.java.canonicalName} required " + + "username=\"sample-user\" " + + "password=\"secretpassword\";" + ) + + val messageProducerProperties = bluePrintMessageLibPropertyService + .messageProducerProperties("${MessageLibConstants.PROPERTY_MESSAGE_PRODUCER_PREFIX}sample") + + val configProps = messageProducerProperties.getConfig() + + assertEquals(messageProducerProperties.topic, + "default-topic", + "Topic doesn't match the expected value" + ) + assertEquals(messageProducerProperties.type, + "kafka-scram-ssl-auth", + "Authentication type doesn't match the expected value") + + expectedConfig.forEach { + assertTrue(configProps.containsKey(it.key), + "Missing expected kafka config key : ${it.key}" + ) + assertEquals(configProps[it.key], + it.value, + "Unexpected value for ${it.key} got ${configProps[it.key]} instead of ${it.value}" + ) + } + } } diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsBasicAuthConsumerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsConsumerServiceTest.kt index 1657d70b4..c30ab9b02 100644 --- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsBasicAuthConsumerServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaStreamsConsumerServiceTest.kt @@ -47,19 +47,27 @@ import kotlin.test.assertNotNull @TestPropertySource( properties = [ - "blueprintsprocessor.messageproducer.sample.type=kafka-basic-auth", + "blueprintsprocessor.messageproducer.sample.type=kafka-scram-ssl-auth", "blueprintsprocessor.messageproducer.sample.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageproducer.sample.topic=default-stream-topic", "blueprintsprocessor.messageproducer.sample.clientId=default-client-id", + "blueprintsprocessor.messageproducer.sample.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageproducer.sample.truststorePassword=secretpassword", + "blueprintsprocessor.messageproducer.sample.scramUsername=sample-user", + "blueprintsprocessor.messageproducer.sample.scramPassword=secretpassword", - "blueprintsprocessor.messageconsumer.stream-consumer.type=kafka-streams-basic-auth", + "blueprintsprocessor.messageconsumer.stream-consumer.type=kafka-streams-scram-ssl-auth", "blueprintsprocessor.messageconsumer.stream-consumer.bootstrapServers=127.0.0.1:9092", "blueprintsprocessor.messageconsumer.stream-consumer.applicationId=test-streams-application", - "blueprintsprocessor.messageconsumer.stream-consumer.topic=default-stream-topic" + "blueprintsprocessor.messageconsumer.stream-consumer.topic=default-stream-topic", + "blueprintsprocessor.messageproducer.stream-consumer.truststore=/path/to/truststore.jks", + "blueprintsprocessor.messageproducer.stream-consumer.truststorePassword=secretpassword", + "blueprintsprocessor.messageproducer.stream-consumer.scramUsername=sample-user", + "blueprintsprocessor.messageproducer.stream-consumer.scramPassword=secretpassword" ] ) -class KafkaStreamsBasicAuthConsumerServiceTest { +class KafkaStreamsConsumerServiceTest { @Autowired lateinit var bluePrintMessageLibPropertyService: BluePrintMessageLibPropertyService @@ -117,7 +125,7 @@ class KafkaStreamsBasicAuthConsumerServiceTest { /** Send message with every 1 sec */ val blueprintMessageProducerService = bluePrintMessageLibPropertyService - .blueprintMessageProducerService("sample") as KafkaBasicAuthMessageProducerService + .blueprintMessageProducerService("sample") as KafkaMessageProducerService launch { repeat(5) { delay(1000) diff --git a/ms/blueprintsprocessor/modules/commons/nats-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/nats-lib/pom.xml index 338428604..1865b4358 100644 --- a/ms/blueprintsprocessor/modules/commons/nats-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/nats-lib/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>nats-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/pom.xml b/ms/blueprintsprocessor/modules/commons/pom.xml index 3f6f16091..7f3043820 100755 --- a/ms/blueprintsprocessor/modules/commons/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/pom.xml @@ -17,13 +17,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>modules</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>commons</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/pom.xml b/ms/blueprintsprocessor/modules/commons/processor-core/pom.xml index 50259d82a..121214d06 100644 --- a/ms/blueprintsprocessor/modules/commons/processor-core/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/processor-core/pom.xml @@ -16,13 +16,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>processor-core</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt index d94985400..58d0f13c2 100644 --- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt +++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintProcessorData.kt @@ -25,6 +25,7 @@ import io.swagger.annotations.ApiModelProperty import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import java.util.Date +import java.util.UUID /** * BlueprintProcessorData @@ -33,7 +34,8 @@ import java.util.Date */ open class ExecutionServiceInput { - + @get:ApiModelProperty(required = false, hidden = true) + var correlationUUID: String = UUID.randomUUID().toString() @get:ApiModelProperty(required = true, value = "Headers providing request context.") lateinit var commonHeader: CommonHeader @get:ApiModelProperty(required = true, value = "Provide information about the action to execute.") @@ -51,6 +53,8 @@ open class ExecutionServiceInput { } open class ExecutionServiceOutput { + @get:ApiModelProperty(required = false, hidden = true) + var correlationUUID: String? = null @get:ApiModelProperty(required = true, value = "Headers providing request context.") lateinit var commonHeader: CommonHeader @get:ApiModelProperty(required = true, value = "Provide information about the action to execute.") diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/rest-lib/pom.xml index 1525882fb..e56742d26 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/pom.xml @@ -16,13 +16,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>rest-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml index 3b7ae9f67..a1f096bf2 100644 --- a/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>commons</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>ssh-lib</artifactId> diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml index 8e907abcf..6bef263da 100644 --- a/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml @@ -14,17 +14,18 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>inbounds</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>configs-api</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Blueprints Processor Resource Configurations API</name> @@ -43,5 +44,9 @@ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprint-core</artifactId> </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.error.catalog</groupId> + <artifactId>error-catalog-services</artifactId> + </dependency> </dependencies> </project> diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotException.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ErrorHandling.kt index 1eeea9893..e742e6375 100644 --- a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotException.kt +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ErrorHandling.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2019 Bell Canada. + * Copyright © 2018-2019 AT&T Intellectual Property. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,8 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.onap.ccsdk.cds.blueprintsprocessor.configs.api -class ResourceConfigSnapshotException(message: String) : RuntimeException(message) { - var code: Int = 404 +object ConfigsApiDomains { + // ConfigsApi Domains Constants + const val CONFIGS_API = "org.onap.ccsdk.cds.blueprintsprocessor.configs.api" +} + +object ConfigsApiHttpErrorCodes { + init { + // Register HttpErrorCodes + // HttpErrorCodes.register("", 200) + } +} + +object ConfigsGrpcErrorCodes { + init { + // Register GrpcErrorCodes + // GrpcErrorCodes.register("", 3) + } } diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt index 0b18fb01f..2a5f4c3ea 100644 --- a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt @@ -24,6 +24,9 @@ import kotlinx.coroutines.runBlocking import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshotService import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes +import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.security.access.prepost.PreAuthorize @@ -101,12 +104,17 @@ open class ResourceConfigSnapshotController(private val resourceConfigSnapshotSe resourceType, ResourceConfigSnapshot.Status.valueOf(status.toUpperCase()) ) } catch (ex: NoSuchElementException) { - throw ResourceConfigSnapshotException( - "Could not find configuration snapshot entry for type $resourceType and Id $resourceId" - ) + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, ConfigsApiDomains.CONFIGS_API, + "Could not find configuration snapshot entry for type $resourceType and Id $resourceId", + ex.errorCauseOrDefault()) + } catch (ex: Exception) { + throw httpProcessorException(ErrorCatalogCodes.INVALID_REQUEST_FORMAT, ConfigsApiDomains.CONFIGS_API, + "Could not find configuration snapshot entry for type $resourceType and Id $resourceId", + ex.errorCauseOrDefault()) } } else { - throw IllegalArgumentException("Missing param. You must specify resource-id and resource-type.") + throw httpProcessorException(ErrorCatalogCodes.INVALID_REQUEST_FORMAT, ConfigsApiDomains.CONFIGS_API, + "Missing param. You must specify resource-id and resource-type.") } var expectedContentType = format diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt index d4c31e780..2b9bb31f6 100644 --- a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Bell Canada + * Copyright © 2019 - 2020 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. @@ -16,106 +16,16 @@ package org.onap.ccsdk.cds.blueprintsprocessor.configs.api -import com.fasterxml.jackson.annotation.JsonFormat -import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.fasterxml.jackson.annotation.JsonTypeName -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException -import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode -import org.slf4j.LoggerFactory -import org.springframework.dao.EmptyResultDataAccessException -import org.springframework.dao.IncorrectResultSizeDataAccessException -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import org.springframework.orm.jpa.JpaObjectRetrievalFailureException -import org.springframework.web.bind.annotation.ExceptionHandler +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogExceptionHandler +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogService import org.springframework.web.bind.annotation.RestControllerAdvice -import org.springframework.web.server.ServerWebInputException -import java.io.Serializable -import java.util.Date /** * Handle exceptions in ResourceConfigSnapshot API and provide relevant HTTP status codes and messages * * @author Serge Simard - * @version 1.0 + * @version 2.0 */ @RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.configs.api") -open class ResourceConfigSnapshotExceptionHandler { - - private val log = LoggerFactory.getLogger(ResourceConfigSnapshotExceptionHandler::class.toString()) - - private val debugMsg = "Resource_Config_Snapshot_ExceptionHandler_Error_Message" - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.BLUEPRINT_PATH_MISSING - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.INVALID_REQUEST_FORMAT - return returnError(e, errorCode, false) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: IllegalArgumentException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.INVALID_REQUEST_FORMAT - return returnError(e, errorCode, false) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: IncorrectResultSizeDataAccessException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.DUPLICATE_DATA - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.RESOURCE_NOT_FOUND - return returnError(e, errorCode, false) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.RESOURCE_NOT_FOUND - return returnError(e, errorCode, false) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.GENERIC_FAILURE - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resourceConfigSnapshotExceptionHandler(e: ResourceConfigSnapshotException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.RESOURCE_NOT_FOUND - return returnError(e, errorCode, false) - } - - fun returnError(e: Exception, errorCode: ErrorCode, toBeLogged: Boolean = true): ResponseEntity<ErrorMessage> { - if (toBeLogged) { - log.error(e.message, e) - } else { - log.error(e.message) - } - val errorMessage = - ErrorMessage( - errorCode.message(e.message!!), - errorCode.value, - debugMsg - ) - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)!!) - } -} - -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonTypeName("errorMessage") -@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) -class ErrorMessage(var message: String?, var code: Int?, var debugMessage: String?) : Serializable { - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - var timestamp = Date() -} +open class ResourceConfigSnapshotExceptionHandler(private val errorCatalogService: ErrorCatalogService) : + ErrorCatalogExceptionHandler(errorCatalogService) diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ErrorCatalogTestConfiguration.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ErrorCatalogTestConfiguration.kt new file mode 100644 index 000000000..66fc3b2ed --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ErrorCatalogTestConfiguration.kt @@ -0,0 +1,28 @@ +/* + * Copyright © 2020 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. + * 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.configs.api + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan( + basePackages = ["org.onap.ccsdk.cds.error.catalog"] +) +@EnableAutoConfiguration +open class ErrorCatalogTestConfiguration diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt index d55568df8..b54d92bb0 100644 --- a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt @@ -35,7 +35,7 @@ import org.springframework.web.reactive.function.BodyInserters @RunWith(SpringRunner::class) @WebFluxTest @ContextConfiguration( - classes = [BluePrintCoreConfiguration::class, BluePrintCatalogService::class] + classes = [BluePrintCoreConfiguration::class, BluePrintCatalogService::class, ErrorCatalogTestConfiguration::class] ) @ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) @TestPropertySource(locations = ["classpath:application-test.properties"]) @@ -112,7 +112,7 @@ class ResourceConfigSnapshotControllerTest { webTestClient.get().uri("/api/v1/configs?$arguments") .exchange() - .expectStatus().isBadRequest + .expectStatus().is4xxClientError } } diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties index ebd394cc2..69dbe23e2 100644 --- a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties @@ -1,4 +1,4 @@ -# Copyright © 2019 Bell Canada. +# Copyright © 2019 - 2020 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. @@ -28,3 +28,8 @@ blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints + +# Error Managements +error.catalog.applicationId=cds +error.catalog.type=properties +error.catalog.errorDefinitionDir=./../../../application/src/test/resources/ diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml index edfcdf891..419db8671 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>inbounds</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>designer-api</artifactId> @@ -28,4 +29,11 @@ <name>Blueprints Processor Designer API</name> <description>Blueprints Processor Designer API</description> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.cds.error.catalog</groupId> + <artifactId>error-catalog-services</artifactId> + </dependency> + </dependencies> </project> diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandler.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandler.kt index bca77f275..7600979f8 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandler.kt @@ -40,13 +40,20 @@ import org.onap.ccsdk.cds.controllerblueprints.management.api.DownloadAction import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk import org.onap.ccsdk.cds.controllerblueprints.management.api.RemoveAction import org.onap.ccsdk.cds.controllerblueprints.management.api.UploadAction +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes +import org.onap.ccsdk.cds.error.catalog.core.GrpcErrorCodes +import org.onap.ccsdk.cds.error.catalog.core.utils.errorMessageOrDefault +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogService import org.slf4j.LoggerFactory import org.springframework.security.access.prepost.PreAuthorize import org.springframework.stereotype.Service // TODO("Convert to coroutines handler") @Service -open class BluePrintManagementGRPCHandler(private val bluePrintModelHandler: BluePrintModelHandler) : +open class BluePrintManagementGRPCHandler( + private val bluePrintModelHandler: BluePrintModelHandler, + private val errorCatalogService: ErrorCatalogService +) : BluePrintManagementServiceGrpc.BluePrintManagementServiceImplBase() { private val log = LoggerFactory.getLogger(BluePrintManagementGRPCHandler::class.java) @@ -266,20 +273,42 @@ open class BluePrintManagementGRPCHandler(private val bluePrintModelHandler: Blu private fun failStatus(header: CommonHeader, message: String, e: Exception): BluePrintManagementOutput { log.error(message, e) + return if (e is BluePrintProcessorException) onErrorCatalog(header, message, e) else onError(header, message, e) + } + + private fun onError(header: CommonHeader, message: String, error: Exception): BluePrintManagementOutput { + val code = GrpcErrorCodes.code(ErrorCatalogCodes.GENERIC_FAILURE) return BluePrintManagementOutput.newBuilder() - .setCommonHeader(header) - .setStatus( - Status.newBuilder() - .setTimestamp(currentTimestamp()) - .setMessage(BluePrintConstants.STATUS_FAILURE) - .setErrorMessage(message) - .setCode(500) - .build() - ) - .build() - // return io.grpc.Status.INTERNAL - // .withDescription(message) - // .withCause(e) - // .asException() + .setCommonHeader(header) + .setStatus( + Status.newBuilder() + .setTimestamp(currentTimestamp()) + .setMessage(BluePrintConstants.STATUS_FAILURE) + .setErrorMessage("Error : $message \n Details: ${error.errorMessageOrDefault()}") + .setCode(code) + .build() + ) + .build() + } + + private fun onErrorCatalog(header: CommonHeader, message: String, error: BluePrintProcessorException): + BluePrintManagementOutput { + val err = if (error.protocol == "") { + error.grpc(ErrorCatalogCodes.GENERIC_FAILURE) + } else { + error.convertToGrpc() + } + val errorPayload = errorCatalogService.errorPayload(err.addErrorPayloadMessage(message)) + return BluePrintManagementOutput.newBuilder() + .setCommonHeader(header) + .setStatus( + Status.newBuilder() + .setTimestamp(currentTimestamp()) + .setMessage(BluePrintConstants.STATUS_FAILURE) + .setErrorMessage("Error : ${errorPayload.message}") + .setCode(errorPayload.code) + .build() + ) + .build() } } diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiData.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiData.kt index 369844445..1d61c7f0c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiData.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiData.kt @@ -17,10 +17,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api -import com.fasterxml.jackson.annotation.JsonFormat -import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.fasterxml.jackson.annotation.JsonTypeName import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.domain.ResourceDictionary import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.DATA_TYPE_JSON import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.DEFAULT_VERSION_NUMBER @@ -28,8 +24,6 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.TOSCA_SPE import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment -import java.io.Serializable -import java.util.Date class BootstrapRequest { var loadModelType: Boolean = false @@ -75,12 +69,3 @@ class AutoMapResponse { var resourceAssignments: List<ResourceAssignment>? = null var dataDictionaries: List<ResourceDictionary>? = null } - -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonTypeName("errorMessage") -@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) -class ErrorMessage(var message: String?, var code: Int?, var debugMessage: String?) : Serializable { - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - var timestamp = Date() -} diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerBlueprintExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerBlueprintExceptionHandler.kt index c140c9a07..a083d7a8b 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerBlueprintExceptionHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerBlueprintExceptionHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2018-2019 Bell Canada Intellectual Property. + * Copyright © 2019 - 2020 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. @@ -13,44 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.onap.ccsdk.cds.blueprintsprocessor.designer.api -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException -import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode -import org.slf4j.LoggerFactory -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.ExceptionHandler -import org.springframework.web.bind.annotation.RestControllerAdvice - /** * ControllerBlueprintExceptionHandler Purpose: Handle exceptions in controllerBlueprint API and provide the right * HTTP code status * - * @author Vinal Patel - * @version 1.0 + * @author Steve Siani + * @version 2.0 */ -@RestControllerAdvice("org.onap.ccsdk.cds.controllerblueprints") -open class DesignerBlueprintExceptionHandler { - - companion object ControllerBlueprintExceptionHandler { - val LOG = LoggerFactory.getLogger(DesignerBlueprintExceptionHandler::class.java) - } - - @ExceptionHandler - fun ControllerBlueprintExceptionHandler(e: BluePrintException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.valueOf(e.code) - val errorMessage = ErrorMessage(errorCode?.message(e.message!!), errorCode?.value, "ControllerBluePrint_Error_Message") - LOG.error("Error: $errorCode ${e.message}") - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode!!.httpCode)) - } +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogExceptionHandler +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogService +import org.springframework.web.bind.annotation.RestControllerAdvice - @ExceptionHandler - fun ControllerBlueprintExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.GENERIC_FAILURE - val errorMessage = ErrorMessage(errorCode?.message(e.message!!), errorCode?.value, "ControllerBluePrint_Error_Message") - LOG.error("Error: $errorCode ${e.message}") - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode!!.httpCode)) - } -} +@RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.designer.api") +open class DesignerBlueprintExceptionHandler(private val errorCatalogService: ErrorCatalogService) : + ErrorCatalogExceptionHandler(errorCatalogService) diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/enhancer/BluePrintEnhancerServiceImpl.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/enhancer/BluePrintEnhancerServiceImpl.kt index e99f49489..1d534bb73 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/enhancer/BluePrintEnhancerServiceImpl.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/enhancer/BluePrintEnhancerServiceImpl.kt @@ -17,15 +17,22 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.enhancer +import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.DesignerApiDomains import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintTypeEnhancerService -import org.onap.ccsdk.cds.controllerblueprints.core.logger import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils.ResourceDictionaryUtils +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes +import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault import org.springframework.stereotype.Service +import java.io.IOException import java.util.UUID @Service @@ -74,9 +81,17 @@ open class BluePrintEnhancerServiceImpl( if (blueprintRuntimeService.getBluePrintError().errors.isNotEmpty()) { throw BluePrintException(blueprintRuntimeService.getBluePrintError().errors.toString()) } + } catch (e: BluePrintProcessorException) { + val errorMsg = "Error while enriching the CBA package." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg, + "Wrong blueprint definitions or resource definitions.") + } catch (e: IOException) { + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "IO Error: CBA file failed enrichment - ${e.message}", e.errorCauseOrDefault()) } catch (e: Exception) { - throw e + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "Error in Enriching CBA: ${e.message}", e.errorCauseOrDefault()) + } + return blueprintRuntimeService.bluePrintContext() } - return blueprintRuntimeService.bluePrintContext() - } } 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 e9839328b..48ca912da 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 @@ -24,27 +24,34 @@ import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSe import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelContentRepository import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelRepository import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelSearchRepository +import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.DesignerApiDomains import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.BootstrapRequest -import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowData import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowSpecRequest import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowSpecResponse +import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowData import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowsResponse import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.load.BluePrintDatabaseLoadService import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils.BluePrintEnhancerUtils import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile +import org.onap.ccsdk.cds.controllerblueprints.core.deleteNBDir import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType -import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode -import org.onap.ccsdk.cds.controllerblueprints.core.deleteNBDir +import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService -import org.onap.ccsdk.cds.controllerblueprints.core.logger -import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile -import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes +import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault +import org.onap.ccsdk.cds.error.catalog.core.utils.errorMessageOrDefault import org.springframework.core.io.ByteArrayResource import org.springframework.core.io.Resource import org.springframework.data.domain.Page @@ -115,17 +122,29 @@ open class BluePrintModelHandler( workFlowData.inputs = workFlow.inputs workFlowData.outputs = workFlow.outputs - for ((k, v) in workFlow.inputs!!) { - addDataType(v.type, blueprintContext, wfRes) + if (workFlow.inputs != null) { + for ((k, v) in workFlow.inputs!!) { + addPropertyInfo(v, blueprintContext, wfRes) + } } - for ((k, v) in workFlow.outputs!!) { - addDataType(v.type, blueprintContext, wfRes) + if (workFlow.outputs != null) { + for ((k, v) in workFlow.outputs!!) { + addPropertyInfo(v, blueprintContext, wfRes) + } } + wfRes.workFlowData = workFlowData return wfRes } + private fun addPropertyInfo(prop: PropertyDefinition, ctx: BluePrintContext, res: WorkFlowSpecResponse) { + addDataType(prop.type, ctx, res) + if (prop.entrySchema != null && prop.entrySchema!!.type != null) { + addDataType(prop.entrySchema!!.type, ctx, res) + } + } + private fun addDataType(name: String, ctx: BluePrintContext, res: WorkFlowSpecResponse) { var data = ctx.dataTypeByName(name) if (data != null) { @@ -135,8 +154,10 @@ open class BluePrintModelHandler( } private fun addParentDataType(data: DataType, ctx: BluePrintContext, res: WorkFlowSpecResponse) { - for ((k, v) in data.properties!!) { - addDataType(v.type, ctx, res) + if (data.properties != null) { + for ((k, v) in data.properties!!) { + addPropertyInfo(v, ctx, res) + } } } @@ -188,10 +209,8 @@ open class BluePrintModelHandler( try { return upload(filePart, false) } catch (e: IOException) { - throw BluePrintException( - ErrorCode.IO_FILE_INTERRUPT.value, - "Error in Save CBA: ${e.message}", e - ) + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "Error in Save CBA: ${e.message}", e.errorCauseOrDefault()) } } @@ -239,11 +258,11 @@ open class BluePrintModelHandler( val archiveByteArray = download(name, version) val fileName = "${name}_$version.zip" return prepareResourceEntity(fileName, archiveByteArray) - } catch (e: BluePrintException) { - throw BluePrintException( - ErrorCode.RESOURCE_NOT_FOUND.value, - String.format("Error while " + "downloading the CBA file: %s", e.message), e - ) + } catch (e: BluePrintProcessorException) { + e.http(ErrorCatalogCodes.RESOURCE_NOT_FOUND) + val errorMsg = "Error while downloading the CBA file by Blueprint Name ($name) and Version ($version)." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg, + "Wrong resource definition or resolution failed.") } } @@ -259,15 +278,15 @@ open class BluePrintModelHandler( try { blueprintModel = getBlueprintModel(id) } catch (e: BluePrintException) { - throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, String.format("Error while " + "downloading the CBA file: %s", e.message), e) + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + "Error while downloading the CBA file: couldn't get blueprint modelby ID ($id)", + e.errorCauseOrDefault()) } val fileName = "${blueprintModel.artifactName}_${blueprintModel.artifactVersion}.zip" val file = blueprintModel.blueprintModelContent?.content - ?: throw BluePrintException( - ErrorCode.RESOURCE_NOT_FOUND.value, - String.format("Error while downloading the CBA file: couldn't get model content") - ) + ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + "Error while downloading the CBA file: couldn't get model content") return prepareResourceEntity(fileName, file) } @@ -296,7 +315,7 @@ open class BluePrintModelHandler( blueprintModel = dbBlueprintModel.get() } else { val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id) - throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg) + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg) } return blueprintModel } @@ -317,7 +336,7 @@ open class BluePrintModelHandler( return blueprintModel } else { val msg = String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version) - throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg) + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg) } } @@ -331,10 +350,8 @@ open class BluePrintModelHandler( @Throws(BluePrintException::class) open fun getBlueprintModelSearch(id: String): BlueprintModelSearch { return blueprintModelSearchRepository.findById(id) - ?: throw BluePrintException( - ErrorCode.RESOURCE_NOT_FOUND.value, - String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id) - ) + ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)) } /** @@ -385,7 +402,7 @@ open class BluePrintModelHandler( blueprintModelRepository.delete(dbBlueprintModel.get()) } else { val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id) - throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg) + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg) } } @@ -410,11 +427,14 @@ open class BluePrintModelHandler( try { val enhancedByteArray = enrichBlueprintFileSource(filePart) return BluePrintEnhancerUtils.prepareResourceEntity("enhanced-cba.zip", enhancedByteArray) - } catch (e: IOException) { - throw BluePrintException( - ErrorCode.IO_FILE_INTERRUPT.value, - "Error in Enriching CBA: ${e.message}", e - ) + } catch (e: BluePrintProcessorException) { + e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT) + val errorMsg = "Error while enhancing the CBA package." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg, + "Wrong CBA file provided, please verify and enrich Again.") + } catch (e: Exception) { + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "EnrichBlueprint: ${e.message}", e.errorCauseOrDefault()) } } @@ -429,11 +449,14 @@ open class BluePrintModelHandler( open suspend fun publishBlueprint(filePart: FilePart): BlueprintModelSearch { try { return upload(filePart, true) + } catch (e: BluePrintProcessorException) { + e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT) + val errorMsg = "Error in Publishing CBA." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg, + "Wrong CBA provided, please verify and enrich your CBA.") } catch (e: Exception) { - throw BluePrintException( - ErrorCode.IO_FILE_INTERRUPT.value, - "Error in Publishing CBA: ${e.message}", e - ) + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "Error in Publishing CBA: ${e.message}", e.errorCauseOrDefault()) } } @@ -453,15 +476,16 @@ open class BluePrintModelHandler( val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(saveId, compressedFile, validate) return blueprintModelSearchRepository.findById(blueprintId) - ?: throw BluePrintException( - ErrorCode.RESOURCE_NOT_FOUND.value, - String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId) - ) + ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId)) + } catch (e: BluePrintException) { + e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT) + val errorMsg = "Error in Upload CBA." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg, + "Wrong enriched CBA.") } catch (e: IOException) { - throw BluePrintException( - ErrorCode.IO_FILE_INTERRUPT.value, - "Error in Upload CBA: ${e.message}", e - ) + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "Error in Upload CBA: ${e.errorMessageOrDefault()}", e.errorCauseOrDefault()) } finally { // Clean blueprint script cache val cacheKey = BluePrintFileUtils @@ -478,15 +502,13 @@ open class BluePrintModelHandler( try { val blueprintModel = getBlueprintModelByNameAndVersion(name, version) return blueprintModel.blueprintModelContent?.content - ?: throw BluePrintException( - ErrorCode.RESOURCE_NOT_FOUND.value, - String.format("Error while downloading the CBA file: couldn't get model content") - ) + ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + "Error while downloading the CBA file: couldn't get model content") } catch (e: BluePrintException) { - throw BluePrintException( - ErrorCode.RESOURCE_NOT_FOUND.value, - String.format("Error while " + "downloading the CBA file: %s", e.message), e - ) + e.http(ErrorCatalogCodes.RESOURCE_NOT_FOUND) + val errorMsg = "Fail to get Blueprint Model content." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg, + "Wrong name and version was provide.") } } @@ -506,11 +528,13 @@ open class BluePrintModelHandler( bluePrintEnhancerService.enhance(blueprintWorkingDir) return BluePrintEnhancerUtils.compressEnhanceDirAndReturnByteArray(blueprintWorkingDir, blueprintArchive) + } catch (e: BluePrintException) { + e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT) + val errorMsg = "Fail Enriching the CBA." + throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg) } catch (e: IOException) { - throw BluePrintException( - ErrorCode.IO_FILE_INTERRUPT.value, - "Error in Enriching CBA: ${e.message}", e - ) + throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API, + "Error while Enriching the CBA file.", e.errorCauseOrDefault()) } finally { BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir) } diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ModelTypeHandler.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ModelTypeHandler.kt index a364f3678..d11c128f0 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ModelTypeHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ModelTypeHandler.kt @@ -17,10 +17,13 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler +import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.DesignerApiDomains import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.domain.ModelType import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.repository.ModelTypeRepository import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils.ModelTypeValidator import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -42,7 +45,8 @@ open class ModelTypeHandler(private val modelTypeRepository: ModelTypeRepository return if (modelType != null) { modelType } else { - throw BluePrintException("couldn't get modelType($modelTypeName)") + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + "couldn't get modelType($modelTypeName)") } } diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ResourceDictionaryHandler.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ResourceDictionaryHandler.kt index 0f0bfef6d..20895efce 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ResourceDictionaryHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/ResourceDictionaryHandler.kt @@ -20,13 +20,16 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler import com.google.common.base.Preconditions import org.apache.commons.collections.CollectionUtils import org.apache.commons.lang3.StringUtils +import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.DesignerApiDomains import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.domain.ResourceDictionary import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.repository.ResourceDictionaryRepository import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceSourceMapping import org.onap.ccsdk.cds.controllerblueprints.resource.dict.factory.ResourceSourceMappingFactory +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes import org.springframework.stereotype.Service @Service @@ -46,7 +49,8 @@ class ResourceDictionaryHandler(private val resourceDictionaryRepository: Resour return if (resourceDictionaryDb != null) { resourceDictionaryDb } else { - throw BluePrintException(String.format("couldn't get resource dictionary for name (%s)", name)) + throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, + String.format("couldn't get resource dictionary for name (%s)", name)) } } diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandlerTest.kt index 35e440554..d6694de9e 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandlerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandlerTest.kt @@ -54,7 +54,7 @@ import kotlin.test.assertTrue @RunWith(SpringRunner::class) @ContextConfiguration( - classes = [DesignerApiTestConfiguration::class] + classes = [DesignerApiTestConfiguration::class, ErrorCatalogTestConfiguration::class] ) @TestPropertySource(locations = ["classpath:application-test.properties"]) class BluePrintManagementGRPCHandlerTest { diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt index 0e33884a0..9489f2882 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt @@ -63,7 +63,7 @@ import kotlin.test.assertTrue @RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ContextConfiguration( - classes = [DesignerApiTestConfiguration::class] + classes = [DesignerApiTestConfiguration::class, ErrorCatalogTestConfiguration::class] ) @TestPropertySource(locations = ["classpath:application-test.properties"]) @FixMethodOrder(MethodSorters.NAME_ASCENDING) diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorCatalogTestConfiguration.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorCatalogTestConfiguration.kt new file mode 100644 index 000000000..d081dc5ab --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/ErrorCatalogTestConfiguration.kt @@ -0,0 +1,28 @@ +/* + * Copyright © 2020 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. + * 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.designer.api + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan( + basePackages = ["org.onap.ccsdk.cds.error.catalog"] +) +@EnableAutoConfiguration +open class ErrorCatalogTestConfiguration diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties index e22e522ee..5e3e66172 100755 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties @@ -1,5 +1,5 @@ # -# Copyright © 2019 IBM. +# Copyright © 2019 - 2020 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. @@ -36,6 +36,11 @@ blueprintsprocessor.blueprintDeployPath=./target/blueprints/deploy blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive blueprintsprocessor.blueprintWorkingPath=./target/blueprints/work +# Error Managements +error.catalog.applicationId=cds +error.catalog.type=properties +error.catalog.errorDefinitionDir=./../../../application/src/test/resources/ + # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints diff --git a/ms/blueprintsprocessor/modules/inbounds/health-api-common/pom.xml b/ms/blueprintsprocessor/modules/inbounds/health-api-common/pom.xml index 9b98a1fc3..9ee9e98c0 100644 --- a/ms/blueprintsprocessor/modules/inbounds/health-api-common/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/health-api-common/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>inbounds</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>health-api-common</artifactId> diff --git a/ms/blueprintsprocessor/modules/inbounds/health-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/health-api/pom.xml index f9866a8ed..f27b20da1 100644 --- a/ms/blueprintsprocessor/modules/inbounds/health-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/health-api/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>inbounds</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>health-api</artifactId> @@ -35,7 +36,7 @@ <dependency> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>health-api-common</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </dependency> </dependencies> </project> diff --git a/ms/blueprintsprocessor/modules/inbounds/pom.xml b/ms/blueprintsprocessor/modules/inbounds/pom.xml index 88e7ac235..18b6fd00d 100644 --- a/ms/blueprintsprocessor/modules/inbounds/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>modules</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>inbounds</artifactId> diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/resource-api/pom.xml index bec0d1850..42d8f087c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>inbounds</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>resource-api</artifactId> @@ -38,5 +39,9 @@ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprint-core</artifactId> </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.error.catalog</groupId> + <artifactId>error-catalog-services</artifactId> + </dependency> </dependencies> </project> diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt index 264cd23ff..1aae8aa1c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt @@ -23,7 +23,9 @@ import io.swagger.annotations.ApiParam import kotlinx.coroutines.runBlocking import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolution import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.security.access.prepost.PreAuthorize @@ -83,7 +85,8 @@ open class ResourceController(private var resourceResolutionDBService: ResourceR ResponseEntity<List<ResourceResolution>> = runBlocking { if ((resolutionKey.isNotEmpty() || artifactName.isNotEmpty()) && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) { - throw ResolutionException("Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") + throw httpProcessorException(ErrorCatalogCodes.REQUEST_NOT_FOUND, ResourceApiDomains.RESOURCE_API, + "Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") } else if (resolutionKey.isNotEmpty() && artifactName.isNotEmpty()) { ResponseEntity.ok() .body(resourceResolutionDBService.readWithResolutionKey(bpName, bpVersion, artifactName, resolutionKey)) @@ -98,7 +101,8 @@ open class ResourceController(private var resourceResolutionDBService: ResourceR ) ) } else { - throw ResolutionException("Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") + throw httpProcessorException(ErrorCatalogCodes.REQUEST_NOT_FOUND, ResourceApiDomains.RESOURCE_API, + "Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") } } diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt index 5d5623d4f..9c09bd819 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Bell Canada + * Copyright © 2019 - 2020 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. @@ -13,99 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.onap.ccsdk.cds.blueprintsprocessor.resource.api -import com.fasterxml.jackson.annotation.JsonFormat -import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.fasterxml.jackson.annotation.JsonTypeName -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException -import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode -import org.slf4j.LoggerFactory -import org.springframework.dao.EmptyResultDataAccessException -import org.springframework.dao.IncorrectResultSizeDataAccessException -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import org.springframework.orm.jpa.JpaObjectRetrievalFailureException -import org.springframework.web.bind.annotation.ExceptionHandler +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogExceptionHandler +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogService import org.springframework.web.bind.annotation.RestControllerAdvice -import org.springframework.web.server.ServerWebInputException -import java.io.Serializable -import java.util.Date /** * Handle exceptions in Resolution API and provide relevant HTTP status codes and messages * * @author Serge Simard - * @version 1.0 + * @version 2.0 */ @RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.resource.api") -open class ResourceExceptionHandler { - - private val log = LoggerFactory.getLogger(ExceptionHandler::class.toString()) - - private val debugMsg = "Resolution_Service_Error_Message" - - @ExceptionHandler - fun resolutionResultsServiceExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.BLUEPRINT_PATH_MISSING - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resolutionResultsServiceExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.INVALID_REQUEST_FORMAT - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resolutionResultsServiceExceptionHandler(e: IncorrectResultSizeDataAccessException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.DUPLICATE_DATA - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resolutionResultsServiceExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.RESOURCE_NOT_FOUND - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resolutionResultsServiceExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.RESOURCE_NOT_FOUND - return returnError(e, errorCode) - } - - @ExceptionHandler - fun resolutionResultsServiceExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> { - val errorCode = ErrorCode.GENERIC_FAILURE - return returnError(e, errorCode) - } - - fun returnError(e: Exception, errorCode: ErrorCode): ResponseEntity<ErrorMessage> { - log.error(e.message, e) - val errorMessage = - ErrorMessage( - errorCode.message(e.message!!), - errorCode.value, - debugMsg - ) - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)!!) - } - - @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: ResolutionException): ResponseEntity<ErrorMessage> { - log.error(e.message, e) - return ResponseEntity(ErrorMessage(e.message, e.code, debugMsg), HttpStatus.resolve(e.code)) - } -} - -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonTypeName("errorMessage") -@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) -class ErrorMessage(var message: String?, var code: Int?, var debugMessage: String?) : Serializable { - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - var timestamp = Date() -} +open class ResourceExceptionHandler(private val errorCatalogService: ErrorCatalogService) : + ErrorCatalogExceptionHandler(errorCatalogService) diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt index 5913bde1d..80000d5fc 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt @@ -23,7 +23,9 @@ import io.swagger.annotations.ApiParam import kotlinx.coroutines.runBlocking import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolution import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService +import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.security.access.prepost.PreAuthorize @@ -99,7 +101,8 @@ open class TemplateController(private val templateResolutionService: TemplateRes var result = "" if ((resolutionKey.isNotEmpty() || artifactName.isNotEmpty()) && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) { - throw ResolutionException("Either retrieve resolved template using artifact name and resolution-key OR using resource-id and resource-type.") + throw httpProcessorException(ErrorCatalogCodes.REQUEST_NOT_FOUND, ResourceApiDomains.RESOURCE_API, + "Either retrieve resolved template using artifact name and resolution-key OR using resource-id and resource-type.") } else if (resolutionKey.isNotEmpty() && artifactName.isNotEmpty()) { result = templateResolutionService.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( bpName, @@ -117,7 +120,8 @@ open class TemplateController(private val templateResolutionService: TemplateRes resourceType ) } else { - throw ResolutionException("Missing param. Either retrieve resolved template using artifact name and resolution-key OR using resource-id and resource-type.") + throw httpProcessorException(ErrorCatalogCodes.REQUEST_NOT_FOUND, ResourceApiDomains.RESOURCE_API, + "Missing param. Either retrieve resolved template using artifact name and resolution-key OR using resource-id and resource-type.") } var expectedContentType = format diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorCatalogTestConfiguration.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorCatalogTestConfiguration.kt new file mode 100644 index 000000000..5b0d1980b --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ErrorCatalogTestConfiguration.kt @@ -0,0 +1,28 @@ +/* + * Copyright © 2020 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. + * 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.resource.api + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan( + basePackages = ["org.onap.ccsdk.cds.error.catalog"] +) +@EnableAutoConfiguration +open class ErrorCatalogTestConfiguration diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceControllerTest.kt index dab96527d..c5e002f08 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceControllerTest.kt @@ -27,6 +27,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment +import org.onap.ccsdk.cds.error.catalog.core.ErrorPayload import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest @@ -39,7 +40,7 @@ import org.springframework.test.web.reactive.server.WebTestClient @RunWith(SpringRunner::class) @WebFluxTest @ContextConfiguration( - classes = [TestDatabaseConfiguration::class, + classes = [TestDatabaseConfiguration::class, ErrorCatalogTestConfiguration::class, ResourceController::class, ResourceResolutionDBService::class] ) @ComponentScan( @@ -147,9 +148,11 @@ class ResourceControllerTest { .expectStatus().is4xxClientError .expectBody() .consumeWith { - val r = JacksonUtils.objectMapper.readValue(it.responseBody, ErrorMessage::class.java) + val r = JacksonUtils.objectMapper.readValue(it.responseBody, ErrorPayload::class.java) Assert.assertEquals( - "Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.", + "Cause: Missing param. Either retrieve resolved value using artifact name and " + + "resolution-key OR using resource-id and resource-type. \n" + + " Action : Please verify your request.", r.message ) } @@ -166,9 +169,10 @@ class ResourceControllerTest { .expectStatus().is4xxClientError .expectBody() .consumeWith { - val r = JacksonUtils.objectMapper.readValue(it.responseBody, ErrorMessage::class.java) + val r = JacksonUtils.objectMapper.readValue(it.responseBody, ErrorPayload::class.java) Assert.assertEquals( - "Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.", + "Cause: Either retrieve resolved value using artifact name and resolution-key OR using " + + "resource-id and resource-type. \n Action : Please verify your request.", r.message ) } diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt index 09b2c5bf7..098423540 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt @@ -38,7 +38,7 @@ import kotlin.test.AfterTest @WebFluxTest @ContextConfiguration( classes = [TestDatabaseConfiguration::class, BluePrintCoreConfiguration::class, - BluePrintCatalogService::class] + BluePrintCatalogService::class, ErrorCatalogTestConfiguration::class] ) @ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) @TestPropertySource(locations = ["classpath:application-test.properties"]) @@ -120,7 +120,7 @@ class TemplateControllerTest { webTestClient.get().uri("/api/v1/template?$arguments") .exchange() - .expectStatus().isBadRequest + .expectStatus().isNotFound } } diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/resources/application-test.properties index cb7837ba4..ee7d6e611 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/resources/application-test.properties @@ -1,7 +1,7 @@ # -# Copyright � 2017-2018 AT&T Intellectual Property. +# Copyright (c) 2017-2018 AT&T Intellectual Property. # -# Modifications Copyright � 2019 IBM, Bell Canada. +# Modifications Copyright (c) 2019 - 2020 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. @@ -28,6 +28,11 @@ blueprintsprocessor.blueprintDeployPath=./target/blueprints/deploy blueprintsprocessor.blueprintWorkingPath=./target/blueprints/work blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive +# Error Managements +error.catalog.applicationId=cds +error.catalog.type=properties +error.catalog.errorDefinitionDir=./../../../application/src/test/resources/ + # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml index 5e3ce2cc9..616b8e144 100755 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml @@ -17,13 +17,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>inbounds</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>selfservice-api</artifactId> @@ -41,6 +42,10 @@ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>blueprint-validation</artifactId> </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.error.catalog</groupId> + <artifactId>error-catalog-services</artifactId> + </dependency> <!-- For Message libraries --> <dependency> 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 305437923..46d91e57c 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 @@ -17,13 +17,19 @@ package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api +import io.grpc.Status import io.grpc.stub.StreamObserver import kotlinx.coroutines.runBlocking import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintCoreConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.toJava +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes +import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault +import org.onap.ccsdk.cds.error.catalog.core.utils.errorMessageOrDefault +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogService import org.slf4j.LoggerFactory import org.springframework.security.access.prepost.PreAuthorize import org.springframework.stereotype.Service @@ -33,7 +39,8 @@ import javax.annotation.PreDestroy @Service open class BluePrintProcessingGRPCHandler( private val bluePrintCoreConfiguration: BluePrintCoreConfiguration, - private val executionServiceHandler: ExecutionServiceHandler + private val executionServiceHandler: ExecutionServiceHandler, + private val errorCatalogService: ErrorCatalogService ) : BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase() { @@ -62,10 +69,29 @@ open class BluePrintProcessingGRPCHandler( override fun onError(error: Throwable) { log.debug("Fail to process message", error) + if (error is BluePrintProcessorException) onErrorCatalog(error) else onError(error) + } + + fun onError(error: Exception) { + responseObserver.onError( + Status.INTERNAL + .withDescription(error.errorMessageOrDefault()) + .withCause(error.errorCauseOrDefault()) + .asException() + ) + } + + fun onErrorCatalog(error: BluePrintProcessorException) { + if (error.protocol == "") { + error.grpc(ErrorCatalogCodes.GENERIC_FAILURE) + } + val errorPayload = errorCatalogService.errorPayload(error) + val grpcCode = Status.fromCodeValue(errorPayload.code) responseObserver.onError( - io.grpc.Status.INTERNAL - .withDescription(error.message) - .asException() + grpcCode + .withDescription(errorPayload.message) + .withCause(error.errorCauseOrDefault()) + .asException() ) } 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 6293f48f4..49f2a50d5 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 @@ -25,6 +25,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BlueprintMessageCo import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsType import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.event.ApplicationReadyEvent import org.springframework.context.event.EventListener @@ -50,33 +51,27 @@ open class BluePrintProcessingKafkaConsumer( companion object { const val CONSUMER_SELECTOR = "self-service-api" - const val PRODUCER_SELECTOR = "self-service-api" } @EventListener(ApplicationReadyEvent::class) fun setupMessageListener() = runBlocking { try { log.info( - "Setting up message consumer($CONSUMER_SELECTOR) and " + - "message producer($PRODUCER_SELECTOR)..." + "Setting up message consumer($CONSUMER_SELECTOR)" ) /** Get the Message Consumer Service **/ blueprintMessageConsumerService = try { bluePrintMessageLibPropertyService .blueprintMessageConsumerService(CONSUMER_SELECTOR) + } catch (e: BluePrintProcessorException) { + val errorMsg = "Failed creating Kafka consumer message service." + throw e.updateErrorMessage(SelfServiceApiDomains.SELF_SERVICE_API, errorMsg, + "Wrong Kafka selector provided or internal error in Kafka service.") } catch (e: Exception) { throw BluePrintProcessorException("failed to create consumer service ${e.message}") } - /** Get the Message Producer Service **/ - val blueprintMessageProducerService = try { - bluePrintMessageLibPropertyService - .blueprintMessageProducerService(PRODUCER_SELECTOR) - } catch (e: Exception) { - throw BluePrintProcessorException("failed to create producer service ${e.message}") - } - launch { /** Subscribe to the consumer topics */ val additionalConfig: MutableMap<String, Any> = hashMapOf() @@ -87,10 +82,7 @@ open class BluePrintProcessingKafkaConsumer( ph.register() log.trace("Consumed Message : $message") val executionServiceInput = message.jsonAsType<ExecutionServiceInput>() - val executionServiceOutput = executionServiceHandler.doProcess(executionServiceInput) - // TODO("In future, Message publisher configuration vary with respect to request") - /** Send the response message */ - blueprintMessageProducerService.sendMessage(executionServiceOutput) + executionServiceHandler.doProcess(executionServiceInput) } catch (e: Exception) { log.error("failed in processing the consumed message : $message", e) } finally { @@ -101,8 +93,7 @@ open class BluePrintProcessingKafkaConsumer( } } catch (e: Exception) { log.error( - "failed to start message consumer($CONSUMER_SELECTOR) and " + - "message producer($PRODUCER_SELECTOR) ", e + "failed to start message consumer($CONSUMER_SELECTOR) ", e ) } } @@ -111,8 +102,7 @@ open class BluePrintProcessingKafkaConsumer( fun shutdownMessageListener() = runBlocking { try { log.info( - "Shutting down message consumer($CONSUMER_SELECTOR) and " + - "message producer($PRODUCER_SELECTOR)..." + "Shutting down message consumer($CONSUMER_SELECTOR)" ) blueprintMessageConsumerService.shutDown() ph.arriveAndAwaitAdvance() diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt index b76bc263a..c4baa854c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorHandling.kt @@ -21,12 +21,6 @@ object SelfServiceApiDomains { const val BLUEPRINT_PROCESSOR = "org.onap.ccsdk.cds.blueprintsprocessor" const val SELF_SERVICE_API = "org.onap.ccsdk.cds.blueprintsprocessor.resource.api" const val SELF_SERVICE_API_VALIDATOR = "org.onap.ccsdk.cds.blueprintsprocessor.resource.api.validator" - const val NETCONF_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor" - const val RESOURCE_RESOLUTION = "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution" - const val RESTCONF_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.restconf.executor" - const val CLI_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor" - const val PYTHON_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor" - const val SDC_LISTENER = "org.onap.ccsdk.cds.sdclistener" } object SelfServiceApiHttpErrorCodes { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceExceptionHandler.kt new file mode 100644 index 000000000..57c02fe6a --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceExceptionHandler.kt @@ -0,0 +1,32 @@ +/* + * Copyright © 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api + +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogExceptionHandler +import org.onap.ccsdk.cds.error.catalog.services.ErrorCatalogService +import org.springframework.web.bind.annotation.RestControllerAdvice + +/** + * ExecutionServiceExceptionHandler.kt Purpose: Handle exceptions in selfservice API and provide the right + * HTTP code status + * + * @author Steve Siani + * @version 1.0 + */ +@RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api") +class ExecutionServiceExceptionHandler(private val errorCatalogService: ErrorCatalogService) : + ErrorCatalogExceptionHandler(errorCatalogService) diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt index 9524e375e..74c4b00e4 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt @@ -44,7 +44,8 @@ class ExecutionServiceHandler( private val bluePrintLoadConfiguration: BluePrintLoadConfiguration, private val blueprintsProcessorCatalogService: BluePrintCatalogService, private val bluePrintWorkflowExecutionService: - BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput> + BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput>, + private val publishAuditService: PublishAuditService ) { private val log = LoggerFactory.getLogger(ExecutionServiceHandler::class.toString()) @@ -67,33 +68,44 @@ class ExecutionServiceHandler( responseObserver.onNext(executionServiceOutput.toProto()) responseObserver.onCompleted() } - else -> responseObserver.onNext( - response( - executionServiceInput, - "Failed to process request, 'actionIdentifiers.mode' not specified. Valid value are: 'sync' or 'async'.", - true - ).toProto() - ) + else -> { + publishAuditService.publish(executionServiceInput) + val executionServiceOutput = response( + executionServiceInput, + "Failed to process request, 'actionIdentifiers.mode' not specified. Valid value are: 'sync' or 'async'.", + true + ) + publishAuditService.publish(executionServiceOutput) + responseObserver.onNext( + executionServiceOutput.toProto() + ) + } } } suspend fun doProcess(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput { val requestId = executionServiceInput.commonHeader.requestId - log.info("processing request id $requestId") val actionIdentifiers = executionServiceInput.actionIdentifiers val blueprintName = actionIdentifiers.blueprintName val blueprintVersion = actionIdentifiers.blueprintVersion + + lateinit var executionServiceOutput: ExecutionServiceOutput + + log.info("processing request id $requestId") + try { + publishAuditService.publish(executionServiceInput) + /** Check Blueprint is needed for this request */ if (checkServiceFunction(executionServiceInput)) { - return executeServiceFunction(executionServiceInput) + executionServiceOutput = executeServiceFunction(executionServiceInput) } else { val basePath = blueprintsProcessorCatalogService.getFromDatabase(blueprintName, blueprintVersion) log.info("blueprint base path $basePath") val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(requestId, basePath.toString()) - val output = bluePrintWorkflowExecutionService.executeBluePrintWorkflow( + executionServiceOutput = bluePrintWorkflowExecutionService.executeBluePrintWorkflow( blueprintRuntimeService, executionServiceInput, hashMapOf() ) @@ -101,14 +113,16 @@ class ExecutionServiceHandler( val errors = blueprintRuntimeService.getBluePrintError().errors if (errors.isNotEmpty()) { val errorMessage = errors.stream().map { it.toString() }.collect(Collectors.joining(", ")) - setErrorStatus(errorMessage, output.status) + setErrorStatus(errorMessage, executionServiceOutput.status) } - return output } } catch (e: Exception) { log.error("fail processing request id $requestId", e) - return response(executionServiceInput, e.localizedMessage ?: e.message ?: e.toString(), true) + executionServiceOutput = response(executionServiceInput, e.localizedMessage ?: e.message ?: e.toString(), true) } + + publishAuditService.publish(executionServiceOutput) + return executionServiceOutput } /** If the blueprint name is default, It means no blueprint is needed for the execution */ diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/KafkaPublishAuditService.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/KafkaPublishAuditService.kt new file mode 100644 index 000000000..129e7a54d --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/KafkaPublishAuditService.kt @@ -0,0 +1,184 @@ +/* + * Copyright © 2020 Bell Canada + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ObjectNode +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BluePrintMessageLibPropertyService +import org.onap.ccsdk.cds.blueprintsprocessor.message.service.BlueprintMessageProducerService +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.common.ApplicationConstants +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.PropertyDefinitionUtils +import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment +import org.slf4j.LoggerFactory +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.stereotype.Service +import javax.annotation.PostConstruct + +/** + * Audit service used to produce execution service input and output message + * sent into dedicated kafka topics. + */ +@ConditionalOnProperty( + name = ["blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable"], + havingValue = "true" +) +@Service +class KafkaPublishAuditService( + private val bluePrintMessageLibPropertyService: BluePrintMessageLibPropertyService, + private val blueprintsProcessorCatalogService: BluePrintCatalogService +) : PublishAuditService { + + private var inputInstance: BlueprintMessageProducerService? = null + private var outputInstance: BlueprintMessageProducerService? = null + + private lateinit var correlationUUID: String + + private val log = LoggerFactory.getLogger(KafkaPublishAuditService::class.toString()) + + companion object { + const val INPUT_SELECTOR = "self-service-api.audit.request" + const val OUTPUT_SELECTOR = "self-service-api.audit.response" + } + + @PostConstruct + private fun init() { + log.info("Kakfa audit service is enabled") + } + + /** + * Publish execution input into a kafka topic. + * The correlation UUID is used to link the input to its output. + * Sensitive data within the request are hidden. + */ + override suspend fun publish(executionServiceInput: ExecutionServiceInput) { + this.correlationUUID = executionServiceInput.correlationUUID + val secureExecutionServiceInput = hideSensitiveData(executionServiceInput) + this.inputInstance = this.getInputInstance(INPUT_SELECTOR) + this.inputInstance!!.sendMessage(secureExecutionServiceInput) + } + + /** + * Publish execution output into a kafka topic. + * The correlation UUID is used to link the output to its input. + * A correlation UUID is added to link the input to its output. + */ + override fun publish(executionServiceOutput: ExecutionServiceOutput) { + executionServiceOutput.correlationUUID = this.correlationUUID + this.outputInstance = this.getOutputInstance(OUTPUT_SELECTOR) + this.outputInstance!!.sendMessage(executionServiceOutput) + } + + /** + * Return the input kafka producer instance using a selector. + */ + private fun getInputInstance(selector: String): BlueprintMessageProducerService = inputInstance ?: createInstance(selector) + + /** + * Return the output kafka producer instance using a selector. + */ + private fun getOutputInstance(selector: String): BlueprintMessageProducerService = outputInstance ?: createInstance(selector) + + /** + * Create a kafka producer instance. + */ + private fun createInstance(selector: String): BlueprintMessageProducerService { + log.info( + "Setting up message producer($selector)..." + ) + return try { + bluePrintMessageLibPropertyService + .blueprintMessageProducerService(selector) + } catch (e: Exception) { + throw BluePrintProcessorException("failed to create producer service ${e.message}") + } + } + + /** + * Hide sensitive data in the request. + * Sensitive data are declared in the resource resolution mapping using + * the property metadata "log-protect" set to true. + */ + private suspend fun hideSensitiveData( + executionServiceInput: ExecutionServiceInput + ): ExecutionServiceInput { + + var clonedExecutionServiceInput = ExecutionServiceInput().apply { + correlationUUID = executionServiceInput.correlationUUID + commonHeader = executionServiceInput.commonHeader + actionIdentifiers = executionServiceInput.actionIdentifiers + payload = executionServiceInput.payload + } + + val blueprintName = clonedExecutionServiceInput.actionIdentifiers.blueprintName + val workflowName = clonedExecutionServiceInput.actionIdentifiers.actionName + + if (blueprintName == "default") return clonedExecutionServiceInput + + if (clonedExecutionServiceInput.payload + .path("$workflowName-request").has("$workflowName-properties")) { + + /** Retrieving sensitive input parameters */ + val requestId = clonedExecutionServiceInput.commonHeader.requestId + val blueprintVersion = clonedExecutionServiceInput.actionIdentifiers.blueprintVersion + + val basePath = blueprintsProcessorCatalogService.getFromDatabase(blueprintName, blueprintVersion) + + val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(requestId, basePath.toString()) + val blueprintContext = blueprintRuntimeService.bluePrintContext() + + val nodeTemplateName = blueprintContext.workflowFirstStepNodeTemplate(workflowName) + val interfaceName = blueprintContext.nodeTemplateFirstInterfaceName(nodeTemplateName) + val operationName = blueprintContext.nodeTemplateFirstInterfaceFirstOperationName(nodeTemplateName) + + val propertyAssignments: MutableMap<String, JsonNode> = + blueprintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName) + ?: hashMapOf() + + val artifactPrefixNamesNode = propertyAssignments[ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES] + val artifactPrefixNames = JacksonUtils.getListFromJsonNode(artifactPrefixNamesNode!!, String::class.java) + + /** Storing mapping entries with metadata log-protect set to true */ + val sensitiveParameters: List<String> = artifactPrefixNames + .map { "$it-mapping" } + .map { blueprintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, it) } + .flatMap { JacksonUtils.getListFromJson(it, ResourceAssignment::class.java) } + .filter { PropertyDefinitionUtils.hasLogProtect(it.property) } + .map { it.name } + + /** Hiding sensitive input parameters from the request */ + var workflowProperties: ObjectNode = clonedExecutionServiceInput.payload + .path("$workflowName-request") + .path("$workflowName-properties") as ObjectNode + + sensitiveParameters.forEach { sensitiveParameter -> + if (workflowProperties.has(sensitiveParameter)) { + workflowProperties.remove(sensitiveParameter) + workflowProperties.put(sensitiveParameter, ApplicationConstants.LOG_REDACTED) + } + } + } + + return clonedExecutionServiceInput + } +} diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/NoPublishAuditService.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/NoPublishAuditService.kt new file mode 100644 index 000000000..3f782000b --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/NoPublishAuditService.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2020 Bell Canada + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api + +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput +import org.onap.ccsdk.cds.controllerblueprints.core.logger +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.stereotype.Service +import javax.annotation.PostConstruct + +/** + * Default audit service when no audit publisher is defined, message aren't sent + */ +@ConditionalOnProperty( + name = ["blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable"], + havingValue = "false" +) +@Service +class NoPublishAuditService : PublishAuditService { + + val log = logger(NoPublishAuditService::class) + + @PostConstruct + fun init() { + log.info("Audit service is disabled") + } + + override suspend fun publish(executionServiceInput: ExecutionServiceInput) { + } + + override fun publish(executionServiceOutput: ExecutionServiceOutput) { + } +} diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResolutionException.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/PublishAuditService.kt index 62e89e260..535a5eae0 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResolutionException.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/PublishAuditService.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2019 Bell Canada. + * Copyright © 2020 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 + * 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, @@ -13,8 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.resource.api -class ResolutionException(message: String) : RuntimeException(message) { - var code: Int = 404 +package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api + +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput + +interface PublishAuditService { + suspend fun publish(executionServiceInput: ExecutionServiceInput) + fun publish(executionServiceOutput: ExecutionServiceOutput) } diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt index af23e7902..f33f1149f 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandlerTest.kt @@ -42,7 +42,8 @@ import kotlin.test.BeforeTest @RunWith(SpringRunner::class) @DirtiesContext @ContextConfiguration( - classes = [SelfServiceApiTestConfiguration::class, TestDatabaseConfiguration::class] + classes = [SelfServiceApiTestConfiguration::class, TestDatabaseConfiguration::class, + ErrorCatalogTestConfiguration::class] ) @TestPropertySource(locations = ["classpath:application-test.properties"]) class BluePrintProcessingGRPCHandlerTest { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingIntegrationTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingIntegrationTest.kt index b26781ad2..825b0c82a 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingIntegrationTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingIntegrationTest.kt @@ -30,7 +30,11 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput +import org.springframework.test.context.ContextConfiguration +@ContextConfiguration( + classes = [SelfServiceApiTestConfiguration::class, ErrorCatalogTestConfiguration::class] +) class BluePrintProcessingIntegrationTest { private val log = logger(BluePrintProcessingIntegrationTest::class) diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumerTest.kt index f71d1b444..ed573d72f 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/BluePrintProcessingKafkaConsumerTest.kt @@ -35,8 +35,8 @@ import kotlin.test.assertNotNull @RunWith(SpringRunner::class) @ContextConfiguration( - classes = [BluePrintMessageLibConfiguration::class, - BluePrintPropertyConfiguration::class, BluePrintPropertiesService::class] + classes = [BluePrintMessageLibConfiguration::class, SelfServiceApiTestConfiguration::class, + BluePrintPropertyConfiguration::class, BluePrintPropertiesService::class, ErrorCatalogTestConfiguration::class] ) @TestPropertySource(locations = ["classpath:application-test.properties"]) class BluePrintProcessingKafkaConsumerTest { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorCatalogTestConfiguration.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorCatalogTestConfiguration.kt new file mode 100644 index 000000000..a773b4cc5 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ErrorCatalogTestConfiguration.kt @@ -0,0 +1,28 @@ +/* + * Copyright © 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan( + basePackages = ["org.onap.ccsdk.cds.error.catalog"] +) +@EnableAutoConfiguration +open class ErrorCatalogTestConfiguration diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceControllerTest.kt index 255220fc5..f2c77d6f8 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceControllerTest.kt @@ -29,7 +29,6 @@ import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest -import org.springframework.context.annotation.ComponentScan import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner @@ -45,11 +44,7 @@ import kotlin.test.assertTrue @WebFluxTest @ContextConfiguration( classes = [ExecutionServiceHandler::class, BluePrintCoreConfiguration::class, - BluePrintCatalogService::class] -) -@ComponentScan( - basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", - "org.onap.ccsdk.cds.controllerblueprints"] + BluePrintCatalogService::class, SelfServiceApiTestConfiguration::class, ErrorCatalogTestConfiguration::class] ) @TestPropertySource(locations = ["classpath:application-test.properties"]) class ExecutionServiceControllerTest { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt index 5a44403e1..37f7861be 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt @@ -16,6 +16,11 @@ package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api +import io.mockk.verify +import io.mockk.coVerify +import io.mockk.Runs +import io.mockk.coEvery +import io.mockk.just import io.mockk.mockk import kotlinx.coroutines.runBlocking import org.junit.Before @@ -23,6 +28,7 @@ import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractServiceFunction import org.onap.ccsdk.cds.controllerblueprints.core.jsonAsJsonType import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService @@ -30,13 +36,16 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.stereotype.Service import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner import kotlin.test.Test import kotlin.test.assertNotNull import kotlin.test.assertTrue @RunWith(SpringRunner::class) -@ContextConfiguration(classes = [MockServiceAction::class]) +@ContextConfiguration(classes = [MockServiceAction::class, SelfServiceApiTestConfiguration::class, + ErrorCatalogTestConfiguration::class]) +@TestPropertySource(locations = ["classpath:application-test.properties"]) class ExecutionServiceHandlerTest { @Autowired @@ -62,13 +71,52 @@ class ExecutionServiceHandlerTest { } } runBlocking { - val executionServiceHandler = ExecutionServiceHandler(mockk(), mockk(), mockk()) + val executionServiceHandler = ExecutionServiceHandler(mockk(), mockk(), mockk(), mockk()) val isServiceFunction = executionServiceHandler.checkServiceFunction(executionServiceInput) assertTrue(isServiceFunction, "failed to checkServiceFunction") val executionServiceOutput = executionServiceHandler.executeServiceFunction(executionServiceInput) assertNotNull(executionServiceOutput, "failed to get executionServiceOutput") } } + + @Test + fun testPublishAuditFunction() { + val executionServiceInput = ExecutionServiceInput().apply { + commonHeader = CommonHeader().apply { + requestId = "1234" + subRequestId = "1234-12" + originatorId = "cds-test" + } + actionIdentifiers = ActionIdentifiers().apply { + blueprintName = "default" + blueprintVersion = "1.0.0" + actionName = "mock-service-action" + } + } + + val publishAuditService = mockk<KafkaPublishAuditService>(relaxed = true) + val executionServiceHandler = ExecutionServiceHandler( + mockk(), + mockk(), + mockk(), + publishAuditService + ) + + coEvery { publishAuditService.publish(ExecutionServiceInput()) } just Runs + + var executionServiceOutput: ExecutionServiceOutput? = null + runBlocking { + executionServiceOutput = executionServiceHandler.doProcess(executionServiceInput) + } + + coVerify { + publishAuditService.publish(executionServiceInput) + } + + verify { + publishAuditService.publish(executionServiceOutput!!) + } + } } @Service("mock-service-action") diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties index d18b70010..77b61a421 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/application-test.properties @@ -1,7 +1,7 @@ # # Copyright © 2017-2018 AT&T Intellectual Property. # -# Modifications Copyright © 2019 IBM, Bell Canada. +# Modifications Copyright © 2019 - 2020 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. @@ -28,20 +28,43 @@ blueprintsprocessor.blueprintDeployPath=./target/blueprints/deploy blueprintsprocessor.blueprintWorkingPath=./target/blueprints/work blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive +# Error Managements +error.catalog.applicationId=cds +error.catalog.type=properties +error.catalog.errorDefinitionDir=./../../../application/src/test/resources/ + # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints -# Kafka-message-lib Configuration +# Kafka-message-lib Configurations blueprintsprocessor.messageconsumer.self-service-api.kafkaEnable=false -blueprintsprocessor.messageconsumer.self-service-api.type=kafka-basic-auth +blueprintsprocessor.messageconsumer.self-service-api.type=kafka-scram-ssl-auth blueprintsprocessor.messageconsumer.self-service-api.bootstrapServers=127.0.0.1:9092 -blueprintsprocessor.messageconsumer.self-service-api.topic=receiver.t blueprintsprocessor.messageconsumer.self-service-api.groupId=receiver-id -blueprintsprocessor.messageconsumer.self-service-api.clientId=default-client-id -blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=10 +blueprintsprocessor.messageconsumer.self-service-api.topic=receiver.t +blueprintsprocessor.messageconsumer.self-service-api.clientId=request-receiver-client-id +blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=1000 +### Security settings +### SSL +blueprintsprocessor.messageconsumer.self-service-api.truststore=src/test/resources/test.truststore.jks +blueprintsprocessor.messageconsumer.self-service-api.truststorePassword=secretpassword +blueprintsprocessor.messageconsumer.self-service-api.keystore=src/test/resources/test.keystore.jks +blueprintsprocessor.messageconsumer.self-service-api.keystorePassword=secretpassword +### SCRAM +blueprintsprocessor.messageconsumer.self-service-api.scramUsername=test-user +blueprintsprocessor.messageconsumer.self-service-api.scramPassword=testUserPassword + +# Kafka audit service Configurations +## Audit request +blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable=false +blueprintsprocessor.messageproducer.self-service-api.audit.request.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.request.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.request.clientId=audit-request-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.request.topic=audit-request-producer.t -blueprintsprocessor.messageproducer.self-service-api.type=kafka-basic-auth -blueprintsprocessor.messageproducer.self-service-api.bootstrapServers=127.0.0.1:9092 -blueprintsprocessor.messageproducer.self-service-api.clientId=default-client-id -blueprintsprocessor.messageproducer.self-service-api.topic=producer.t +## Audit response +blueprintsprocessor.messageproducer.self-service-api.audit.response.type=kafka-basic-auth +blueprintsprocessor.messageproducer.self-service-api.audit.response.bootstrapServers=127.0.0.1:9092 +blueprintsprocessor.messageproducer.self-service-api.audit.response.clientId=audit-response-producer-client-id +blueprintsprocessor.messageproducer.self-service-api.audit.response.topic=audit-response-producer.t diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/test.keystore.jks b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/test.keystore.jks Binary files differnew file mode 100644 index 000000000..1a4150952 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/test.keystore.jks diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/test.truststore.jks b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/test.truststore.jks Binary files differnew file mode 100644 index 000000000..b094a1f8a --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/resources/test.truststore.jks diff --git a/ms/blueprintsprocessor/modules/outbounds/pom.xml b/ms/blueprintsprocessor/modules/outbounds/pom.xml index e6739571d..49279c926 100644 --- a/ms/blueprintsprocessor/modules/outbounds/pom.xml +++ b/ms/blueprintsprocessor/modules/outbounds/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>modules</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>outbounds</artifactId> diff --git a/ms/blueprintsprocessor/modules/pom.xml b/ms/blueprintsprocessor/modules/pom.xml index 3f6d915bd..fd9a1e7ca 100644 --- a/ms/blueprintsprocessor/modules/pom.xml +++ b/ms/blueprintsprocessor/modules/pom.xml @@ -16,13 +16,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../parent</relativePath> </parent> diff --git a/ms/blueprintsprocessor/modules/services/execution-service/pom.xml b/ms/blueprintsprocessor/modules/services/execution-service/pom.xml index 15e715249..a81723663 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/pom.xml +++ b/ms/blueprintsprocessor/modules/services/execution-service/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>services</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>execution-service</artifactId> diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt index 3e329d7f5..aa39a1dd0 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt @@ -134,6 +134,7 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic try { prepareRequestNB(executionServiceInput) withTimeout((implementation.timeout * 1000).toLong()) { + log.debug("DEBUG::: AbstractComponentFunction.withTimeout section ${implementation.timeout} seconds") processNB(executionServiceInput) } } catch (runtimeException: RuntimeException) { diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ErrorHandling.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ErrorHandling.kt new file mode 100644 index 000000000..fd7cde4d0 --- /dev/null +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ErrorHandling.kt @@ -0,0 +1,42 @@ +/* + * Copyright © 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.services.execution + +object ExecutionServiceDomains { + // ExecutionService Domains Constants + const val BLUEPRINT_PROCESSOR = "org.onap.ccsdk.cds.blueprintsprocessor" + const val NETCONF_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor" + const val RESOURCE_RESOLUTION = "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution" + const val RESTCONF_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.restconf.executor" + const val CLI_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor" + const val PYTHON_EXECUTOR = "org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor" + const val SDC_LISTENER = "org.onap.ccsdk.cds.sdclistener" +} + +object ExecutionServiceHttpErrorCodes { + init { + // Register HttpErrorCodes + // HttpErrorCodes.register("", 200) + } +} + +object ExecutionServiceGrpcErrorCodes { + init { + // Register GrpcErrorCodes + // GrpcErrorCodes.register("", 3) + } +} diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt index 3b83261e5..861a95507 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt @@ -41,6 +41,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.context.annotation.Scope import org.springframework.stereotype.Service +import java.util.concurrent.TimeUnit interface RemoteScriptExecutionService { suspend fun init(selector: Any) @@ -65,12 +66,12 @@ class GrpcRemoteScriptExecutionService(private val bluePrintGrpcLibPropertyServi override suspend fun init(selector: Any) { // Get the GRPC Client Service based on selector - val grpcClientService: BluePrintGrpcClientService - if (selector is JsonNode) { - grpcClientService = bluePrintGrpcLibPropertyService.blueprintGrpcClientService(selector) + val grpcClientService: BluePrintGrpcClientService = if (selector is JsonNode) { + bluePrintGrpcLibPropertyService.blueprintGrpcClientService(selector) } else { - grpcClientService = bluePrintGrpcLibPropertyService.blueprintGrpcClientService(selector.toString()) + bluePrintGrpcLibPropertyService.blueprintGrpcClientService(selector.toString()) } + // Get the GRPC Channel channel = grpcClientService.channel() // Create Non Blocking Stub @@ -81,9 +82,10 @@ class GrpcRemoteScriptExecutionService(private val bluePrintGrpcLibPropertyServi } } - override suspend fun prepareEnv(prepareEnvInput: PrepareRemoteEnvInput): - RemoteScriptExecutionOutput { - val grpResponse = commandExecutorServiceGrpc.prepareEnv(prepareEnvInput.asGrpcData()) + override suspend fun prepareEnv(prepareEnvInput: PrepareRemoteEnvInput): RemoteScriptExecutionOutput { + val grpResponse = commandExecutorServiceGrpc + .withDeadlineAfter(prepareEnvInput.timeOut * 1000, TimeUnit.MILLISECONDS) + .prepareEnv(prepareEnvInput.asGrpcData()) checkNotNull(grpResponse.status) { "failed to get GRPC prepare env response status for requestId(${prepareEnvInput.requestId})" @@ -95,19 +97,18 @@ class GrpcRemoteScriptExecutionService(private val bluePrintGrpcLibPropertyServi return remoteScriptExecutionOutput } - override suspend fun executeCommand(remoteExecutionInput: RemoteScriptExecutionInput): - RemoteScriptExecutionOutput { - - val grpResponse = commandExecutorServiceGrpc.executeCommand(remoteExecutionInput.asGrpcData()) + override suspend fun executeCommand(remoteExecutionInput: RemoteScriptExecutionInput): RemoteScriptExecutionOutput { + val grpResponse = + commandExecutorServiceGrpc + .withDeadlineAfter(remoteExecutionInput.timeOut * 1000, TimeUnit.MILLISECONDS) + .executeCommand(remoteExecutionInput.asGrpcData()) checkNotNull(grpResponse.status) { "failed to get GRPC response status for requestId(${remoteExecutionInput.requestId})" } - val remoteScriptExecutionOutput = grpResponse.asJavaData() log.debug("Received response from command server for requestId(${remoteExecutionInput.requestId})") - - return remoteScriptExecutionOutput + return grpResponse.asJavaData() } override suspend fun close() { diff --git a/ms/blueprintsprocessor/modules/services/pom.xml b/ms/blueprintsprocessor/modules/services/pom.xml index 604cdb19d..da4581fd5 100755 --- a/ms/blueprintsprocessor/modules/services/pom.xml +++ b/ms/blueprintsprocessor/modules/services/pom.xml @@ -17,13 +17,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>modules</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>services</artifactId> diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/pom.xml b/ms/blueprintsprocessor/modules/services/workflow-service/pom.xml index 98bb82397..cfc03e7dc 100644 --- a/ms/blueprintsprocessor/modules/services/workflow-service/pom.xml +++ b/ms/blueprintsprocessor/modules/services/workflow-service/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>services</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>workflow-service</artifactId> diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index 546156d47..a71392b00 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>blueprintsprocessor</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>Blueprints Processor Parent</name> diff --git a/ms/blueprintsprocessor/pom.xml b/ms/blueprintsprocessor/pom.xml index 2a6bc75a1..be7a73256 100755 --- a/ms/blueprintsprocessor/pom.xml +++ b/ms/blueprintsprocessor/pom.xml @@ -15,13 +15,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ms</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> diff --git a/ms/command-executor/pom.xml b/ms/command-executor/pom.xml index 0beb34d5e..ceb4147e0 100755 --- a/ms/command-executor/pom.xml +++ b/ms/command-executor/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ms</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> diff --git a/ms/command-executor/src/main/docker/Dockerfile b/ms/command-executor/src/main/docker/Dockerfile index 70cf943f6..e91265b56 100644 --- a/ms/command-executor/src/main/docker/Dockerfile +++ b/ms/command-executor/src/main/docker/Dockerfile @@ -5,6 +5,8 @@ RUN python -m pip install --upgrade pip RUN pip install grpcio==${GRPC_PYTHON_VERSION} grpcio-tools==${GRPC_PYTHON_VERSION} RUN pip install virtualenv==16.7.9 +RUN groupadd -r onap && useradd -r -g onap onap + COPY start.sh /opt/app/onap/start.sh RUN chmod u+x /opt/app/onap/start.sh @@ -16,6 +18,9 @@ RUN tar -xzf /source.tar.gz -C /tmp \ && rm -rf /source.tar.gz \ && rm -rf /tmp/@project.build.finalName@ -VOLUME /opt/app/onap/blueprints/deploy/ +RUN mkdir -p /opt/app/onap/blueprints/deploy +RUN chown onap:onap /opt -R +VOLUME /opt/app/onap/blueprints/deploy/ +USER onap ENTRYPOINT /opt/app/onap/start.sh diff --git a/ms/command-executor/src/main/python/command_executor_handler.py b/ms/command-executor/src/main/python/command_executor_handler.py index 3219a974b..1e6f03b81 100644 --- a/ms/command-executor/src/main/python/command_executor_handler.py +++ b/ms/command-executor/src/main/python/command_executor_handler.py @@ -31,7 +31,7 @@ import json REQUIREMENTS_TXT = "requirements.txt" -class CommandExecutorHandler: +class CommandExecutorHandler(): def __init__(self, request): self.request = request @@ -45,51 +45,77 @@ class CommandExecutorHandler: def prepare_env(self, request, results): if not self.is_installed(): - self.create_venv() - if not self.activate_venv(): - return False - - f = open(self.installed, "w+") - if not self.install_packages(request, CommandExecutor_pb2.pip, f, results): - return False - f.write("\r\n") - results.append("\n") - if not self.install_packages(request, CommandExecutor_pb2.ansible_galaxy, f, results): - return False - f.close() + create_venv_status = self.create_venv() + if not create_venv_status["cds_is_successful"]: + err_msg = "ERROR: failed to prepare environment for request {} due to error in creating virtual Python env. Original error {}".format(self.blueprint_id, create_venv_status["err_msg"]) + self.logger.error(err_msg) + return utils.build_ret_data(False, err_msg) + + activate_venv_status = self.activate_venv() + if not activate_venv_status["cds_is_successful"]: + err_msg = "ERROR: failed to prepare environment for request {} due Python venv_activation. Original error {}".format(self.blueprint_id, activate_venv_status["err_msg"]) + self.logger.error(err_msg) + return utils.build_ret_data(False, err_msg) + try: + with open(self.installed, "w+") as f: + if not self.install_packages(request, CommandExecutor_pb2.pip, f, results): + return utils.build_ret_data(False, "ERROR: failed to prepare environment for request {} during pip package install.".format(self.blueprint_id)) + f.write("\r\n") # TODO: is \r needed? + results.append("\n") + if not self.install_packages(request, CommandExecutor_pb2.ansible_galaxy, f, results): + return utils.build_ret_data(False, "ERROR: failed to prepare environment for request {} during Ansible install.".format(self.blueprint_id)) + except Exception as ex: + err_msg = "ERROR: failed to prepare environment for request {} during installing packages. Exception: {}".format(self.blueprint_id, ex) + self.logger.error(err_msg) + return utils.build_ret_data(False, err_msg) else: - f = open(self.installed, "r") - results.append(f.read()) - f.close() + try: + with open(self.installed, "r") as f: + results.append(f.read()) + except Exception as ex: + return utils.build_ret_data(False, "ERROR: failed to prepare environment during reading 'installed' file {}. Exception: {}".format(self.installed, ex)) # deactivate_venv(blueprint_id) - return True + return utils.build_ret_data(True, "") def execute_command(self, request, results): - - if not self.activate_venv(): - return False - - cmd = "cd " + self.venv_home - - if "ansible-playbook" in request.command: - cmd = cmd + "; " + request.command + " -e 'ansible_python_interpreter=" + self.venv_home + "/bin/python'" - else: - cmd = cmd + "; " + request.command + " " + re.escape(MessageToJson(request.properties)) - payload_result = {} - payload_section = [] - is_payload_section = False - - ### extract the original header request into sys-env variables - ### RequestID - request_id = request.requestId - ### Sub-requestID - subrequest_id = request.correlationId - request_id_map = {'CDS_REQUEST_ID':request_id, 'CDS_CORRELATION_ID':subrequest_id} - updated_env = { **os.environ, **request_id_map } - + # workaround for when packages are not specified, we may not want to go through the install step + # can just call create_venv from here. + if not self.is_installed(): + self.create_venv() try: + if not self.is_installed(): + create_venv_status = self.create_venv + if not create_venv_status["cds_is_successful"]: + err_msg = "{} - Failed to execute command during venv creation. Original error: {}".format(self.blueprint_id, create_venv_status["err_msg"]) + results.append(err_msg) + return utils.build_ret_data(False, err_msg) + activate_response = self.activate_venv() + if not activate_response["cds_is_successful"]: + orig_error = activate_response["err_msg"] + err_msg = "{} - Failed to execute command during environment activation. Original error: {}".format(self.blueprint_id, orig_error) + results.append(err_msg) #TODO: get rid of results and just rely on the return data struct. + return utils.build_ret_data(False, err_msg) + + cmd = "cd " + self.venv_home + + ### TODO: replace with os.environ['VIRTUAL_ENV']? + if "ansible-playbook" in request.command: + cmd = cmd + "; " + request.command + " -e 'ansible_python_interpreter=" + self.venv_home + "/bin/python'" + else: + cmd = cmd + "; " + request.command + " " + re.escape(MessageToJson(request.properties)) + payload_section = [] + is_payload_section = False + + ### extract the original header request into sys-env variables + ### RequestID + request_id = request.requestId + ### Sub-requestID + subrequest_id = request.correlationId + request_id_map = {'CDS_REQUEST_ID':request_id, 'CDS_CORRELATION_ID':subrequest_id} + updated_env = { **os.environ, **request_id_map } + with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, bufsize=1, universal_newlines=True, env=updated_env) as newProcess: while True: @@ -113,14 +139,17 @@ class CommandExecutorHandler: payload_section.append(output.strip()) rc = newProcess.poll() except Exception as e: - self.logger.info("{} - Failed to execute command. Error: {}".format(self.blueprint_id, e)) + err_msg = "{} - Failed to execute command. Error: {}".format(self.blueprint_id, e) + self.logger.info(err_msg) results.append(e) - payload_result["cds_return_code"] = False + payload_result.update(utils.build_ret_data(False, err_msg)) return payload_result # deactivate_venv(blueprint_id) - - payload_result["cds_return_code"] = rc + #Since return code is only used to check if it's zero (success), we can just return success flag instead. + self.logger.debug("python return_code : {}".format(rc)) + is_execution_successful = rc == 0 + payload_result.update(utils.build_ret_data(is_execution_successful, "")) return payload_result def install_packages(self, request, type, f, results): @@ -155,13 +184,16 @@ class CommandExecutorHandler: env = dict(os.environ) if "https_proxy" in os.environ: env['https_proxy'] = os.environ['https_proxy'] + self.logger.info("Using https_proxy: ", env['https_proxy']) try: results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode()) results.append("\n") + self.logger.info("install_python_packages {} succeeded".format(package)) return True except CalledProcessError as e: results.append(e.stderr.decode()) + self.logger.error("install_python_packages {} failed".format(package)) return False def install_ansible_packages(self, package, results): @@ -182,6 +214,10 @@ class CommandExecutorHandler: results.append(e.stderr.decode()) return False + # Returns a map with 'status' and 'err_msg'. + # 'status' True indicates success. + # 'err_msg' indicates an error occurred. The presence of err_msg may not be fatal, + # status should be set to False for fatal errors. def create_venv(self): self.logger.info("{} - Create Python Virtual Environment".format(self.blueprint_id)) try: @@ -189,10 +225,15 @@ class CommandExecutorHandler: # venv doesn't populate the activate_this.py script, hence we use from virtualenv venv.create(self.venv_home, with_pip=True, system_site_packages=True) virtualenv.writefile(os.path.join(bin_dir, "activate_this.py"), virtualenv.ACTIVATE_THIS) + self.logger.info("{} - Creation of Python Virtual Environment finished.".format(self.blueprint_id)) + return utils.build_ret_data(True, "") except Exception as err: - self.logger.info( - "{} - Failed to provision Python Virtual Environment. Error: {}".format(self.blueprint_id, err)) + err_msg = "{} - Failed to provision Python Virtual Environment. Error: {}".format(self.blueprint_id, err) + self.logger.info(err_msg) + return utils.build_ret_data(False, err_msg) + # return map cds_is_successful and err_msg. Status is True on success. err_msg may existence doesn't necessarily indicate fatal condition. + # the 'status' should be set to False to indicate error. def activate_venv(self): self.logger.info("{} - Activate Python Virtual Environment".format(self.blueprint_id)) @@ -203,14 +244,15 @@ class CommandExecutorHandler: path = "%s/bin/activate_this.py" % self.venv_home try: - exec (open(path).read(), {'__file__': path}) + with open(path) as activate_this_script: + exec (activate_this_script.read(), {'__file__': path}) exec (fixpathenvvar) self.logger.info("Running with PATH : {}".format(os.environ['PATH'])) - return True + return utils.build_ret_data(True, "") except Exception as err: - self.logger.info( - "{} - Failed to activate Python Virtual Environment. Error: {}".format(self.blueprint_id, err)) - return False + err_msg ="{} - Failed to activate Python Virtual Environment. Error: {}".format(self.blueprint_id, err) + self.logger.info( err_msg) + return utils.build_ret_data(False, err_msg) def deactivate_venv(self): self.logger.info("{} - Deactivate Python Virtual Environment".format(self.blueprint_id)) diff --git a/ms/command-executor/src/main/python/command_executor_server.py b/ms/command-executor/src/main/python/command_executor_server.py index 39cd1e6da..3435e2272 100644 --- a/ms/command-executor/src/main/python/command_executor_server.py +++ b/ms/command-executor/src/main/python/command_executor_server.py @@ -37,11 +37,12 @@ class CommandExecutorServer(CommandExecutor_pb2_grpc.CommandExecutorServiceServi results = [] handler = CommandExecutorHandler(request) - if not handler.prepare_env(request, results): + prepare_env_response = handler.prepare_env(request, results) + if not prepare_env_response["cds_is_successful"]: self.logger.info("{} - Failed to prepare python environment. {}".format(blueprint_id, results)) - return utils.build_response(request, results, {}, False) + return utils.build_grpc_response(request, results, {}, False) self.logger.info("{} - Package installation logs {}".format(blueprint_id, results)) - return utils.build_response(request, results, {}, True) + return utils.build_grpc_response(request, results, {}, True) def executeCommand(self, request, context): blueprint_id = utils.get_blueprint_id(request) @@ -53,12 +54,12 @@ class CommandExecutorServer(CommandExecutor_pb2_grpc.CommandExecutorServiceServi payload_result = {} handler = CommandExecutorHandler(request) payload_result = handler.execute_command(request, log_results) - if payload_result["cds_return_code"] != 0: + if not payload_result["cds_is_successful"]: self.logger.info("{} - Failed to executeCommand. {}".format(blueprint_id, log_results)) else: self.logger.info("{} - Execution finished successfully.".format(blueprint_id)) - ret = utils.build_response(request, log_results, payload_result, payload_result["cds_return_code"] == 0) + ret = utils.build_grpc_response(request, log_results, payload_result, payload_result["cds_is_successful"]) self.logger.info("Payload returned %s" % payload_result) return ret
\ No newline at end of file diff --git a/ms/command-executor/src/main/python/utils.py b/ms/command-executor/src/main/python/utils.py index a3748eb17..574be51db 100644 --- a/ms/command-executor/src/main/python/utils.py +++ b/ms/command-executor/src/main/python/utils.py @@ -18,23 +18,34 @@ from google.protobuf.timestamp_pb2 import Timestamp import proto.CommandExecutor_pb2 as CommandExecutor_pb2 import json + def get_blueprint_id(request): - blueprint_name = request.identifiers.blueprintName - blueprint_version = request.identifiers.blueprintVersion - return blueprint_name + '/' + blueprint_version + blueprint_name = request.identifiers.blueprintName + blueprint_version = request.identifiers.blueprintVersion + return blueprint_name + '/' + blueprint_version +# Create a response for grpc. Fills in the timestamp as well as removes cds_is_successful element +def build_grpc_response(request, log_results, payload_return, is_success=False): + if is_success: + status = CommandExecutor_pb2.SUCCESS + else: + status = CommandExecutor_pb2.FAILURE -def build_response(request, log_results, payload_return, is_success=False): - if is_success: - status = CommandExecutor_pb2.SUCCESS - else: - status = CommandExecutor_pb2.FAILURE + timestamp = Timestamp() + timestamp.GetCurrentTime() - timestamp = Timestamp() - timestamp.GetCurrentTime() + if "cds_is_successful" in payload_return: + payload_return.pop('cds_is_successful') + payload_str = json.dumps(payload_return) + return CommandExecutor_pb2.ExecutionOutput(requestId=request.requestId, + response=log_results, + status=status, + payload=payload_str, + timestamp=timestamp) - if 'cds_return_code' in payload_return: - payload_return.pop('cds_return_code') - payload_str = json.dumps(payload_return) - return CommandExecutor_pb2.ExecutionOutput(requestId=request.requestId, response=log_results, status=status, - payload=payload_str, timestamp=timestamp) +# build a return data structure which may contain an error message +def build_ret_data(cds_is_successful, err_msg): + ret_data = {"cds_is_successful": cds_is_successful } + if err_msg != "": + ret_data["err_msg"] = err_msg + return ret_data diff --git a/ms/error-catalog/application/pom.xml b/ms/error-catalog/application/pom.xml index c2a09dbdb..e775585ae 100644 --- a/ms/error-catalog/application/pom.xml +++ b/ms/error-catalog/application/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.error.catalog</groupId> <artifactId>error-catalog</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>error-catalog-application</artifactId> @@ -31,4 +32,11 @@ <properties> <sonar.skip>true</sonar.skip> </properties> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.cds.error.catalog</groupId> + <artifactId>error-catalog-services</artifactId> + </dependency> + </dependencies> </project> diff --git a/ms/error-catalog/core/pom.xml b/ms/error-catalog/core/pom.xml index 0592112cf..81ad38f00 100644 --- a/ms/error-catalog/core/pom.xml +++ b/ms/error-catalog/core/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.error.catalog</groupId> <artifactId>error-catalog</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>error-catalog-core</artifactId> @@ -31,4 +32,23 @@ <properties> <sonar.skip>true</sonar.skip> </properties> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-webflux</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.module</groupId> + <artifactId>jackson-module-kotlin</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>javax.persistence-api</artifactId> + </dependency> + </dependencies> </project> diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCatalogException.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCatalogException.kt index 032feb62c..348b60ceb 100644 --- a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCatalogException.kt +++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCatalogException.kt @@ -23,6 +23,8 @@ interface ErrorCatalogExceptionFluent<T> { fun action(action: String): T fun http(type: String): T fun grpc(type: String): T + fun convertToHttp(): T + fun convertToGrpc(): T fun payloadMessage(message: String): T fun addErrorPayloadMessage(message: String): T fun addSubError(errorMessage: ErrorMessage): T @@ -78,12 +80,30 @@ open class ErrorCatalogException : RuntimeException { fun <T : ErrorCatalogException> updateHttp(type: String): T { this.protocol = ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_HTTP + this.name = type this.code = HttpErrorCodes.code(type) return this as T } + fun <T : ErrorCatalogException> inverseToHttp(): T { + if (this.protocol != "" && this.protocol == ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_GRPC) { + this.protocol = ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_HTTP + this.code = HttpErrorCodes.code(this.name) + } + return this as T + } + + fun <T : ErrorCatalogException> inverseToGrpc(): T { + if (this.protocol != "" && this.protocol == ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_HTTP) { + this.protocol = ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_GRPC + this.code = GrpcErrorCodes.code(this.name) + } + return this as T + } + fun <T : ErrorCatalogException> updateGrpc(type: String): T { this.protocol = ErrorMessageLibConstants.ERROR_CATALOG_PROTOCOL_GRPC + this.name = type this.code = GrpcErrorCodes.code(type) return this as T } diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCodes.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCodes.kt index 86483e3e9..8023d97c8 100644 --- a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCodes.kt +++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorCodes.kt @@ -54,8 +54,7 @@ object HttpErrorCodes { } fun code(type: String): Int { - // FIXME("Return Default Error Code , If missing") - return store[type]!! + return store[type] ?: store[ErrorCatalogCodes.GENERIC_FAILURE]!! } } @@ -82,7 +81,6 @@ object GrpcErrorCodes { } fun code(type: String): Int { - // FIXME("Return Default Error Code , If missing") - return store[type]!! + return store[type] ?: store[ErrorCatalogCodes.GENERIC_FAILURE]!! } } diff --git a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorLibData.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorLibData.kt index 2c0772e31..4158cfaf8 100644 --- a/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorLibData.kt +++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/ErrorLibData.kt @@ -20,12 +20,15 @@ import com.fasterxml.jackson.annotation.JsonFormat import org.slf4j.event.Level import org.onap.ccsdk.cds.error.catalog.core.ErrorMessageLibConstants.ERROR_CATALOG_DEFAULT_ERROR_CODE import java.time.LocalDateTime +import java.time.ZoneId +import java.util.Date +import kotlin.collections.ArrayList open class ErrorPayload { var code: Int = ERROR_CATALOG_DEFAULT_ERROR_CODE var status: String = "" @get:JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - var timestamp: LocalDateTime = LocalDateTime.now() + var timestamp: Date = controllerDate() var message: String = "" var debugMessage: String = "" var logLevel: String = Level.ERROR.name @@ -68,6 +71,11 @@ open class ErrorPayload { this.logLevel == errorPayload.logLevel && this.debugMessage == errorPayload.debugMessage && this.subErrors == errorPayload.subErrors) } + + private fun controllerDate(): Date { + val localDateTime = LocalDateTime.now(ZoneId.systemDefault()) + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()) + } } /** diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/utils/ErrorCatalogUtils.kt b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/utils/ErrorCatalogUtils.kt index 967d3560c..f13a3604f 100644 --- a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/utils/ErrorCatalogUtils.kt +++ b/ms/error-catalog/core/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/core/utils/ErrorCatalogUtils.kt @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onap.ccsdk.cds.error.catalog.services.utils +package org.onap.ccsdk.cds.error.catalog.core.utils + +import org.apache.commons.lang3.exception.ExceptionUtils object ErrorCatalogUtils { private const val REGEX_PATTERN = "^cause=(.*),action=(.*)" @@ -31,7 +33,7 @@ object ErrorCatalogUtils { } fun Exception.errorCauseOrDefault(): Throwable { - return this.cause ?: Throwable() + return ExceptionUtils.getRootCause(this) } fun Exception.errorMessageOrDefault(): String { diff --git a/ms/error-catalog/pom.xml b/ms/error-catalog/pom.xml index 8b82d7d75..8356e4d38 100644 --- a/ms/error-catalog/pom.xml +++ b/ms/error-catalog/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ms</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> @@ -37,17 +38,21 @@ <module>services</module> </modules> + <properties> + <error-catalog.version>${project.version}</error-catalog.version> + </properties> + <dependencyManagement> <dependencies> <dependency> <groupId>org.onap.ccsdk.cds.error.catalog</groupId> <artifactId>error-catalog-core</artifactId> - <version>${project.version}</version> + <version>${error-catalog.version}</version> </dependency> <dependency> <groupId>org.onap.ccsdk.cds.error.catalog</groupId> <artifactId>error-catalog-services</artifactId> - <version>${project.version}</version> + <version>${error-catalog.version}</version> </dependency> </dependencies> </dependencyManagement> @@ -55,70 +60,29 @@ <!-- Kotlin Dependencies --> <dependency> <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-stdlib</artifactId> + <artifactId>kotlin-stdlib-jdk8</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-stdlib-common</artifactId> + <artifactId>kotlin-reflect</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-script-util</artifactId> + <artifactId>kotlin-stdlib</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-stdlib-jdk8</artifactId> - </dependency> - <dependency> - <groupId>org.jetbrains.kotlinx</groupId> - <artifactId>kotlinx-coroutines-core</artifactId> - </dependency> - <dependency> - <groupId>org.jetbrains.kotlinx</groupId> - <artifactId>kotlinx-coroutines-reactor</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.module</groupId> - <artifactId>jackson-module-kotlin</artifactId> + <artifactId>kotlin-stdlib-common</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-compiler-embeddable</artifactId> </dependency> <dependency> - <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-scripting-jvm-host</artifactId> - <!--Use kotlin-compiler-embeddable as koltin-compiler wrap--> - <!--guava dependency creating classpath issues at runtime--> - <exclusions> - <exclusion> - <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-compiler</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-webflux</artifactId> - </dependency> - <dependency> - <groupId>javax.persistence</groupId> - <artifactId>javax.persistence-api</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-data-jpa</artifactId> - </dependency> - <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> - <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-test</artifactId> - <scope>test</scope> - </dependency> </dependencies> <build> diff --git a/ms/error-catalog/services/pom.xml b/ms/error-catalog/services/pom.xml index a0a1ba9b1..c5e6cb216 100644 --- a/ms/error-catalog/services/pom.xml +++ b/ms/error-catalog/services/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.error.catalog</groupId> <artifactId>error-catalog</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>error-catalog-services</artifactId> @@ -37,5 +38,39 @@ <groupId>org.onap.ccsdk.cds.error.catalog</groupId> <artifactId>error-catalog-core</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-scripting-jvm-host</artifactId> + <!--Use kotlin-compiler-embeddable as koltin-compiler wrap--> + <!--guava dependency creating classpath issues at runtime--> + <exclusions> + <exclusion> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-compiler</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlinx</groupId> + <artifactId>kotlinx-coroutines-core</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlinx</groupId> + <artifactId>kotlinx-coroutines-reactor</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-util</artifactId> + </dependency> + <!-- Kotlin Dependencies --> + <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-test</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogExceptionHandler.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogExceptionHandler.kt index 88e2f4522..258209f71 100644 --- a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogExceptionHandler.kt +++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogExceptionHandler.kt @@ -16,10 +16,18 @@ package org.onap.ccsdk.cds.error.catalog.services +import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogException import org.onap.ccsdk.cds.error.catalog.core.ErrorPayload +import org.onap.ccsdk.cds.error.catalog.core.HttpErrorCodes +import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault +import org.onap.ccsdk.cds.error.catalog.core.utils.errorMessageOrDefault +import org.springframework.dao.EmptyResultDataAccessException +import org.springframework.dao.IncorrectResultSizeDataAccessException import org.springframework.http.ResponseEntity +import org.springframework.orm.jpa.JpaObjectRetrievalFailureException import org.springframework.web.bind.annotation.ExceptionHandler +import org.springframework.web.server.ServerWebInputException abstract class ErrorCatalogExceptionHandler(private val errorCatalogService: ErrorCatalogService) { @@ -28,4 +36,44 @@ abstract class ErrorCatalogExceptionHandler(private val errorCatalogService: Err val errorPayload = errorCatalogService.errorPayload(e) return errorPayload.toResponseEntity() } + + @ExceptionHandler + fun errorCatalogException(e: ServerWebInputException): ResponseEntity<ErrorPayload> { + val error = ErrorCatalogException(HttpErrorCodes.code(ErrorCatalogCodes.REQUEST_NOT_FOUND), + e.errorMessageOrDefault(), e.errorCauseOrDefault()) + val errorPayload = ErrorPayload(error.code, error.name, error.errorMessageOrDefault()) + return errorPayload.toResponseEntity() + } + + @ExceptionHandler + fun errorCatalogException(e: IncorrectResultSizeDataAccessException): ResponseEntity<ErrorPayload> { + val error = ErrorCatalogException(HttpErrorCodes.code(ErrorCatalogCodes.DUPLICATE_DATA), + e.errorMessageOrDefault(), e.errorCauseOrDefault()) + val errorPayload = ErrorPayload(error.code, error.name, error.errorMessageOrDefault()) + return errorPayload.toResponseEntity() + } + + @ExceptionHandler + fun errorCatalogException(e: EmptyResultDataAccessException): ResponseEntity<ErrorPayload> { + val error = ErrorCatalogException(HttpErrorCodes.code(ErrorCatalogCodes.RESOURCE_NOT_FOUND), + e.errorMessageOrDefault(), e.errorCauseOrDefault()) + val errorPayload = ErrorPayload(error.code, error.name, error.errorMessageOrDefault()) + return errorPayload.toResponseEntity() + } + + @ExceptionHandler + fun errorCatalogException(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorPayload> { + val error = ErrorCatalogException(HttpErrorCodes.code(ErrorCatalogCodes.RESOURCE_NOT_FOUND), + e.errorMessageOrDefault(), e.errorCauseOrDefault()) + val errorPayload = ErrorPayload(error.code, error.name, error.errorMessageOrDefault()) + return errorPayload.toResponseEntity() + } + + @ExceptionHandler + fun errorCatalogException(e: Exception): ResponseEntity<ErrorPayload> { + val error = ErrorCatalogException(HttpErrorCodes.code(ErrorCatalogCodes.GENERIC_FAILURE), + e.errorMessageOrDefault(), e.errorCauseOrDefault()) + val errorPayload = ErrorPayload(error.code, error.name, error.errorMessageOrDefault()) + return errorPayload.toResponseEntity() + } } diff --git a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogService.kt b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogService.kt index 91f817133..21fd51b2f 100644 --- a/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogService.kt +++ b/ms/error-catalog/services/src/main/kotlin/org/onap/ccsdk/cds/error/catalog/services/ErrorCatalogService.kt @@ -24,7 +24,8 @@ import org.onap.ccsdk.cds.error.catalog.core.ErrorMessageLibConstants import org.onap.ccsdk.cds.error.catalog.core.ErrorPayload import org.onap.ccsdk.cds.error.catalog.core.GrpcErrorCodes import org.onap.ccsdk.cds.error.catalog.core.HttpErrorCodes -import org.onap.ccsdk.cds.error.catalog.services.utils.ErrorCatalogUtils +import org.onap.ccsdk.cds.error.catalog.core.utils.ErrorCatalogUtils +import org.apache.commons.lang3.exception.ExceptionUtils import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.stereotype.Service import javax.annotation.PostConstruct @@ -40,10 +41,17 @@ open class ErrorCatalogService(private var errorCatalogLoadService: ErrorCatalog fun errorPayload(errorCatalogException: ErrorCatalogException): ErrorPayload { val errorCatalog = getErrorCatalog(errorCatalogException) - val errorPayload = ErrorPayload(errorCatalog.code, errorCatalog.errorId, errorCatalog.getMessage()) - errorPayload.subErrors.addAll(errorCatalogException.errorPayload!!.subErrors) + val errorPayload: ErrorPayload + if (errorCatalogException.errorPayload == null) { + errorPayload = ErrorPayload(errorCatalog.code, errorCatalog.errorId, errorCatalog.getMessage()) + } else { + errorPayload = errorCatalogException.errorPayload!! + errorPayload.code = errorCatalog.code + errorPayload.message = errorCatalog.getMessage() + errorPayload.status = errorCatalog.errorId + } if (errorCatalogException.cause != null) { - errorPayload.debugMessage = errorCatalogException.cause!!.printStackTrace().toString() + errorPayload.debugMessage = ExceptionUtils.getStackTrace(errorCatalogException.cause) } return errorPayload } diff --git a/ms/pom.xml b/ms/pom.xml index 22f016a2e..92ffa546b 100644 --- a/ms/pom.xml +++ b/ms/pom.xml @@ -14,18 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <artifactId>ms</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>Micro-services Root</name> diff --git a/ms/py-executor/docker/Dockerfile b/ms/py-executor/docker/Dockerfile index 043e15d53..638b09f39 100644 --- a/ms/py-executor/docker/Dockerfile +++ b/ms/py-executor/docker/Dockerfile @@ -1,5 +1,7 @@ FROM python:3.7-slim +RUN groupadd -r onap && useradd -r -g onap onap + RUN mkdir -p /opt/app/onap/logs/ && touch /opt/app/onap/logs/application.log COPY @project.build.finalName@-@assembly.id@.tar.gz /source.tar.gz @@ -10,6 +12,9 @@ RUN tar -xzf /source.tar.gz -C /tmp \ RUN pip install --no-cache-dir -r /opt/app/onap/python/requirements/docker.txt -VOLUME /opt/app/onap/blueprints/deploy/ +RUN mkdir -p /opt/app/onap/blueprints/deploy +RUN chown onap:onap /opt -R +VOLUME /opt/app/onap/blueprints/deploy/ +USER onap ENTRYPOINT /opt/app/onap/python/start.sh diff --git a/ms/py-executor/pom.xml b/ms/py-executor/pom.xml index dee2a3307..e678ea9dc 100644 --- a/ms/py-executor/pom.xml +++ b/ms/py-executor/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ms</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>py-executor</artifactId> diff --git a/ms/sdclistener/application/pom.xml b/ms/sdclistener/application/pom.xml index 3825a0809..45c3919e6 100644 --- a/ms/sdclistener/application/pom.xml +++ b/ms/sdclistener/application/pom.xml @@ -14,18 +14,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.sdclistener</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../parent</relativePath> </parent> <artifactId>application</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>SDC Listener Application</name> @@ -56,7 +57,7 @@ <dependency> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>health-api-common</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> diff --git a/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/dto/SdcListenerDtoTest.java b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/dto/SdcListenerDtoTest.java new file mode 100644 index 000000000..1f4ba81f7 --- /dev/null +++ b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/dto/SdcListenerDtoTest.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 2020 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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============================================ + * + * + */ +package org.onap.ccsdk.cds.sdclistener.dto; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.ccsdk.cds.sdclistener.dto.SdcListenerDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.onap.ccsdk.cds.sdclistener.client.SdcListenerAuthClientInterceptor; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties({SdcListenerDto.class,SdcListenerAuthClientInterceptor.class}) +@SpringBootTest(classes = {SdcListenerDtoTest.class}) +public class SdcListenerDtoTest { + + @Autowired + private SdcListenerDto listenerConfiguration; + + @Test + public void testCdsSdcListenerDto() { + listenerConfiguration.setDistributionId("1234"); + listenerConfiguration.setArtifactUrl("/sdc/v1/artifact/"); + assertEquals(listenerConfiguration.getDistributionId(), "1234"); + assertEquals(listenerConfiguration.getArtifactUrl(), "/sdc/v1/artifact/"); + } + + +} diff --git a/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/exceptions/SdcListenerExceptionTest.java b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/exceptions/SdcListenerExceptionTest.java new file mode 100644 index 000000000..72f0ef289 --- /dev/null +++ b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/exceptions/SdcListenerExceptionTest.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START============================================ + * ONAP Portal + * ===================================================================== + * Copyright (C) 2020 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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================================================ + * + * + */ +package org.onap.ccsdk.cds.sdclistener.exceptions; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +public class SdcListenerExceptionTest { + + @Test + public void testConstructor() { + final String s1="Exception occured"; + SdcListenerException sle=new SdcListenerException(s1); + assertEquals(sle.getMessage(),"Exception occured"); + } +} diff --git a/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/status/ComponentStatusMessageTest.java b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/status/ComponentStatusMessageTest.java new file mode 100644 index 000000000..898596dfa --- /dev/null +++ b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/status/ComponentStatusMessageTest.java @@ -0,0 +1,30 @@ +package org.onap.ccsdk.cds.sdclistener.status; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.ccsdk.cds.sdclistener.status.ComponentStatusMessage; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {ComponentStatusMessageTest.class}) +public class ComponentStatusMessageTest { + ComponentStatusMessage componentStatusMsg= new ComponentStatusMessage(); + + @Test + public void testComponentStatusMessage() { + componentStatusMsg.setComponentName("Test"); + componentStatusMsg.setArtifactUrl("/sdc/v1/artifact"); + componentStatusMsg.setConsumerID("cds-id-local"); + componentStatusMsg.setDistributionID("1"); + componentStatusMsg.setTimeStamp(01022020); + assertEquals(componentStatusMsg.getComponentName(), "Test"); + assertEquals(componentStatusMsg.getArtifactURL(), "/sdc/v1/artifact"); + assertEquals(componentStatusMsg.getConsumerID(), "cds-id-local"); + assertEquals(componentStatusMsg.getDistributionID(), "1"); + assertEquals(componentStatusMsg.getTimeStamp(), 01022020); + assertEquals(componentStatusMsg.getTimestamp(), 01022020); + } +} diff --git a/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/util/FileUtilTest.java b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/util/FileUtilTest.java new file mode 100644 index 000000000..a43e8c072 --- /dev/null +++ b/ms/sdclistener/application/src/test/java/org/onap/ccsdk/cds/sdclistener/util/FileUtilTest.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 2020 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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============================================ + * + * + */ +package org.onap.ccsdk.cds.sdclistener.util; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import java.io.File; +import java.io.IOException; +import static org.hamcrest.MatcherAssert.assertThat; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.hamcrest.collection.IsEmptyCollection; + +import java.util.ArrayList; +import java.util.List; +import static org.hamcrest.CoreMatchers.*; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {FileUtilTest.class}) +public class FileUtilTest { + + FileUtil fs; + + @Test + public void testDeleteFile() throws IOException { + File tempFile = File.createTempFile("tempFile", ".txt"); +// System.out.println(tempFile.getRoot()); + fs.deleteFile(tempFile,tempFile.getAbsolutePath()); + assertFalse(tempFile.exists()); + + } + + @Test + public void testGetFilesFromDisk() throws IOException{ + + Path resourceDirectory = Paths.get("src","test","resources"); + int totalfile=resourceDirectory.getNameCount(); + List fileList=fs.getFilesFromDisk(resourceDirectory); + assertNotNull(fileList); + assertEquals(fileList.size(),totalfile); + } + + +} diff --git a/ms/sdclistener/distribution/pom.xml b/ms/sdclistener/distribution/pom.xml index 669db4338..ec02cfb5c 100755 --- a/ms/sdclistener/distribution/pom.xml +++ b/ms/sdclistener/distribution/pom.xml @@ -14,13 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds.sdclistener</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>../parent</relativePath> </parent> diff --git a/ms/sdclistener/distribution/src/main/docker/Dockerfile b/ms/sdclistener/distribution/src/main/docker/Dockerfile index 34f6443bf..e9ecb8d66 100755 --- a/ms/sdclistener/distribution/src/main/docker/Dockerfile +++ b/ms/sdclistener/distribution/src/main/docker/Dockerfile @@ -1,7 +1,9 @@ FROM openjdk:8-jdk-alpine +RUN addgroup -S onap && adduser -S onap -G onap # add entrypoint COPY startService.sh /startService.sh +RUN chown onap:onap /startService.sh RUN chmod 751 /startService.sh # add application COPY @project.build.finalName@-@assembly.id@.tar.gz /source.tar.gz @@ -10,4 +12,8 @@ RUN tar -xzf /source.tar.gz -C /tmp \ && rm -rf /source.tar.gz \ && rm -rf /tmp/@project.build.finalName@ +RUN mkdir -p /opt/app/onap/cds-sdc-listener +RUN chown onap:onap /opt -R + +USER onap ENTRYPOINT /startService.sh diff --git a/ms/sdclistener/parent/pom.xml b/ms/sdclistener/parent/pom.xml index 36a96f037..ea67d1b95 100755 --- a/ms/sdclistener/parent/pom.xml +++ b/ms/sdclistener/parent/pom.xml @@ -16,13 +16,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>sdclistener</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.onap.ccsdk.cds.sdclistener</groupId> diff --git a/ms/sdclistener/pom.xml b/ms/sdclistener/pom.xml index 8404f0a81..d89eb14a3 100644 --- a/ms/sdclistener/pom.xml +++ b/ms/sdclistener/pom.xml @@ -14,13 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>ms</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> @@ -16,19 +16,20 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.parent</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>1.5.2</version> + <version>2.0.0-SNAPSHOT</version> <relativePath/> </parent> <groupId>org.onap.ccsdk.cds</groupId> <artifactId>parent</artifactId> - <version>0.7.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>CDS Parent</name> diff --git a/version.properties b/version.properties index b05a161f6..1da7b9a35 100644 --- a/version.properties +++ b/version.properties @@ -4,9 +4,9 @@ # because they are used in Jenkins, whose plug-in doesn't support -release_name=0 -sprint_number=7 -feature_revision=1 +release_name=1 +sprint_number=0 +feature_revision=0 base_version=${release_name}.${sprint_number}.${feature_revision} |