Support setting interfaces on instances
[sdc.git] / catalog-ui / src / app / ng2 / services / component-services / topology-template.service.ts
1 /**
2  * Created by ob0695 on 6/26/2018.
3  */
4 /*-
5  * ============LICENSE_START=======================================================
6  * SDC
7  * ================================================================================
8  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
9  * Modification Copyright (C) 2022 Nordix Foundation.
10  * ================================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * ============LICENSE_END=========================================================
23  */
24
25 import * as _ from "lodash";
26 import {Inject, Injectable} from '@angular/core';
27 import {Observable} from 'rxjs/Observable';
28 import 'rxjs/add/operator/map';
29 import 'rxjs/add/operator/toPromise';
30 import {
31     ArtifactModel,
32     AttributeModel,
33     Capability,
34     Component,
35     FilterPropertiesAssignmentData,
36     IFileDownload,
37     InputBEModel,
38     InstancePropertiesAPIMap,
39     InterfaceModel,
40     OperationModel,
41     PropertyModel,
42     Requirement
43 } from "app/models";
44 import {API_QUERY_PARAMS, ArtifactGroupType, COMPONENT_FIELDS} from "app/utils";
45 import {ComponentGenericResponse} from "../responses/component-generic-response";
46 import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map";
47 import {ComponentType, ServerTypeUrl, SERVICE_FIELDS} from "../../../utils/constants";
48 import {ISdcConfig, SdcConfigToken} from "../../config/sdc-config.config";
49 import {IDependenciesServerResponse} from "../responses/dependencies-server-response";
50 import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response";
51 import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service";
52 import {ComponentInstance} from "../../../models/componentsInstances/componentInstance";
53 import {CommonUtils} from "../../../utils/common-utils";
54 import {RelationshipModel} from "../../../models/graph/relationship";
55 import {ServiceGenericResponse} from "../responses/service-generic-response";
56 import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
57 import {HttpHelperService} from "../http-hepler.service";
58 import {ConsumptionInput} from "../../components/logic/service-consumption/service-consumption.component";
59 import {PolicyInstance} from "../../../models/graph/zones/policy-instance";
60 import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model";
61 import {map} from "rxjs/operators";
62 import {BEInterfaceOperationModel, InterfaceOperationModel} from "../../../models/interfaceOperation";
63 import {AttributeBEModel} from "../../../models/attributes-outputs/attribute-be-model";
64 import {InstanceAttributesAPIMap} from "../../../models/attributes-outputs/attribute-fe-map";
65 import {FilterConstraint} from "../../../models/filter-constraint";
66 import {CustomToscaFunction, DefaultCustomFunctions} from "../../../models/default-custom-functions";
67
68 /* we need to use this service from now, we will remove component.service when we finish remove the angular1.
69  The service is duplicated since we can not use downgrades service with NGXS*/
70
71 @Injectable()
72 export class TopologyTemplateService {
73
74     protected baseUrl;
75
76     constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) {
77         this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root;
78     }
79
80     putServiceToscaTemplate(componentId: string, componentType: string, file) {
81         return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/toscaTemplate', file)
82     }
83
84     putServiceToscaModel(componentId: string, componentType: string, file) {
85         let uploadData:FormData = new FormData();
86         uploadData.append('upload', file);
87         return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/toscaModel', uploadData);
88     }
89
90     getFullComponent(componentType: string, uniqueId: string): Observable<Component> {
91         return this.http.get<Component>(this.baseUrl + this.getServerTypeUrl(componentType) + uniqueId);
92     }
93
94     getComponentMetadata(uniqueId: string, type: string): Observable<ComponentGenericResponse> {
95         return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_METADATA]);
96     }
97
98     getComponentInstanceAttributesAndProperties(uniqueId: string, type: string): Observable<ComponentGenericResponse> {
99         return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]);
100     }
101
102     getComponentInstanceAttributesAndPropertiesAndInputs(uniqueId: string, type: string): Observable<ComponentGenericResponse> {
103         return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES, COMPONENT_FIELDS.COMPONENT_INPUTS]);
104     }
105
106     async getComponentAttributes(componentType: string, componentId: string): Promise<ComponentGenericResponse> {
107         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES]).toPromise();
108     }
109
110     getComponentCompositionData(componentUniqueId: string, componentType: string): Observable<ComponentGenericResponse> {
111         const params: string[] = [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES,
112             COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS];
113         if (componentType === ComponentType.SERVICE) {
114             params.push(COMPONENT_FIELDS.FORWARDING_PATHS);
115         }
116         return this.getComponentDataByFieldsName(componentType, componentUniqueId, params);
117     }
118
119     getComponentResourcePropertiesData(component: Component): Observable<ComponentGenericResponse> {
120         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId,
121             [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
122     }
123
124     getComponentInstances(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
125         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES]);
126     }
127
128     getComponentInputs(component: Component): Observable<ComponentGenericResponse> {
129         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INPUTS]);
130     }
131
132     getComponentInputsValues(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
133         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INPUTS]);
134     }
135
136     getComponentInputsWithProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
137         return this.getComponentDataByFieldsName(componentType, componentId,
138             [COMPONENT_FIELDS.COMPONENT_INPUTS, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
139     }
140
141     getComponentOutputsWithAttributes(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
142         return this.getComponentDataByFieldsName(componentType, componentId,
143             [COMPONENT_FIELDS.COMPONENT_OUTPUTS, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES, COMPONENT_FIELDS.COMPONENT_ATTRIBUTES,COMPONENT_FIELDS.COMPONENT_INSTANCES_OUTPUTS]);
144     }
145
146     getComponentDeploymentArtifacts(component: Component): Observable<ComponentGenericResponse> {
147         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_DEPLOYMENT_ARTIFACTS]);
148     }
149
150     getComponentInformationalArtifacts(component: Component): Observable<ComponentGenericResponse> {
151         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS]);
152     }
153
154     getComponentInterfaceOperations(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
155         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INTERFACE_OPERATIONS]);
156     }
157
158     getComponentInformationalArtifactsAndInstances(component: Component): Observable<ComponentGenericResponse> {
159         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS, COMPONENT_FIELDS.COMPONENT_INSTANCES]);
160     }
161
162     getComponentToscaArtifacts(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
163         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_TOSCA_ARTIFACTS]);
164     }
165
166     getComponentProperties(component: Component): Observable<ComponentGenericResponse> {
167         return this.findAllComponentProperties(component.componentType, component.uniqueId);
168     }
169
170     findAllComponentProperties(componentType: string, componentUniqueId: string): Observable<ComponentGenericResponse> {
171         return this.getComponentDataByFieldsName(componentType, componentUniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
172     }
173
174     findAllComponentAttributes(componentType: string, componentUniqueId: string): Observable<ComponentGenericResponse> {
175         return this.getComponentDataByFieldsName(componentType, componentUniqueId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES]);
176     }
177
178     findAllComponentAttributesAndProperties(componentType: string, componentUniqueId: string): Observable<ComponentGenericResponse> {
179         return this.getComponentDataByFieldsName(componentType, componentUniqueId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES, COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
180     }
181
182     getCapabilitiesAndRequirements(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
183         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES]);
184     }
185
186     getRequirementsAndCapabilitiesWithProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
187         return this.getComponentDataByFieldsName(componentType, componentId,
188             [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]);
189     }
190
191     getDeploymentGraphData(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
192         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_GROUPS]);
193     }
194
195     createInput(component: Component, inputsToCreate: InstancePropertiesAPIMap, isSelf: boolean): Observable<any> {
196         const inputs = isSelf ? { serviceProperties: inputsToCreate.componentInstanceProperties } : inputsToCreate;
197         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/inputs', inputs);
198     }
199
200     createOutput(component: Component, outputsToCreate: InstanceAttributesAPIMap, isSelf: boolean): Observable<any> {
201         const outputs = isSelf ? { serviceProperties: outputsToCreate.componentInstanceAttributes } : outputsToCreate;
202         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/outputs', outputs);
203     }
204
205     restoreComponent(componentType: string, componentId: string) {
206         return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/restore', {});
207     }
208
209     archiveComponent(componentType: string, componentId: string) {
210         return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/archive', {});
211     }
212
213     deleteInput(component: Component, input: InputBEModel): Observable<InputBEModel> {
214         return this.http.delete<InputBEModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input')
215             .map((res) => {
216                 return new InputBEModel(res);
217             });
218     }
219
220     updateComponentInputs(component: Component, inputs: InputBEModel[]): Observable<InputBEModel[]> {
221         return this.http.post<InputBEModel[]>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs)
222             .map((res) => {
223                 return res.map((input) => new InputBEModel(input));
224             });
225     }
226
227     filterComponentInstanceProperties(component: Component, filterData: FilterPropertiesAssignmentData): Observable<InstanceBePropertiesMap> {// instance-property-be-map
228         let params: HttpParams = new HttpParams();
229         _.forEach(filterData.selectedTypes, (type: string) => {
230             params = params.append('resourceType', type);
231         });
232
233         // tslint:disable-next-line:object-literal-shorthand
234         return this.http.get<InstanceBePropertiesMap>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {params: params});
235     }
236
237      createServiceProperty(componentId: string, propertyModel: PropertyBEModel): Observable<PropertyBEModel> {
238         const serverObject = {};
239         serverObject[propertyModel.name] = propertyModel;
240         return this.http.post<PropertyBEModel>(this.baseUrl + 'services/' + componentId + '/properties', serverObject)
241             .map((res) => {
242                 const property: PropertyBEModel = new PropertyBEModel(res);
243                 return property;
244             });
245     }
246
247     createServiceAttribute(componentId: string, attributeModel: AttributeBEModel): Observable<AttributeBEModel> {
248         const serverObject = {};
249         serverObject[attributeModel.name] = attributeModel;
250         return this.http.post<AttributeBEModel>(this.baseUrl + 'services/' + componentId + '/attributes', serverObject)
251             .map((res) => {
252                 const attribute: AttributeBEModel = new AttributeBEModel(res);
253                 return attribute;
254             });
255     }
256
257     getServiceProperties(componentId: string): Observable<PropertyBEModel[]> {
258         return this.http.get<any>(this.baseUrl + 'services/' + componentId + '/properties')
259             .map((res) => {
260                 if (!res) {
261                     return new Array<PropertyBEModel>();
262                 }
263                 return CommonUtils.initBeProperties(res);
264             });
265     }
266
267     getServiceAttributes(componentId: string): Observable<AttributeBEModel[]> {
268         return this.http.get<any>(this.baseUrl + 'services/' + componentId + '/attributes')
269             .map((res) => {
270                 if (!res) {
271                     return new Array<AttributeBEModel>();
272                 }
273                 return CommonUtils.initAttributes(res);
274             });
275     }
276
277     updateServiceProperties(componentId: string, properties: PropertyBEModel[]) {
278         return this.http.put<any>( this.baseUrl + 'services/' + componentId + '/properties', properties)
279             .map((res) => {
280                 const resJson = res;
281                 return _.map(resJson,
282                     (resValue: PropertyBEModel) => new PropertyBEModel(resValue));
283             });
284     }
285
286     updateServiceAttributes(componentId: string, attributes: AttributeBEModel[]) {
287         return this.http.put<any>( this.baseUrl + 'services/' + componentId + '/attributes', attributes)
288             .map((res) => {
289                 const resJson = res;
290                 return _.map(resJson,
291                     (resValue: AttributeBEModel) => new AttributeBEModel(resValue));
292             });
293     }
294
295     deleteServiceProperty(componentId: string, property: PropertyBEModel): Observable<string> {
296         return this.http.delete(this.baseUrl + 'services/' + componentId + '/properties/' + property.uniqueId )
297             .map((res: Response) => {
298                 return property.uniqueId;
299             });
300     }
301
302     createServiceInput(componentId: string, inputModel: InputBEModel): Observable<InputBEModel> {
303         const serverObject = {};
304         serverObject[inputModel.name] = inputModel;
305         return this.http.post<InputBEModel>(this.baseUrl + 'services/' + componentId + '/create/input', serverObject)
306             .map((res) => {
307                 const input: InputBEModel = new InputBEModel(res);
308                 return input;
309             });
310     }
311
312     deleteServiceAttribute(componentId: string, attribute: AttributeBEModel): Observable<string> {
313         return this.http.delete(this.baseUrl + 'services/' + componentId + '/attributes/' + attribute.uniqueId )
314             .map((res: Response) => {
315                 return attribute.uniqueId;
316             });
317     }
318
319     getDependencies(componentType: string, componentId: string): Observable<IDependenciesServerResponse[]> {
320         return this.http.get<IDependenciesServerResponse[]>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/dependencies');
321     }
322
323     automatedUpgrade(componentType: string, componentId: string, componentsIdsToUpgrade: IAutomatedUpgradeRequestObj[]): Observable<AutomatedUpgradeGenericResponse> {
324         return this.http.post<AutomatedUpgradeGenericResponse>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/automatedupgrade', componentsIdsToUpgrade);
325     }
326
327     updateComponentInstance(componentMetaDataId: string, componentType: string, componentInstance:ComponentInstance): Observable<ComponentInstance> {
328         return this.http.post<ComponentInstance>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstance/' + componentInstance.uniqueId, componentInstance);
329     }
330
331     updateMultipleComponentInstances(componentId: string, componentType: string, instances: ComponentInstance[]): Observable<ComponentInstance[]> {
332         return this.http.post<ComponentInstance[]>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/multipleComponentInstance', instances)
333             .map((res) => {
334                 return CommonUtils.initComponentInstances(res);
335             });
336     }
337
338     createRelation(componentId: string, componentType: string, link: RelationshipModel): Observable<RelationshipModel> {
339         return this.http.post<RelationshipModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/associate', link)
340             .map((res) => {
341                 return new RelationshipModel(res);
342             });
343     }
344
345     deleteRelation(componentId: string, componentType: string, link: RelationshipModel): Observable<RelationshipModel> {
346         return this.http.put<RelationshipModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/dissociate', link)
347             .map((res) => {
348                 return new RelationshipModel(res);
349             });
350     }
351
352     createComponentInstance(componentType: string, componentId: string, componentInstance: ComponentInstance): Observable<ComponentInstance> {
353         return this.http.post<ComponentInstance>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance', componentInstance)
354             .map((res) => {
355                 return new ComponentInstance(res);
356             });
357     }
358
359     deleteComponentInstance(componentType: string, componentId: string, componentInstanceId: string): Observable<ComponentInstance> {
360         return this.http.delete<ComponentInstance>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + componentInstanceId)
361             .map((res) => {
362                 return new ComponentInstance(res);
363             });
364     }
365
366     fetchRelation(componentType: string, componentId: string, linkId: string): Observable<RelationshipModel> {
367         return this.http.get<RelationshipModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/relationId/' + linkId)
368             .map((res) => {
369                 return new RelationshipModel(res);
370             });
371     }
372
373     addOrUpdateArtifact = (componentType: string, componentId: string, artifact: ArtifactModel): Observable<ArtifactModel> => {
374         let headerObj: HttpHeaders = new HttpHeaders();
375         if (artifact.payloadData) {
376             headerObj = headerObj.append('Content-MD5', HttpHelperService.getHeaderMd5(artifact));
377         }
378
379         let artifactID: string = '';
380         if (artifact.uniqueId) {
381             artifactID = '/' + artifact.uniqueId;
382         }
383         return this.http.post<ArtifactModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/artifacts' + artifactID, JSON.stringify(artifact), {headers: headerObj}).map(
384             (res) => new ArtifactModel(res)
385         );
386     }
387
388     deleteArtifact = (componentId: string, componentType: string, artifactId: string, artifactLabel: string): Observable<ArtifactModel> => {
389         return this.http.delete<ArtifactModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/artifacts/' + artifactId + '?operation=' + artifactLabel)
390             .map((res) => new ArtifactModel(res));
391     }
392
393     downloadArtifact = (componentType: string, componentId: string, artifactId: string): Observable<IFileDownload> => {
394         return this.http.get<IFileDownload>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/artifacts/' + artifactId);
395     }
396
397     // ------------------------------------------------ Properties API --------------------------------------------------//
398     addProperty = (componentType: string, componentId: string, property: PropertyModel):Observable<PropertyModel> => {
399         return this.http.post<PropertyModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties', property.convertToServerObject())
400         .map((response) => {
401             return new PropertyModel(response);
402         });
403     }
404
405     updateProperty = (componentType: string, componentId: string, property: PropertyModel): Observable<PropertyModel> => {
406         const propertiesList: PropertyBEModel[] = [property];
407         return this.http.put<PropertyModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties', propertiesList)
408         .map((response) => {
409             return new PropertyModel(response[Object.keys(response)[0]]);
410         });
411     }
412
413     deleteProperty = (componentType: string, componentId: string, propertyId: string): Observable<PropertyModel> => {
414         return this.http.delete<PropertyModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties/' + propertyId);
415     }
416
417     // ------------------------------------------------ Attributes API --------------------------------------------------//
418     addAttribute = (componentType: string, componentId: string, attribute: AttributeModel): Observable<AttributeModel> => {
419         return this.http.post<AttributeModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/attributes', attribute.convertToServerObject())
420             .map((response) => {
421                 return new AttributeModel(response);
422             });
423     }
424
425     updateAttribute = (componentType: string, componentId: string, attribute: AttributeModel): Observable<AttributeModel> => {
426         const payload = attribute.convertToServerObject();
427
428         return this.http.put<AttributeModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/attributes/' + attribute.uniqueId, payload)
429             .map((response) => {
430                 return new AttributeModel(response);
431             });
432     }
433
434     // Async Methods
435     addAttributeAsync = async (componentType: string, componentId: string, attribute: AttributeModel): Promise<AttributeModel> => {
436         return this.addAttribute(componentType, componentId, attribute).toPromise();
437     }
438
439     updateAttributeAsync = async (componentType: string, componentId: string, attribute: AttributeModel): Promise<AttributeModel> => {
440         return this.updateAttribute(componentType, componentId, attribute).toPromise();
441     }
442
443     deleteAttributeAsync = async (componentType: string, componentId: string, attribute: AttributeModel): Promise<any> => {
444         return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/attributes/' + attribute.uniqueId, {}).toPromise();
445     }
446
447     getArtifactsByType(componentType: string, componentId: string, artifactsType: ArtifactGroupType) {
448         return this.getComponentDataByFieldsName(componentType, componentId, [this.convertArtifactTypeToUrl(artifactsType)]);
449     }
450
451     getServiceConsumptionData(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
452         return this.getComponentDataByFieldsName(componentType, componentId, [
453             // COMPONENT_FIELDS.COMPONENT_INSTANCES_INTERFACES,
454             COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES,
455             // COMPONENT_FIELDS.COMPONENT_INSTANCES_INPUTS,
456             COMPONENT_FIELDS.COMPONENT_INPUTS,
457             COMPONENT_FIELDS.COMPONENT_INSTANCES,
458             COMPONENT_FIELDS.COMPONENT_CAPABILITIES
459         ]);
460     }
461
462     getServiceConsumptionInputs(componentMetaDataId: string, serviceInstanceId: string, interfaceId: string, operation: OperationModel): Observable<ConsumptionInput[]> {
463         return this.http.get<ConsumptionInput[]>
464         (this.baseUrl + 'services/' + componentMetaDataId + '/consumption/' + serviceInstanceId + '/interfaces/' + interfaceId + '/operations/' + operation.uniqueId + '/inputs');
465     }
466
467     createOrUpdateServiceConsumptionInputs(componentMetaDataId: string, serviceInstanceId: string, consumptionInputsList: Array<{[id: string]: ConsumptionInput[]}>): Observable<any> {
468         return this.http.post(this.baseUrl + 'services/' + componentMetaDataId + '/consumption/' + serviceInstanceId, consumptionInputsList);
469     }
470
471     getServiceFilterConstraints(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
472         return this.getComponentDataByFieldsName(componentType, componentId, [SERVICE_FIELDS.NODE_FILTER]);
473     }
474
475     getSubstitutionFilterConstraints(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
476         return this.getComponentDataByFieldsName(componentType, componentId, [SERVICE_FIELDS.SUBSTITUTION_FILTER]);
477     }
478
479     getComponentInstanceProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
480         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]);
481     }
482
483     findAllComponentInstanceAttributes(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
484         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]);
485     }
486
487     getComponentInstanceCapabilityProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
488         return this.getComponentDataByFieldsName(componentType, componentId,
489             [COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]);
490     }
491
492     createServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable<any> {
493         return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint);
494     }
495
496     createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable<any> {
497         return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint);
498     }
499
500     updateServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{
501         return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraint)
502     }
503
504     updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: FilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{
505         return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints)
506     }
507
508     deleteServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraintIndex: number, componentType: string, constraintType: string): Observable<any>{
509         return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter')
510     }
511
512     getComponentPropertiesAndInputsForSubstitutionFilter(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
513         return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INPUTS]);
514     }
515
516     createSubstitutionFilterConstraints(componentMetaDataId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable<any> {
517         return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType, constraint);
518     }
519
520     updateSubstitutionFilterConstraint(componentId: string, constraint: FilterConstraint, componentType: string, constraintType: string,
521                                        index: number): Observable<any> {
522         const url = `${this.baseUrl}${this.getServerTypeUrl(componentType)}${componentId}/substitutionFilter/${constraintType}/${index}`;
523         return this.http.put<any>(url, constraint);
524     }
525
526     deleteSubstitutionFilterConstraints(componentMetaDataId: string, constraintIndex: number, componentType: string, constraintType: string): Observable<any>{
527         return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType + "/" + constraintIndex)
528     }
529
530     deletePolicy(component: Component, policy: PolicyInstance): Observable<PolicyInstance> {
531         return this.http.put<PolicyInstance>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policy.uniqueId + '/undeclare', policy)
532     }
533
534     createListInput(component: Component, input: any, isSelf: boolean): Observable<any> {
535         let inputs: any;
536         if (isSelf) {
537             // change componentInstanceProperties -> serviceProperties
538             inputs = {
539                 componentInstInputsMap: {
540                     serviceProperties: input.componentInstInputsMap.componentInstanceProperties
541                 },
542                 listInput: input.listInput
543             };
544         } else {
545             inputs = input;
546         }
547         return this.http.post<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/listInput', inputs);
548     }
549
550     createPolicy(component: Component, policiesToCreate: InstancePropertiesAPIMap, isSelf: boolean): Observable<any> {
551         const policiesList =
552             isSelf ?
553                 // tslint:disable-next-line:object-literal-key-quotes
554                 {'componentPropertiesToPolicies': {
555                         ...policiesToCreate.componentInstanceProperties
556                     }
557                 } :
558                 // tslint:disable-next-line:object-literal-key-quotes
559                 {'componentInstancePropertiesToPolicies': {
560                         ...policiesToCreate.componentInstanceProperties
561                     }
562                 };
563         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/policies', policiesList);
564     }
565
566     protected getComponentDataByFieldsName(componentType: string, componentId: string, fields: string[]): Observable<ComponentGenericResponse> {
567         let params: HttpParams = new HttpParams();
568         _.forEach(fields, (field: string): void => {
569             params = params.append(API_QUERY_PARAMS.INCLUDE, field);
570         });
571         // tslint:disable-next-line:object-literal-shorthand
572         return this.http.get<ComponentGenericResponse>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/filteredDataByParams', {params: params})
573             .map((res) => {
574                 return componentType === ComponentType.SERVICE ? new ServiceGenericResponse().deserialize(res) :
575                         new ComponentGenericResponse().deserialize(res);
576             });
577     }
578
579     private getServerTypeUrl = (componentType: string): string => {
580         switch (componentType) {
581             case ComponentType.SERVICE:
582             case ComponentType.SERVICE_PROXY:
583             case ComponentType.SERVICE_SUBSTITUTION:
584                 return ServerTypeUrl.SERVICES;
585             default:
586                 return ServerTypeUrl.RESOURCES;
587         }
588     }
589
590     private convertArtifactTypeToUrl = (artifactType: ArtifactGroupType): string => {
591         switch (artifactType) {
592             case ArtifactGroupType.TOSCA:
593                 return COMPONENT_FIELDS.COMPONENT_TOSCA_ARTIFACTS;
594             case ArtifactGroupType.INFORMATION:
595                 return COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS;
596             case ArtifactGroupType.DEPLOYMENT:
597                 return COMPONENT_FIELDS.COMPONENT_DEPLOYMENT_ARTIFACTS;
598             case ArtifactGroupType.SERVICE_API:
599                 return COMPONENT_FIELDS.SERVICE_API_ARTIFACT;
600         }
601     }
602
603     // createCapability(component: Component, capabilityData: Capability): Observable<Capability[]> {
604     createCapability(type: string, uniqueId: string, capabilityData: Capability): Observable<Capability[]> {
605         let capBEObj = {
606             'capabilities': {
607                 [capabilityData.type]: [capabilityData]
608             }
609         };
610         return this.http.post<any>(this.baseUrl + type + uniqueId + '/capabilities', capBEObj);
611     }
612
613     updateCapability(type: string, uniqueId: string, capabilityData: Capability): Observable<Capability[]> {
614         let capBEObj = {
615             'capabilities': {
616                 [capabilityData.type]: [capabilityData]
617             }
618         };
619         return this.http.put<any>(this.baseUrl + type + uniqueId + '/capabilities', capBEObj);
620     }
621
622     deleteCapability(component: Component, capId: string): Observable<Capability> {
623         return this.http.delete<Capability>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/capabilities/' + capId);
624     }
625
626     createRequirement(type: string, uniqueId: string, requirementData: Requirement): Observable<any> {
627         let reqBEObj = {
628             'requirements': {
629                 [requirementData.capability]: [requirementData]
630             }
631         };
632         return this.http.post(this.baseUrl + type + uniqueId + '/requirements', reqBEObj);
633     }
634
635     updateRequirement(type: string, uniqueId: string, requirementData: Requirement): Observable<any> {
636         let reqBEObj = {
637             'requirements': {
638                 [requirementData.capability]: [requirementData]
639             }
640         };
641         return this.http.put(this.baseUrl + type + uniqueId + '/requirements', reqBEObj);
642     }
643
644     deleteRequirement(component: Component, reqId: string): Observable<Requirement> {
645         return this.http.delete<Requirement>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/requirements/' + reqId);
646     }
647
648     getDirectiveList(): Observable<string[]> {
649         return this.http.get<ListDirectiveResponse>(this.baseUrl + "directives")
650         .pipe(map(response => response.directives));
651     }
652
653     updateComponentInstanceInterfaceOperation(componentMetaDataId: string,
654                                               componentMetaDataType: string,
655                                               componentInstanceId: string,
656                                               operation: InterfaceOperationModel): Observable<ComponentInstance> {
657         const operationList = {
658             interfaces: {
659                 [operation.interfaceType]: {
660                     type: operation.interfaceType,
661                     operations: {
662                         [operation.name]: new BEInterfaceOperationModel(operation)
663                     }
664                 }
665             }
666         };
667         return this.http.put<ComponentInstance>(this.baseUrl + this
668         .getServerTypeUrl(componentMetaDataType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/interfaceOperation', operationList);
669     }
670
671     getDefaultCustomFunction(type='ALL'): Observable<CustomToscaFunction[]> {
672         return this.http.get<DefaultCustomFunctions>(this.baseUrl + "customToscaFunctions/" + type)
673         .pipe(map(response => response && response.defaultCustomToscaFunction  ? response.defaultCustomToscaFunction : []));
674     }
675
676     createComponentInstanceInterfaceOperation(componentMetaDataId: string, componentInstanceId: string,
677         operation: InterfaceOperationModel): Observable<InterfaceOperationModel> {
678         const operationList = {
679             interfaces: {
680                 [operation.interfaceType]: {
681                     type: operation.interfaceType,
682                     operations: {
683                         [operation.name]: new BEInterfaceOperationModel(operation)
684                     }
685                 }
686             }
687         };
688         return this.http.post<any>(this.baseUrl + 'services/' + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/interfaceOperation', operationList)
689         .map((res: any) => {
690             const interf: InterfaceModel = _.find(res.interfaces, interf => interf.type === operation.interfaceType);
691             const newOperation: OperationModel = _.find(interf.operations, op => op.name === operation.name);
692
693             return new InterfaceOperationModel({
694                 ...newOperation,
695                 interfaceType: interf.type,
696                 interfaceId: interf.uniqueId,
697             });
698         });
699     }
700
701 }