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