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