Fix 'Fail to import service with CP'-bug
[sdc.git] / catalog-ui / src / app / utils / service-csar-reader.ts
1 /*
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2022 Nordix Foundation. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 import {ServiceCsar, ToscaMetaEntry} from "../models";
22 import {load} from 'js-yaml';
23 import {ComponentType} from "./constants";
24
25 export class ServiceCsarReader {
26
27     private serviceCsar = new ServiceCsar();
28
29     public read(serviceCsarBlob: Blob): Promise<ServiceCsar> {
30         const jsZip = require("jszip");
31         return new Promise<ServiceCsar>((resolve, reject) => {
32             jsZip.loadAsync(serviceCsarBlob).then(async zip => {
33                 try {
34                     const toscaMetaFileContent = await zip.file("TOSCA-Metadata/TOSCA.meta").async("string");
35                     this.readToscaMeta(toscaMetaFileContent);
36                     const entryDefinitionFileContent = await zip.file(this.serviceCsar.entryDefinitionFileName).async("string");
37                     this.readServiceMetadata(entryDefinitionFileContent);
38                     if (zip.file(this.serviceCsar.interfaceDefinitionFileName) != null) {
39                         const interfaceDefinitionFileContent = await zip.file(this.serviceCsar.interfaceDefinitionFileName).async("string");
40                         this.readSubstitutionNodeFromInterfaceDefinitionFile(interfaceDefinitionFileContent);
41                     } else {
42                         this.readSubstitutionNodeFromMainTemplateFile(entryDefinitionFileContent);
43                     }
44                     resolve(this.serviceCsar);
45                 } catch (error) {
46                     reject(error);
47                 }
48             });
49         });
50     }
51
52     private readToscaMeta(toscaMetaFileContent:string) {
53         let fileEntities:Array<string> = toscaMetaFileContent.replace("\r", "").split("\n");
54         for(let entity of fileEntities.filter(e => e)) {
55             let mapEntry:Array<string> = entity.split(":");
56             let key:string = mapEntry[0].trim();
57             let value:string = mapEntry[1].trim();
58             this.serviceCsar.toscaMeta.dataMap.set(key, value);
59         }
60         this.readEntryDefinitionFileName();
61         this.readInterfaceDefinitionFileName();
62     }
63
64     private readEntryDefinitionFileName() {
65         this.serviceCsar.entryDefinitionFileName = this.serviceCsar.toscaMeta.getEntry(ToscaMetaEntry.ENTRY_DEFINITIONS);
66     }
67     private readInterfaceDefinitionFileName() {
68         let fileNameArray:Array<string> = this.serviceCsar.entryDefinitionFileName.split(".");
69         fileNameArray.splice(fileNameArray.length - 1, 0, "-interface.");
70         this.serviceCsar.interfaceDefinitionFileName = fileNameArray.join("");
71     }
72
73     private readServiceMetadata(entryDefinitionFileContent) {
74         const metadata = load(entryDefinitionFileContent).metadata;
75         this.setMetadata(metadata);
76     }
77
78     private readSubstitutionNodeFromInterfaceDefinitionFile(interfaceDefinitionFileContent) {
79         const nodeTypes = load(interfaceDefinitionFileContent).node_types;
80         let nodeType = Object.keys(nodeTypes).values().next().value;
81         this.serviceCsar.substitutionNodeType = nodeTypes[nodeType]["derived_from"];
82     }
83
84     private readSubstitutionNodeFromMainTemplateFile(entryDefinitionFileContent) {
85         const loadEntryDefinitionFileContent = load(entryDefinitionFileContent);
86         if (loadEntryDefinitionFileContent.topology_template && loadEntryDefinitionFileContent.topology_template.substitution_mappings) {
87             this.serviceCsar.substitutionNodeType = loadEntryDefinitionFileContent.topology_template.substitution_mappings.node_type;
88         }
89     }
90
91     private setMetadata = (metadata:object) : void => {
92         let extraServiceMetadata: Map<string, string> = new Map<string, string>();
93         this.serviceCsar.serviceMetadata.componentType = ComponentType.SERVICE;
94         this.serviceCsar.serviceMetadata.serviceType = "Service";
95         Object.keys(metadata).forEach(variable => {
96             switch(variable) {
97                 case "description": {
98                     this.serviceCsar.serviceMetadata.description = metadata[variable];
99                     break;
100                 }
101                 case "name": {
102                     this.serviceCsar.serviceMetadata.name = metadata[variable];
103                     break;
104                 }
105                 case "model": {
106                     this.serviceCsar.serviceMetadata.model = metadata[variable];
107                     break;
108                 }
109                 case "category": {
110                     this.serviceCsar.serviceMetadata.selectedCategory = metadata[variable];
111                     break;
112                 }
113                 case "serviceRole": {
114                     this.serviceCsar.serviceMetadata.serviceRole = metadata[variable];
115                     break;
116                 }
117                 case "serviceFunction": {
118                     this.serviceCsar.serviceMetadata.serviceFunction = metadata[variable];
119                     break;
120                 }
121                 case "environmentContext": {
122                     if (metadata[variable] != null) {
123                         this.serviceCsar.serviceMetadata.environmentContext = metadata[variable];
124                     }
125                     break;
126                 }
127                 case "instantiationType": {
128                     if (metadata[variable] != null) {
129                         this.serviceCsar.serviceMetadata.instantiationType = metadata[variable];
130                     }
131                     break;
132                 }
133                 case "ecompGeneratedNaming": {
134                     if (metadata[variable] != null) {
135                         this.serviceCsar.serviceMetadata.ecompGeneratedNaming = metadata[variable] == "false" ? false : true;
136                     }
137                     break;
138                 }
139                 case "namingPolicy": {
140                     if (metadata["ecompGeneratedNaming"] != "false") {
141                         this.serviceCsar.serviceMetadata.namingPolicy = metadata[variable];
142                     }
143                     break;
144                 }
145                 default: {
146                     extraServiceMetadata.set(variable, metadata[variable])
147                     break;
148                 }
149             }
150         });
151         this.serviceCsar.extraServiceMetadata = extraServiceMetadata;
152     }
153 }