5d7b37f0fa39af366f5a60888eabc2a3a56bcfb0
[sdc.git] / catalog-ui / src / app / ng2 / services / component-services / component.service.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. 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 * as _ from "lodash";
22 import {Injectable, Inject} from '@angular/core';
23 import {Observable} from 'rxjs/Observable';
24 import 'rxjs/add/operator/map';
25 import 'rxjs/add/operator/toPromise';
26 import { Component, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData, OperationModel, CreateOperationResponse, ArtifactModel} from "app/models";
27 import {COMPONENT_FIELDS} from "app/utils";
28 import {ComponentGenericResponse} from "../responses/component-generic-response";
29 import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map";
30 import {API_QUERY_PARAMS} from "app/utils";
31 import {ComponentType, ServerTypeUrl, SERVICE_FIELDS} from "../../../utils/constants";
32 import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config";
33 import {IDependenciesServerResponse} from "../responses/dependencies-server-response";
34 import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response";
35 import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service";
36 import {ComponentInstance} from "../../../models/componentsInstances/componentInstance";
37 import {CommonUtils} from "../../../utils/common-utils";
38 import {RelationshipModel} from "../../../models/graph/relationship";
39 import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http";
40 import { BEOperationModel, InterfaceModel } from "../../../models/operation";
41 import { PropertyBEModel } from "../../../models/properties-inputs/property-be-model";
42 import { PolicyInstance } from "../../../models/graph/zones/policy-instance";
43 import { ConstraintObject } from "../../components/logic/service-dependencies/service-dependencies.component";
44 import { Requirement } from "../../../models/requirement";
45 import { Capability } from "../../../models/capability";
46 import { OutputBEModel } from "app/models/attributes-outputs/output-be-model";
47
48 /*
49 PLEASE DO NOT USE THIS SERVICE IN ANGULAR2! Use the topology-template.service instead
50  */
51 @Injectable()
52 export class ComponentServiceNg2 {
53
54     protected baseUrl;
55
56     constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) {
57         this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root;
58     }
59
60     protected getComponentDataByFieldsName(componentType:string, componentId:string, fields:Array<string>):Observable<ComponentGenericResponse> {
61
62         let params: HttpParams = new HttpParams();
63         fields.forEach((field:string):void => {
64             params = params.append(API_QUERY_PARAMS.INCLUDE, field);
65         });
66
67         return this.http.get<ComponentGenericResponse>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/filteredDataByParams', {params: params})
68             .map((res) => {
69                 return new ComponentGenericResponse().deserialize(res);
70             });
71     }
72     protected getServerTypeUrl = (componentType:string):string => {
73         switch (componentType) {
74             case ComponentType.SERVICE:
75                 return ServerTypeUrl.SERVICES;
76             default:
77                 return ServerTypeUrl.RESOURCES;
78         }
79     }
80
81     getFullComponent(uniqueId:string):Observable<ComponentGenericResponse> {
82         return this.http.get<ComponentGenericResponse>(this.baseUrl + uniqueId)
83             .map((res) => {
84                 return new ComponentGenericResponse().deserialize(res);
85             });
86     }
87
88     getComponentMetadata(uniqueId:string, type:string):Observable<ComponentGenericResponse> {
89         return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_METADATA]);
90     }
91
92
93     getComponentInstanceAttributesAndProperties(component:Component):Observable<ComponentGenericResponse> {
94         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]);
95     }
96
97     getComponentInstanceProperties(component:Component): Observable<ComponentGenericResponse> {
98         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]);
99     }
100
101     getComponentAttributes(component:Component):Observable<ComponentGenericResponse> {
102         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES]);
103     }
104
105     getComponentCompositionData(component:Component):Observable<ComponentGenericResponse> {
106         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
107     }
108
109     getComponentResourcePropertiesData(component:Component):Observable<ComponentGenericResponse> {
110         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
111     }
112
113     getComponentResourceAttributesData(component:Component):Observable<ComponentGenericResponse> {
114         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
115     }
116
117     getComponentResourceInstances(component:Component):Observable<ComponentGenericResponse> {
118         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES]);
119     }
120
121     getComponentInputs(component:Component):Observable<ComponentGenericResponse> {
122         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INPUTS]);
123     }
124
125     getComponentInputsWithProperties(component:Component):Observable<ComponentGenericResponse> {
126         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INPUTS, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
127     }
128
129     getComponentDeploymentArtifacts(component:Component):Observable<ComponentGenericResponse> {
130         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_DEPLOYMENT_ARTIFACTS]);
131     }
132
133     getComponentInformationalArtifacts(component:Component):Observable<ComponentGenericResponse> {
134         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS]);
135     }
136
137     getComponentInformationalArtifactsAndInstances(component:Component):Observable<ComponentGenericResponse> {
138         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS, COMPONENT_FIELDS.COMPONENT_INSTANCES]);
139     }
140
141     getComponentToscaArtifacts(component:Component):Observable<ComponentGenericResponse> {
142         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_TOSCA_ARTIFACTS]);
143     }
144
145     getComponentProperties(component:Component):Observable<ComponentGenericResponse> {
146         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
147     }
148
149     getInterfaceOperations(component:Component):Observable<ComponentGenericResponse> {
150         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INTERFACE_OPERATIONS]);
151     }
152
153     getInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> {
154         return this.http.get<OperationModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId);
155     }
156
157     // tslint:disable-next-line:member-ordering
158     createInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> {
159         const operationList = {
160             'interfaces': {
161                 [operation.interfaceType]: {
162                     'type': operation.interfaceType,
163                     'operations': {
164                         [operation.name]: new BEOperationModel(operation)
165                     }
166                 }
167             }
168         };
169         return this.http.post<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList)
170             .map((res:any) => {
171                 const interf:InterfaceModel = _.find(res.interfaces, interf => interf.type === operation.interfaceType);
172                 const newOperation:OperationModel = _.find(interf.operations, op => op.name === operation.name);
173                 return new OperationModel({
174                     ...newOperation,
175                     interfaceType: interf.type,
176                     interfaceId: interf.uniqueId,
177                     artifactFileName: operation.artifactFileName
178                 });
179             });
180     }
181
182     // tslint:disable-next-line:member-ordering
183     updateInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> {
184         const operationList = {
185             interfaces: {
186                 [operation.interfaceType]: {
187                     type: operation.interfaceType,
188                     operations: {
189                         [operation.name]: new BEOperationModel(operation)
190                     }
191                 }
192             }
193         };
194         return this.http.put<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList)
195             .map((res: any) => {
196                 const interf: InterfaceModel = _.find(res.interfaces, interf => interf.type === operation.interfaceType);
197                 const newOperation: OperationModel = _.find(interf.operations, op => op.name === operation.name);
198                 return new OperationModel({
199                     ...newOperation,
200                     interfaceType: interf.type,
201                     interfaceId: interf.uniqueId,
202                     artifactFileName: operation.artifactFileName
203                 });
204             });
205     }
206
207
208     deleteInterfaceOperation(component: Component, operation:OperationModel):Observable<OperationModel> {
209         return this.http.delete<OperationModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaces/' + operation.interfaceId + '/operations/' + operation.uniqueId);
210     }
211
212     getInterfaceTypes(component:Component):Observable<{[id:string]: Array<string>}> {
213         return this.http.get<any>(this.baseUrl + 'interfaceLifecycleTypes' + ((component && component.model) ? '?model=' + component.model : ''))
214             .map((res: any) => {
215                 const interfaceMap = {};
216                 if (!res) {
217                     return interfaceMap;
218                 }
219                 Object.keys(res).forEach(interfaceName => {
220                     const interface1 = res[interfaceName];
221                     if (!interface1.toscaPresentation.operations) {
222                         return;
223                     }
224                     interfaceMap[interface1.toscaPresentation.type] = Object.keys(interface1.toscaPresentation.operations);
225                 });
226                 return interfaceMap;
227             });
228     }
229
230     uploadInterfaceOperationArtifact(component:Component, newOperation:OperationModel, oldOperation:OperationModel) {
231         const payload = {
232             artifactType: "WORKFLOW",
233             artifactName: oldOperation.artifactFileName,
234             description: "Workflow Artifact Description",
235             payloadData: oldOperation.artifactData
236         };
237
238
239         JSON.stringify(payload);
240         const payloadString = JSON.stringify(payload, null, '  ');
241         const md5Result = md5(payloadString).toLowerCase();
242         const headers = new HttpHeaders().append('Content-MD5', btoa(md5Result));
243
244         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uuid + '/interfaces/' + newOperation.interfaceId + '/operations/' + newOperation.uniqueId + '/artifacts/' + newOperation.implementation.artifactUUID,
245                 payload, {headers}
246             ).map((res: any) => {
247                 const fileName = res.artifactDisplayName || res.artifactName;
248                 newOperation.artifactFileName = fileName;
249                 return res;
250             });
251     }
252
253     getCapabilitiesAndRequirements(componentType: string, componentId:string):Observable<ComponentGenericResponse> {
254         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES]);
255     }
256
257
258
259
260
261     getDeploymentGraphData(component:Component):Observable<ComponentGenericResponse> {
262         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_GROUPS]);
263     }
264
265     createInput(component:Component, inputsToCreate:InstancePropertiesAPIMap, isSelf:boolean):Observable<any> {
266         const inputs = isSelf ? { serviceProperties: inputsToCreate.componentInstanceProperties } : inputsToCreate;
267         return this.http.post<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/inputs', inputs);
268     }
269
270     createListInput(component:Component, input:any, isSelf:boolean):Observable<any> {
271         let inputs: any;
272         if(isSelf) {
273             // change componentInstanceProperties -> serviceProperties
274             inputs = {
275                 componentInstInputsMap: {
276                     serviceProperties: input.componentInstInputsMap.componentInstanceProperties
277                 },
278                 listInput: input.listInput
279             };
280         } else {
281             inputs = input;
282         }
283         return this.http.post<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/listInput', inputs);
284     }
285
286     createPolicy(component:Component, policiesToCreate:InstancePropertiesAPIMap, isSelf:boolean):Observable<any> {
287         const policiesList =
288             isSelf ?
289                 {'componentPropertiesToPolicies': {
290                         ...policiesToCreate.componentInstanceProperties
291                     }
292                 } :
293                 {'componentInstancePropertiesToPolicies': {
294                         ...policiesToCreate.componentInstanceProperties
295                     }
296                 };
297         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/policies', policiesList);
298     }
299
300     deletePolicy(component:Component, policy: PolicyInstance) {
301         return this.http.put<PolicyInstance>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policy.uniqueId + '/undeclare', policy);
302     }
303
304     restoreComponent(componentType:string, componentId:string) {
305         return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/restore', {})
306     }
307
308     archiveComponent(componentType:string, componentId:string) {
309         return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/archive', {})
310     }
311
312     deleteInput(component:Component, input:InputBEModel):Observable<InputBEModel> {
313
314         return this.http.delete<InputBEModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input')
315             .map((res) => {
316                 return new InputBEModel(res);
317             })
318     }
319
320     deleteOutput(component:Component, output:OutputBEModel):Observable<OutputBEModel> {
321
322         return this.http.delete<OutputBEModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + output.uniqueId + '/output')
323             .map((res) => {
324                 return new OutputBEModel(res);
325             })
326     }
327
328     updateComponentInputs(component:Component, inputs:InputBEModel[]):Observable<InputBEModel[]> {
329
330         return this.http.post<InputBEModel[]>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs)
331             .map((res) => {
332                 return res.map((input) => new InputBEModel(input));
333             })
334     }
335
336     updateComponentOutputs(component:Component, outputs:OutputBEModel[]):Observable<OutputBEModel[]> {
337
338         return this.http.post<OutputBEModel[]>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/outputs', outputs)
339             .map((res) => {
340                 return res.map((output) => new OutputBEModel(output));
341             })
342     }
343
344     filterComponentInstanceProperties(component:Component, filterData:FilterPropertiesAssignmentData):Observable<InstanceBePropertiesMap> {//instance-property-be-map
345         let params: HttpParams = new HttpParams();
346         filterData.selectedTypes.forEach((type:string) => {
347             params = params.append('resourceType', type);
348         });
349
350         return this.http.get<InstanceBePropertiesMap>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {params: params});
351     }
352
353     filterComponentInstanceAttributes(component:Component, filterData:FilterPropertiesAssignmentData):Observable<InstanceBePropertiesMap> {//instance-property-be-map
354         let params: HttpParams = new HttpParams();
355         filterData.selectedTypes.forEach((type:string) => {
356             params = params.append('resourceType', type);
357         });
358
359         return this.http.get<InstanceBePropertiesMap>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {params: params});
360     }
361
362     createServiceProperty(component: Component, propertyModel:PropertyBEModel): Observable<PropertyBEModel> {
363         let serverObject = {};
364         serverObject[propertyModel.name] = propertyModel;
365         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties', serverObject)
366             .map((res: PropertyBEModel) => {
367                 const property: PropertyBEModel = new PropertyBEModel(res);
368                 return property;
369             })
370     }
371
372     getServiceProperties(component: Component): Observable<PropertyBEModel[]> {
373         return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties')
374             .map((res: PropertyBEModel[]) => {
375                 if (!res) {
376                     return new Array<PropertyBEModel>();
377                 }
378                 return CommonUtils.initBeProperties(res);
379             });
380     }
381
382     updateServiceProperties(component: Component, properties: PropertyBEModel[]) {
383         return this.http.put<PropertyBEModel[]>( this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties', properties)
384             .map((res) => {
385                 const resJson = res;
386                 return _.map(resJson,
387                     (resValue:PropertyBEModel) => new PropertyBEModel(resValue));
388             });
389     }
390
391     deleteServiceProperty(component:Component, property:PropertyBEModel):Observable<string> {
392         return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties/' + property.uniqueId )
393             .map((res:Response) => {
394                 return property.uniqueId;
395             })
396     }
397
398     getDependencies(componentType:string, componentId: string):Observable<IDependenciesServerResponse[]> {
399         return this.http.get<IDependenciesServerResponse[]>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/dependencies');
400     }
401
402     automatedUpgrade(componentType:string, componentId:string, componentsIdsToUpgrade:IAutomatedUpgradeRequestObj[]):Observable<AutomatedUpgradeGenericResponse> {
403         return this.http.post<AutomatedUpgradeGenericResponse>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/automatedupgrade', componentsIdsToUpgrade);
404     }
405
406     updateMultipleComponentInstances(componentId:string, instances:ComponentInstance[]):Observable<ComponentInstance[]> {
407         return this.http.post<ComponentInstance[]>(this.baseUrl + componentId + '/resourceInstance/multipleComponentInstance', instances);
408     }
409
410     getServiceFilterConstraints(component:Component):Observable<ComponentGenericResponse> {
411         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [SERVICE_FIELDS.NODE_FILTER]);
412     }
413
414     createServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraint:ConstraintObject):Observable<any> {
415         return this.http.post<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter', constraint);
416     }
417
418     updateServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraints:ConstraintObject[]):Observable<any> {
419         return this.http.put<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/', constraints);
420     }
421
422     deleteServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraintIndex:number) {
423         return this.http.delete<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/' + constraintIndex);
424     }
425
426     protected analyzeComponentDataResponse(res: Response):ComponentGenericResponse {
427         return new ComponentGenericResponse().deserialize(res);
428     }
429 }