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