summaryrefslogtreecommitdiffstats
path: root/catalog-ui
diff options
context:
space:
mode:
authorJvD_Ericsson <jeff.van.dam@est.tech>2022-06-02 10:46:40 +0100
committerMichael Morris <michael.morris@est.tech>2022-06-24 13:17:23 +0000
commit363d9a6fea48bf6f34e4f1d4ecb37d33812c7626 (patch)
tree6d5023023b0f93346ed40e62f6cf3f4bc23792b9 /catalog-ui
parent2dcfb0996a8345de5c8be73a5600ee995309664a (diff)
Service Import - Read metadata from csar
Also exports metadata to the tosca template and fixes service metadata not being set when the create button is clicked Issue-ID: SDC-4044 Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech> Change-Id: I6f8428d9ed385335c05e7b994e622229ea00342b
Diffstat (limited to 'catalog-ui')
-rw-r--r--catalog-ui/package.json4
-rw-r--r--catalog-ui/src/app/models.ts3
-rw-r--r--catalog-ui/src/app/models/service-csar.ts46
-rw-r--r--catalog-ui/src/app/modules/utils.ts2
-rw-r--r--catalog-ui/src/app/utils.ts1
-rw-r--r--catalog-ui/src/app/utils/file-utils.ts18
-rw-r--r--catalog-ui/src/app/utils/service-csar-reader.ts139
-rw-r--r--catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts30
8 files changed, 237 insertions, 6 deletions
diff --git a/catalog-ui/package.json b/catalog-ui/package.json
index 92e6ef4e01..27bba5889c 100644
--- a/catalog-ui/package.json
+++ b/catalog-ui/package.json
@@ -94,10 +94,10 @@
"@angular/upgrade": "^5.0.0",
"@bardit/cytoscape-expand-collapse": "^2.0.3",
"@bardit/cytoscape-qtip": "^2.5.1",
+ "@ng-select/ng-select": "^1.0.2",
"@ngxs/devtools-plugin": "3.3.4",
"@ngxs/logger-plugin": "3.3.4",
"@ngxs/store": "^2.1.0-dev.d538580",
- "@ng-select/ng-select": "^1.0.2",
"@swimlane/ngx-datatable": "^14.0.0",
"@types/core-js": "^0.9.35",
"@types/jquery": "^2.0.52",
@@ -133,6 +133,8 @@
"jquery": "^3.6.0",
"jqueryui": "^1.11.1",
"js-md5": "^0.4.2",
+ "js-yaml": "^4.1.0",
+ "jszip": "^3.10.0",
"less": "~3.9.0",
"lodash": "^4.17.2",
"ng-infinite-scroll": "^1.3.0",
diff --git a/catalog-ui/src/app/models.ts b/catalog-ui/src/app/models.ts
index 78be1e55e4..7604b6797b 100644
--- a/catalog-ui/src/app/models.ts
+++ b/catalog-ui/src/app/models.ts
@@ -127,4 +127,5 @@ export * from './models/service-instance-properties-and-interfaces';
export * from './models/relationship-types';
export * from './models/tosca-presentation';
export * from './models/node-types';
-export * from './models/capability-types'; \ No newline at end of file
+export * from './models/capability-types';
+export * from './models/service-csar'; \ No newline at end of file
diff --git a/catalog-ui/src/app/models/service-csar.ts b/catalog-ui/src/app/models/service-csar.ts
new file mode 100644
index 0000000000..39f8e05a4b
--- /dev/null
+++ b/catalog-ui/src/app/models/service-csar.ts
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 Nordix Foundation. All rights reserved.
+ * ================================================================================
+ * 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 {ComponentMetadata} from "./component-metadata";
+
+export enum ToscaMetaEntry {
+ ENTRY_DEFINITIONS = "Entry-Definitions"
+}
+
+export class ServiceCsar {
+
+ entryDefinitionFileName: string;
+ interfaceDefinitionFileName: string;
+ substitutionNodeType:string;
+ toscaMeta: ToscaMeta = new ToscaMeta();
+ serviceMetadata: ComponentMetadata = new ComponentMetadata();
+ extraServiceMetadata: Map<string, string> = new Map<string, string>();
+
+}
+
+export class ToscaMeta {
+
+ dataMap: Map<string, string> = new Map<string, string>();
+
+ getEntry(toscaMetaEntry: ToscaMetaEntry): string {
+ return this.dataMap.get(toscaMetaEntry.valueOf());
+ }
+
+}
diff --git a/catalog-ui/src/app/modules/utils.ts b/catalog-ui/src/app/modules/utils.ts
index 7a57478c1c..a2fb6907ce 100644
--- a/catalog-ui/src/app/modules/utils.ts
+++ b/catalog-ui/src/app/modules/utils.ts
@@ -23,6 +23,7 @@ import {ComponentInstanceFactory} from "../utils/component-instance-factory";
import {ChangeLifecycleStateHandler} from "../utils/change-lifecycle-state-handler";
import {ModalsHandler} from "../utils/modals-handler";
import {MenuHandler} from "../utils/menu-handler";
+import {ServiceCsarReader} from "../utils/service-csar-reader";
let moduleName:string = 'Sdc.Utils';
let serviceModule:ng.IModule = angular.module(moduleName, []);
@@ -33,4 +34,5 @@ serviceModule.service('ComponentInstanceFactory', ComponentInstanceFactory);
serviceModule.service('ChangeLifecycleStateHandler', ChangeLifecycleStateHandler);
serviceModule.service('ModalsHandler', ModalsHandler);
serviceModule.service('MenuHandler', MenuHandler);
+serviceModule.service('ServiceCsarReader', ServiceCsarReader);
diff --git a/catalog-ui/src/app/utils.ts b/catalog-ui/src/app/utils.ts
index 27c805a762..ccf9156553 100644
--- a/catalog-ui/src/app/utils.ts
+++ b/catalog-ui/src/app/utils.ts
@@ -32,3 +32,4 @@ export * from './utils/menu-handler';
export * from './utils/constants';
export * from './utils/common-utils';
export * from './utils/functions';
+export * from './utils/service-csar-reader';
diff --git a/catalog-ui/src/app/utils/file-utils.ts b/catalog-ui/src/app/utils/file-utils.ts
index d726736bd4..4b6f330354 100644
--- a/catalog-ui/src/app/utils/file-utils.ts
+++ b/catalog-ui/src/app/utils/file-utils.ts
@@ -66,6 +66,24 @@ export class FileUtils {
"cancelable": true
});
downloadLink.dispatchEvent(clickEvent);
+ }
+ public getEntryDefinitionFileNameFromCsarBlob = (csarBlob:Blob):Promise<any> => {
+ let JSZip = require("jszip");
+ return JSZip.loadAsync(csarBlob).then(zip => {
+ return zip.file("TOSCA-Metadata/TOSCA.meta").async("string");
+ }).then((toscaMetaData: string) => {
+ let fileEntities:Array<string> = toscaMetaData.replace("\r", "").split("\n");
+ let entryDefinitionFilename:string = fileEntities.find(element => !element.search("Entry-Definitions"))
+ .replace("Entry-Definitions:", "").trim();
+ return entryDefinitionFilename;
+ });
+ }
+
+ public getFileNameDataFromCsarBlob = (csarBlob:Blob, fileName:string):Promise<any> => {
+ let JSZip = require("jszip");
+ return JSZip.loadAsync(csarBlob).then(zip => {
+ return zip.file(fileName).async("string");
+ });
}
}
diff --git a/catalog-ui/src/app/utils/service-csar-reader.ts b/catalog-ui/src/app/utils/service-csar-reader.ts
new file mode 100644
index 0000000000..73b77559e2
--- /dev/null
+++ b/catalog-ui/src/app/utils/service-csar-reader.ts
@@ -0,0 +1,139 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 Nordix Foundation. All rights reserved.
+ * ================================================================================
+ * 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 {ServiceCsar, ToscaMetaEntry} from "../models";
+import {load} from 'js-yaml';
+import { ComponentType } from "./constants";
+
+export class ServiceCsarReader {
+
+ private serviceCsar = new ServiceCsar();
+
+ public read(serviceCsarBlob:Blob): Promise<ServiceCsar> {
+ const jsZip = require("jszip");
+ return new Promise<ServiceCsar>((resolve) => {
+ jsZip.loadAsync(serviceCsarBlob).then(async zip => {
+ const toscaMetaFileContent = await zip.file("TOSCA-Metadata/TOSCA.meta").async("string");
+ this.readToscaMeta(toscaMetaFileContent);
+ const entryDefinitionFileContent = await zip.file(this.serviceCsar.entryDefinitionFileName).async("string");
+ this.readServiceMetadata(entryDefinitionFileContent);
+ const interfaceDefinitionFileContent = await zip.file(this.serviceCsar.interfaceDefinitionFileName).async("string");
+ this.readServiceSubstitutionNode(interfaceDefinitionFileContent);
+ resolve(this.serviceCsar);
+ });
+ });
+ }
+
+ private readToscaMeta(toscaMetaFileContent:string) {
+ let fileEntities:Array<string> = toscaMetaFileContent.replace("\r", "").split("\n");
+ for(let entity of fileEntities.filter(e => e)) {
+ let mapEntry:Array<string> = entity.split(":");
+ let key:string = mapEntry[0].trim();
+ let value:string = mapEntry[1].trim();
+ this.serviceCsar.toscaMeta.dataMap.set(key, value);
+ }
+ this.readEntryDefinitionFileName();
+ this.readInterfaceDefinitionFileName();
+ }
+
+ private readEntryDefinitionFileName() {
+ this.serviceCsar.entryDefinitionFileName = this.serviceCsar.toscaMeta.getEntry(ToscaMetaEntry.ENTRY_DEFINITIONS);
+ }
+
+ private readInterfaceDefinitionFileName() {
+ let fileNameArray:Array<string> = this.serviceCsar.entryDefinitionFileName.split(".");
+ fileNameArray.splice(fileNameArray.length - 1, 0, "-interface.");
+ this.serviceCsar.interfaceDefinitionFileName = fileNameArray.join("");
+ }
+
+ private readServiceMetadata(entryDefinitionFileContent) {
+ const metadata = load(entryDefinitionFileContent).metadata;
+ this.setMetadata(metadata);
+ }
+
+ private readServiceSubstitutionNode(interfaceDefinitionFileContent) {
+ const nodeTypes = load(interfaceDefinitionFileContent).node_types;
+ let nodeType = Object.keys(nodeTypes).values().next().value;
+ this.serviceCsar.substitutionNodeType = nodeTypes[nodeType]["derived_from"];
+ }
+
+ private setMetadata = (metadata:object) : void => {
+ let extraServiceMetadata: Map<string, string> = new Map<string, string>();
+ this.serviceCsar.serviceMetadata.componentType = ComponentType.SERVICE;
+ this.serviceCsar.serviceMetadata.serviceType = "Service";
+ Object.keys(metadata).forEach(variable => {
+ switch(variable) {
+ case "description": {
+ this.serviceCsar.serviceMetadata.description = metadata[variable];
+ break;
+ }
+ case "name": {
+ this.serviceCsar.serviceMetadata.name = metadata[variable];
+ break;
+ }
+ case "model": {
+ this.serviceCsar.serviceMetadata.model = metadata[variable];
+ break;
+ }
+ case "category": {
+ this.serviceCsar.serviceMetadata.selectedCategory = metadata[variable];
+ break;
+ }
+ case "serviceRole": {
+ this.serviceCsar.serviceMetadata.serviceRole = metadata[variable];
+ break;
+ }
+ case "serviceFunction": {
+ this.serviceCsar.serviceMetadata.serviceFunction = metadata[variable];
+ break;
+ }
+ case "environmentContext": {
+ if (metadata[variable] != null) {
+ this.serviceCsar.serviceMetadata.environmentContext = metadata[variable];
+ }
+ break;
+ }
+ case "instantiationType": {
+ if (metadata[variable] != null) {
+ this.serviceCsar.serviceMetadata.instantiationType = metadata[variable];
+ }
+ break;
+ }
+ case "ecompGeneratedNaming": {
+ if (metadata[variable] != null) {
+ this.serviceCsar.serviceMetadata.ecompGeneratedNaming = metadata[variable] == "false" ? false : true;
+ }
+ break;
+ }
+ case "namingPolicy": {
+ if (metadata["ecompGeneratedNaming"] != "false") {
+ this.serviceCsar.serviceMetadata.namingPolicy = metadata[variable];
+ }
+ break;
+ }
+ default: {
+ extraServiceMetadata.set(variable, metadata[variable])
+ break;
+ }
+ }
+ });
+ this.serviceCsar.extraServiceMetadata = extraServiceMetadata;
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
index 6b0d49029a..0057ba4669 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
@@ -30,7 +30,9 @@ import {
instantiationType,
ModalsHandler,
ResourceType,
- ValidationUtils
+ ValidationUtils,
+ FileUtils,
+ ServiceCsarReader
} from "app/utils";
import {EventListenerService, ProgressService} from "app/services";
import {CacheService, ElementService, ModelService, ImportVSPService, OnboardingService} from "app/services-ng2";
@@ -121,6 +123,7 @@ export class GeneralViewModel {
'VendorModelNumberValidationPattern',
'CommentValidationPattern',
'ValidationUtils',
+ 'FileUtils',
'sdcConfig',
'$state',
'ModalsHandler',
@@ -148,6 +151,7 @@ export class GeneralViewModel {
private VendorModelNumberValidationPattern:RegExp,
private CommentValidationPattern:RegExp,
private ValidationUtils:ValidationUtils,
+ private FileUtils: FileUtils,
private sdcConfig:IAppConfigurtaion,
private $state:ng.ui.IStateService,
private ModalsHandler:ModalsHandler,
@@ -276,9 +280,25 @@ export class GeneralViewModel {
} else if(this.$scope.component.isService()){
let service: Service = <Service>this.$scope.component;
console.log(service.name + ": " + service.csarUUID);
- if (service.importedFile) { // Component has imported file.
+ if (service.importedFile) {
this.$scope.isShowFileBrowse = true;
- (<Service>this.$scope.component).serviceType = 'Service';
+ (<Service>this.$scope.component).ecompGeneratedNaming = true;
+ let blob = this.FileUtils.base64toBlob(service.importedFile.base64, "zip");
+ new ServiceCsarReader().read(blob).then((serviceCsar) => {
+ serviceCsar.serviceMetadata.contactId = this.cacheService.get("user").userId;
+ (<Service>this.$scope.component).setComponentMetadata(serviceCsar.serviceMetadata);
+ (<Service>this.$scope.component).model = serviceCsar.serviceMetadata.model;
+ this.$scope.onModelChange();
+ this.$scope.componentCategories.selectedCategory = serviceCsar.serviceMetadata.selectedCategory;
+ this.$scope.onCategoryChange();
+ serviceCsar.extraServiceMetadata.forEach((value: string, key: string) => {
+ if(this.getMetadataKey(key)) {
+ (<Service>this.$scope.component).categorySpecificMetadata[key] = value;
+ }
+ });
+ (<Service>this.$scope.component).derivedFromGenericType = serviceCsar.substitutionNodeType;
+ this.$scope.onBaseTypeChange();
+ });
}
if (this.$scope.isEditMode() && service.serviceType == 'Service' && !service.csarUUID) {
this.$scope.isShowFileBrowse = true;
@@ -878,7 +898,9 @@ export class GeneralViewModel {
if (this.$scope.isBaseTypeRequired) {
const baseType = baseTypeResponseList.baseTypes[0];
baseType.versions.reverse().forEach(version => this.$scope.baseTypeVersions.push(version));
- this.$scope.component.derivedFromGenericType = baseType.toscaResourceName;
+ if(!this.$scope.component.derivedFromGenericType) {
+ this.$scope.component.derivedFromGenericType = baseType.toscaResourceName;
+ }
this.$scope.component.derivedFromGenericVersion = this.$scope.baseTypeVersions[0];
this.$scope.showBaseTypeVersions = true;
return