[SDC] rebase 1710 code
[sdc.git] / catalog-ui / src / app / models / components / component.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 'use strict';
22
23 import {AsdcComment, ArtifactModel, ArtifactGroupModel, IFileDownload, PropertyModel, PropertiesGroup, AttributeModel, AttributesGroup, ComponentInstance,
24     InputModel, DisplayModule, Module, IValidate, RelationshipModel, IMainCategory, RequirementsGroup, CapabilitiesGroup, AdditionalInformationModel,
25     Resource, IAppMenu, Service} from "../../models";
26
27 import {IComponentService} from "../../services/components/component-service";
28 import {CommonUtils} from "../../utils/common-utils";
29 import {QueueUtils} from "../../utils/functions";
30 import {ArtifactGroupType} from "../../utils/constants";
31 import {ComponentMetadata} from "../component-metadata";
32
33 // import {}
34 export interface IComponent {
35
36     //---------------------------------------------- API CALLS ----------------------------------------------------//
37
38     //Component API
39     getComponent():ng.IPromise<Component>;
40     updateComponent():ng.IPromise<Component>;
41     createComponentOnServer():ng.IPromise<Component>;
42     changeLifecycleState(state:string, commentObj:AsdcComment):ng.IPromise<Component>;
43     validateName(newName:string):ng.IPromise<IValidate>;
44     updateRequirementsCapabilities():ng.IPromise<any>;
45
46     //Artifacts API
47     addOrUpdateArtifact(artifact:ArtifactModel):ng.IPromise<ArtifactModel>;
48     updateMultipleArtifacts(artifacts:Array<ArtifactModel>):ng.IPromise<any>;
49     deleteArtifact(artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel>;
50     downloadInstanceArtifact(artifactId:string):ng.IPromise<IFileDownload>;
51     downloadArtifact(artifactId:string):ng.IPromise<IFileDownload>;
52     getArtifactByGroupType(artifactGroupType:string):ng.IPromise<ArtifactGroupModel>;
53
54
55     //Property API
56     addOrUpdateProperty(property:PropertyModel):ng.IPromise<PropertyModel>;
57     deleteProperty(propertyId:string):ng.IPromise<PropertyModel>;
58     updateInstanceProperty(property:PropertyModel):ng.IPromise<PropertyModel>;
59
60     //Attribute API
61     deleteAttribute(attributeId:string):ng.IPromise<AttributeModel>;
62     addOrUpdateAttribute(attribute:AttributeModel):ng.IPromise<AttributeModel>;
63     updateInstanceAttribute(attribute:AttributeModel):ng.IPromise<AttributeModel>;
64
65
66
67
68     //Component Instance API
69     createComponentInstance(componentInstance:ComponentInstance):ng.IPromise<ComponentInstance>;
70     deleteComponentInstance(componentInstanceId:string):ng.IPromise<ComponentInstance>;
71     addOrUpdateInstanceArtifact(artifact:ArtifactModel):ng.IPromise<ArtifactModel>;
72     deleteInstanceArtifact(artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel>;
73     uploadInstanceEnvFile(artifact:ArtifactModel):ng.IPromise<ArtifactModel>;
74     changeComponentInstanceVersion(componentUid:string):ng.IPromise<Component>;
75     updateComponentInstance(componentInstance:ComponentInstance):ng.IPromise<ComponentInstance>;
76     updateMultipleComponentInstances(instances:Array<ComponentInstance>):ng.IPromise<Array<ComponentInstance>>;
77
78     //Inputs API
79     getComponentInstanceInputProperties(componentInstanceId:string, inputId:string):ng.IPromise<Array<PropertyModel>>
80     getComponentInstanceProperties(componentInstanceId:string):ng.IPromise<Array<PropertyModel>>
81     getComponentInputs(componentId:string):ng.IPromise<Array<InputModel>>;
82
83     createRelation(link:RelationshipModel):ng.IPromise<RelationshipModel>;
84     deleteRelation(link:RelationshipModel):ng.IPromise<RelationshipModel>;
85
86
87     //Modules
88     getModuleForDisplay(moduleId:string):ng.IPromise<DisplayModule>;
89     getModuleInstanceForDisplay(componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule>;
90     updateGroupMetadata(group:Module):ng.IPromise<Module>;
91     //---------------------------------------------- HELP FUNCTIONS ----------------------------------------------------//
92
93     getComponentSubType():string;
94     isAlreadyCertified():boolean;
95     isService():boolean;
96     isResource():boolean;
97     isComplex():boolean;
98     getAdditionalInformation():Array<AdditionalInformationModel>;
99     getAllVersionsAsSortedArray():Array<any>;
100     getStatus(sdcMenu:IAppMenu):string;
101 }
102
103
104 export abstract class Component implements IComponent {
105
106     //server data
107     public abstract:string;
108     public uniqueId:string;
109     public uuid:string;
110     public invariantUUID:string;
111     public name:string;
112     public version:string;
113     public creationDate:number;
114     public lastUpdateDate:number;
115     public description:string;
116     public lifecycleState:string;
117     public tags:Array<string>;
118     public icon:string;
119     public contactId:string;
120     public allVersions:any;
121     public creatorUserId:string;
122     public creatorFullName:string;
123     public lastUpdaterUserId:string;
124     public lastUpdaterFullName:string;
125     public componentType:string;
126     public deploymentArtifacts:ArtifactGroupModel;
127     public artifacts:ArtifactGroupModel;
128     public toscaArtifacts:ArtifactGroupModel;
129     public distributionStatus:string;
130     public categories:Array<IMainCategory>;
131     public componentInstancesProperties:PropertiesGroup;
132     public componentInstancesAttributes:AttributesGroup;
133     public componentInstancesRelations:Array<RelationshipModel>;
134     public componentInstances:Array<ComponentInstance>;
135     public inputs:Array<InputModel>;
136     public capabilities:CapabilitiesGroup;
137     public requirements:RequirementsGroup;
138     public additionalInformation:any;
139     public properties:Array<PropertyModel>;
140     public attributes:Array<AttributeModel>;
141     public highestVersion:boolean;
142     public vendorName:string;
143     public vendorRelease:string;
144     public derivedList:Array<any>;
145     public interfaces:any;
146     public normalizedName:string;
147     public systemName:string;
148     public projectCode:string;
149     public groups:Array<Module>;
150     //custom properties
151     public componentService:IComponentService;
152     public filterTerm:string;
153     public iconSprite:string;
154     public selectedInstance:ComponentInstance;
155     public mainCategory:string;
156     public subCategory:string;
157     public selectedCategory:string;
158     public showMenu:boolean;
159
160
161     constructor(componentService:IComponentService, protected $q:ng.IQService, component?:Component) {
162         if (component) {
163             this.abstract = component.abstract;
164             this.uniqueId = component.uniqueId;
165             this.uuid = component.uuid;
166             this.invariantUUID = component.invariantUUID;
167             this.additionalInformation = component.additionalInformation;
168             this.artifacts = new ArtifactGroupModel(component.artifacts);
169             this.toscaArtifacts = new ArtifactGroupModel(component.toscaArtifacts);
170             this.contactId = component.contactId;
171             this.categories = component.categories;
172             this.creatorUserId = component.creatorUserId;
173             this.creationDate = component.creationDate;
174             this.creatorFullName = component.creatorFullName;
175             this.description = component.description;
176             this.icon = component.icon;
177             this.lastUpdateDate = component.lastUpdateDate;
178             this.lastUpdaterUserId = component.lastUpdaterUserId;
179             this.lastUpdaterFullName = component.lastUpdaterFullName;
180             this.lifecycleState = component.lifecycleState;
181             this.componentInstancesRelations = CommonUtils.initComponentInstanceRelations(component.componentInstancesRelations);
182             this.componentInstancesProperties = new PropertiesGroup(component.componentInstancesProperties);
183             this.componentInstancesAttributes = new AttributesGroup(component.componentInstancesAttributes);
184             this.name = component.name;
185             this.version = component.version;
186             this.tags = [];
187             angular.copy(component.tags, this.tags);
188             this.capabilities = new CapabilitiesGroup(component.capabilities);
189             this.requirements = new RequirementsGroup(component.requirements);
190             this.allVersions = component.allVersions;
191             this.deploymentArtifacts = new ArtifactGroupModel(component.deploymentArtifacts);
192             this.componentType = component.componentType;
193             this.distributionStatus = component.distributionStatus;
194             this.highestVersion = component.highestVersion;
195             this.vendorName = component.vendorName;
196             this.vendorRelease = component.vendorRelease;
197             this.derivedList = component.derivedList;
198             this.interfaces = component.interfaces;
199             this.normalizedName = component.normalizedName;
200             this.systemName = component.systemName;
201             this.projectCode = component.projectCode;
202             this.inputs = component.inputs;
203             this.componentInstances = CommonUtils.initComponentInstances(component.componentInstances);
204             this.properties = CommonUtils.initProperties(component.properties, this.uniqueId);
205             this.attributes = CommonUtils.initAttributes(component.attributes, this.uniqueId);
206             this.selectedInstance = component.selectedInstance;
207             this.iconSprite = component.iconSprite;
208             this.showMenu = true;
209             this.groups = CommonUtils.initModules(component.groups);
210         }
211
212         //custom properties
213         this.componentService = componentService;
214     }
215
216     public setUniqueId = (uniqueId:string):void => {
217         this.uniqueId = uniqueId;
218     };
219
220     public setSelectedInstance = (componentInstance:ComponentInstance):void => {
221         this.selectedInstance = componentInstance;
222     };
223
224
225     //------------------------------------------ API Calls ----------------------------------------------------------------//
226     public changeLifecycleState = (state:string, commentObj:AsdcComment):ng.IPromise<Component> => {
227         let deferred = this.$q.defer();
228         let onSuccess = (componentMetadata:ComponentMetadata):void => {
229             this.setComponentMetadata(componentMetadata);
230             // this.version = componentMetadata.version;
231             this.lifecycleState = componentMetadata.lifecycleState;
232
233             deferred.resolve(this);
234         };
235         let onError = (error:any):void => {
236             deferred.reject(error);
237         };
238         this.componentService.changeLifecycleState(this, state, JSON.stringify(commentObj)).then(onSuccess, onError);
239         return deferred.promise;
240     };
241
242     public getComponent = ():ng.IPromise<Component> => {
243         return this.componentService.getComponent(this.uniqueId);
244     };
245
246     public createComponentOnServer = ():ng.IPromise<Component> => {
247         this.handleTags();
248         return this.componentService.createComponent(this);
249     };
250
251     public updateComponent = ():ng.IPromise<Component> => {
252         this.handleTags();
253         return this.componentService.updateComponent(this);
254     };
255
256     public validateName = (newName:string, subtype?:string):ng.IPromise<IValidate> => {
257         return this.componentService.validateName(newName, subtype);
258     };
259
260     public downloadArtifact = (artifactId:string):ng.IPromise<IFileDownload> => {
261         return this.componentService.downloadArtifact(this.uniqueId, artifactId);
262     };
263
264     public addOrUpdateArtifact = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
265         let deferred = this.$q.defer();
266         let onSuccess = (artifactObj:ArtifactModel):void => {
267             let newArtifact = new ArtifactModel(artifactObj);
268             let artifacts = this.getArtifactsByType(artifactObj.artifactGroupType);
269             artifacts[artifactObj.artifactLabel] = newArtifact;
270             deferred.resolve(newArtifact);
271         };
272         let onError = (error:any):void => {
273             deferred.reject(error);
274         };
275         this.componentService.addOrUpdateArtifact(this.uniqueId, artifact).then(onSuccess, onError);
276         return deferred.promise;
277     };
278
279     public updateMultipleArtifacts = (artifacts:Array<ArtifactModel>):ng.IPromise<any>=> {
280         let deferred = this.$q.defer();
281         let onSuccess = (response:any):void => {
282             deferred.resolve(response);
283         };
284         let onError = (error:any):void => {
285             deferred.reject(error);
286         };
287         let q = new QueueUtils(this.$q);
288
289         _.forEach(artifacts, (artifact)=> {
290             q.addBlockingUIAction(()=> this.addOrUpdateArtifact(artifact).then(onSuccess, onError));
291         });
292         return deferred.promise;
293     };
294
295
296     public deleteArtifact = (artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
297         let deferred = this.$q.defer();
298         let onSuccess = (artifactObj:ArtifactModel):void => {
299             let newArtifact = new ArtifactModel(artifactObj);
300             let artifacts = this.getArtifactsByType(artifactObj.artifactGroupType);
301             if (newArtifact.mandatory || newArtifact.serviceApi) {
302                 artifacts[newArtifact.artifactLabel] = newArtifact;
303             }
304             else {
305                 delete artifacts[artifactLabel];
306             }
307             deferred.resolve(newArtifact);
308         };
309         this.componentService.deleteArtifact(this.uniqueId, artifactId, artifactLabel).then(onSuccess);
310         return deferred.promise;
311     };
312
313     public getArtifactByGroupType = (artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
314
315         let deferred = this.$q.defer();
316         let onSuccess = (response:ArtifactGroupModel):void => {
317             deferred.resolve(response);
318         };
319         let onFailed = (error:any):void => {
320             deferred.reject(error);
321         };
322         this.componentService.getArtifactByGroupType(this.uniqueId, artifactGroupType).then(onSuccess, onFailed);
323         return deferred.promise;
324     };
325
326     public getComponentInstanceArtifactsByGroupType = (componentInstanceId:string, artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
327
328         let deferred = this.$q.defer();
329         let onSuccess = (response:ArtifactGroupModel):void => {
330             deferred.resolve(response);
331         };
332         let onFailed = (error:any):void => {
333             deferred.reject(error);
334         };
335         this.componentService.getComponentInstanceArtifactsByGroupType(this.uniqueId, componentInstanceId, artifactGroupType).then(onSuccess, onFailed);
336         return deferred.promise;
337     };
338
339     public addOrUpdateProperty = (property:PropertyModel):ng.IPromise<PropertyModel> => {
340         let deferred = this.$q.defer();
341
342         let onError = (error:any):void => {
343             deferred.reject(error);
344         };
345
346         if (!property.uniqueId) {
347             let onSuccess = (property:PropertyModel):void => {
348                 let newProperty = new PropertyModel(property);
349                 this.properties.push(newProperty);
350                 deferred.resolve(newProperty);
351             };
352             this.componentService.addProperty(this.uniqueId, property).then(onSuccess, onError);
353         }
354         else {
355             let onSuccess = (newProperty:PropertyModel):void => {
356                 // find exist instance property in parent component for update the new value ( find bu uniqueId )
357                 let existProperty:PropertyModel = <PropertyModel>_.find(this.properties, {uniqueId: newProperty.uniqueId});
358                 let propertyIndex = this.properties.indexOf(existProperty);
359                 newProperty.readonly = this.uniqueId != newProperty.parentUniqueId;
360                 this.properties[propertyIndex] = newProperty;
361                 deferred.resolve(newProperty);
362             };
363             this.componentService.updateProperty(this.uniqueId, property).then(onSuccess, onError);
364         }
365         return deferred.promise;
366     };
367
368     public addOrUpdateAttribute = (attribute:AttributeModel):ng.IPromise<AttributeModel> => {
369         let deferred = this.$q.defer();
370
371         let onError = (error:any):void => {
372             deferred.reject(error);
373         };
374
375         if (!attribute.uniqueId) {
376             let onSuccess = (attribute:AttributeModel):void => {
377                 let newAttribute = new AttributeModel(attribute);
378                 this.attributes.push(newAttribute);
379                 deferred.resolve(newAttribute);
380             };
381             this.componentService.addAttribute(this.uniqueId, attribute).then(onSuccess, onError);
382         }
383         else {
384             let onSuccess = (newAttribute:AttributeModel):void => {
385                 let existAttribute:AttributeModel = <AttributeModel>_.find(this.attributes, {uniqueId: newAttribute.uniqueId});
386                 let attributeIndex = this.attributes.indexOf(existAttribute);
387                 newAttribute.readonly = this.uniqueId != newAttribute.parentUniqueId;
388                 this.attributes[attributeIndex] = newAttribute;
389                 deferred.resolve(newAttribute);
390             };
391             this.componentService.updateAttribute(this.uniqueId, attribute).then(onSuccess, onError);
392         }
393         return deferred.promise;
394     };
395
396     public deleteProperty = (propertyId:string):ng.IPromise<PropertyModel> => {
397         let deferred = this.$q.defer();
398         let onSuccess = ():void => {
399             console.log("Property deleted");
400             delete _.remove(this.properties, {uniqueId: propertyId})[0];
401             deferred.resolve();
402         };
403         let onFailed = ():void => {
404             console.log("Failed to delete property");
405             deferred.reject();
406         };
407         this.componentService.deleteProperty(this.uniqueId, propertyId).then(onSuccess, onFailed);
408         return deferred.promise;
409     };
410
411     public deleteAttribute = (attributeId:string):ng.IPromise<AttributeModel> => {
412         let deferred = this.$q.defer();
413         let onSuccess = ():void => {
414             console.log("Attribute deleted");
415             delete _.remove(this.attributes, {uniqueId: attributeId})[0];
416         };
417         let onFailed = ():void => {
418             console.log("Failed to delete attribute");
419         };
420         this.componentService.deleteAttribute(this.uniqueId, attributeId).then(onSuccess, onFailed);
421         return deferred.promise;
422     };
423
424     public updateInstanceProperty = (property:PropertyModel):ng.IPromise<PropertyModel> => {
425         let deferred = this.$q.defer();
426         let onSuccess = (newProperty:PropertyModel):void => {
427             // find exist instance property in parent component for update the new value ( find bu uniqueId & path)
428             let existProperty:PropertyModel = <PropertyModel>_.find(this.componentInstancesProperties[newProperty.resourceInstanceUniqueId], {
429                 uniqueId: newProperty.uniqueId,
430                 path: newProperty.path
431             });
432             let index = this.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty);
433             this.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty;
434             deferred.resolve(newProperty);
435         };
436         let onFailed = (error:any):void => {
437             console.log('Failed to update property value');
438             deferred.reject(error);
439         };
440         this.componentService.updateInstanceProperty(this.uniqueId, property).then(onSuccess, onFailed);
441         return deferred.promise;
442     };
443
444     public updateInstanceAttribute = (attribute:AttributeModel):ng.IPromise<AttributeModel> => {
445         let deferred = this.$q.defer();
446         let onSuccess = (newAttribute:AttributeModel):void => {
447             let existAttribute:AttributeModel = <AttributeModel>_.find(this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId], {uniqueId: newAttribute.uniqueId});
448             let index = this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId].indexOf(existAttribute);
449             this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId][index] = newAttribute;
450             deferred.resolve(newAttribute);
451         };
452         let onFailed = (error:any):void => {
453             console.log('Failed to update attribute value');
454             deferred.reject(error);
455         };
456         this.componentService.updateInstanceAttribute(this.uniqueId, attribute).then(onSuccess, onFailed);
457         return deferred.promise;
458     };
459
460     public downloadInstanceArtifact = (artifactId:string):ng.IPromise<IFileDownload> => {
461         return this.componentService.downloadInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifactId);
462     };
463
464     public deleteInstanceArtifact = (artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
465         let deferred = this.$q.defer();
466         let onSuccess = (artifactObj:ArtifactModel):void => {
467             let newArtifact = new ArtifactModel(artifactObj);
468             let artifacts = this.selectedInstance.deploymentArtifacts;
469             if (newArtifact.mandatory || newArtifact.serviceApi) {//?????????
470                 artifacts[newArtifact.artifactLabel] = newArtifact;
471             }
472             else {
473                 delete artifacts[artifactLabel];
474             }
475             deferred.resolve(newArtifact);
476         };
477         this.componentService.deleteInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifactId, artifactLabel).then(onSuccess);
478         return deferred.promise;
479     };
480
481     public addOrUpdateInstanceArtifact = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
482         let deferred = this.$q.defer();
483         let onSuccess = (artifactObj:ArtifactModel):void => {
484             switch (artifactObj.artifactGroupType) {
485                 case ArtifactGroupType.DEPLOYMENT:
486                     this.selectedInstance.deploymentArtifacts[artifactObj.artifactLabel] = artifactObj;
487                     break;
488                 case ArtifactGroupType.INFORMATION:
489                     this.selectedInstance.artifacts[artifactObj.artifactLabel] = artifactObj;
490                     break;
491             }
492             deferred.resolve(artifactObj);
493         };
494         let onError = (error:any):void => {
495             deferred.reject(error);
496         };
497         if (artifact.uniqueId) {
498             this.componentService.updateInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifact).then(onSuccess, onError);
499         } else {
500             this.componentService.addInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifact).then(onSuccess, onError);
501         }
502         return deferred.promise;
503     };
504
505     public uploadInstanceEnvFile = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
506         let deferred = this.$q.defer();
507         let onSuccess = (artifactObj:ArtifactModel):void => {
508             this.selectedInstance.deploymentArtifacts[artifactObj.artifactLabel] = artifactObj;
509             deferred.resolve(artifactObj);
510         };
511         let onError = (error:any):void => {
512             deferred.reject(error);
513         };
514         this.componentService.uploadInstanceEnvFile(this.uniqueId, this.selectedInstance.uniqueId, artifact).then(onSuccess, onError);
515         return deferred.promise;
516     };
517
518     //this function will update the instance version than the function call getComponent to update the current component and return the new instance version
519     public changeComponentInstanceVersion = (componentUid:string):ng.IPromise<Component> => {
520         let deferred = this.$q.defer();
521         let onFailed = (error:any):void => {
522             deferred.reject(error);
523         };
524         let onSuccess = (componentInstance:ComponentInstance):void => {
525             let onSuccess = (component:Component):void => {
526                 component.setSelectedInstance(componentInstance);
527                 deferred.resolve(component);
528             };
529             this.getComponent().then(onSuccess, onFailed);
530         };
531         this.componentService.changeResourceInstanceVersion(this.uniqueId, this.selectedInstance.uniqueId, componentUid).then(onSuccess, onFailed);
532         return deferred.promise;
533     };
534
535     public createComponentInstance = (componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
536         let deferred = this.$q.defer();
537         let onSuccess = (instance:ComponentInstance):void => {
538             this.componentInstances.push(instance);
539             deferred.resolve(instance);
540         };
541         let onFailed = (error:any):void => {
542             deferred.reject(error);
543         };
544         this.componentService.createComponentInstance(this.uniqueId, componentInstance).then(onSuccess, onFailed);
545         return deferred.promise;
546     };
547
548     public updateComponentInstance = (componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
549         let deferred = this.$q.defer();
550         let onSuccess = (updatedInstance:ComponentInstance):void => {
551             let componentInstance:ComponentInstance = _.find(this.componentInstances, (instance:ComponentInstance) => {
552                 return instance.uniqueId === updatedInstance.uniqueId;
553             });
554
555             let index = this.componentInstances.indexOf(componentInstance);
556             this.componentInstances[index] = componentInstance;
557             deferred.resolve(updatedInstance);
558
559         };
560         let onFailed = (error:any):void => {
561             deferred.reject(error);
562         };
563         this.componentService.updateComponentInstance(this.uniqueId, componentInstance).then(onSuccess, onFailed);
564         return deferred.promise;
565     };
566
567     public updateMultipleComponentInstances = (instances:Array<ComponentInstance>):ng.IPromise<Array<ComponentInstance>> => {
568         let deferred = this.$q.defer();
569         let onSuccess = (updatedInstances:Array<ComponentInstance>):void => {
570             _.forEach(updatedInstances, (updatedComponentInstance) => {
571                 let componentInstance:ComponentInstance = _.find(this.componentInstances, (instance:ComponentInstance) => {
572                     return instance.uniqueId === updatedComponentInstance.uniqueId;
573                 });
574
575                 let index = this.componentInstances.indexOf(componentInstance);
576                 this.componentInstances[index] = componentInstance;
577
578             });
579             deferred.resolve(updatedInstances);
580
581         };
582         let onFailed = (error:any):void => {
583             deferred.reject(error);
584         };
585         this.componentService.updateMultipleComponentInstances(this.uniqueId, instances).then(onSuccess, onFailed);
586         return deferred.promise;
587     };
588
589     public deleteComponentInstance = (componentInstanceId:string):ng.IPromise<ComponentInstance> => {
590         let deferred = this.$q.defer();
591         let onSuccess = ():void => {
592             let onSuccess = (component:Component):void => {
593                 this.componentInstances = CommonUtils.initComponentInstances(component.componentInstances);
594                 this.componentInstancesProperties = new PropertiesGroup(component.componentInstancesProperties);
595                 this.componentInstancesAttributes = new AttributesGroup(component.componentInstancesAttributes);
596                 this.groups = component.groups;
597                 this.componentInstancesRelations = CommonUtils.initComponentInstanceRelations(component.componentInstancesRelations);
598                 deferred.resolve();
599             };
600             this.getComponent().then(onSuccess);
601         };
602         let onFailed = (error:any):void => {
603             deferred.reject(error);
604         };
605         this.componentService.deleteComponentInstance(this.uniqueId, componentInstanceId).then(onSuccess, onFailed);
606         return deferred.promise;
607     };
608
609
610     public createRelation = (relation:RelationshipModel):ng.IPromise<RelationshipModel> => {
611         let deferred = this.$q.defer();
612         let onSuccess = (relation:RelationshipModel):void => {
613             console.info('Link created successfully', relation);
614             if (!this.componentInstancesRelations) {
615                 this.componentInstancesRelations = [];
616             }
617             this.componentInstancesRelations.push(new RelationshipModel(relation));
618             deferred.resolve(relation);
619         };
620         let onFailed = (error:any):void => {
621             console.info('Failed to create relation', error);
622             deferred.reject(error);
623         };
624         this.componentService.createRelation(this.uniqueId, relation).then(onSuccess, onFailed);
625         return deferred.promise;
626     };
627
628     public deleteRelation = (relation:RelationshipModel):ng.IPromise<RelationshipModel> => {
629         let deferred = this.$q.defer();
630         let onSuccess = (responseRelation:RelationshipModel):void => {
631             console.log("Link Deleted In Server");
632             let relationToDelete = _.find(this.componentInstancesRelations, (item) => {
633                 return item.fromNode === relation.fromNode && item.toNode === relation.toNode && _.some(item.relationships, (relationship)=> {
634                         return angular.equals(relation.relationships[0], relationship);
635                     });
636             });
637             let index = this.componentInstancesRelations.indexOf(relationToDelete);
638             if (relationToDelete != undefined && index > -1) {
639                 if (relationToDelete.relationships.length == 1) {
640                     this.componentInstancesRelations.splice(index, 1);
641                 } else {
642                     this.componentInstancesRelations[index].relationships =
643                         _.reject(this.componentInstancesRelations[index].relationships, relation.relationships[0]);
644                 }
645             } else {
646                 console.error("Error while deleting relation - the return delete relation from server was not found in UI")
647             }
648             deferred.resolve(relation);
649         };
650         let onFailed = (error:any):void => {
651             console.error("Failed To Delete Link");
652             deferred.reject(error);
653         };
654         this.componentService.deleteRelation(this.uniqueId, relation).then(onSuccess, onFailed);
655         return deferred.promise;
656     };
657
658     public updateRequirementsCapabilities = ():ng.IPromise<any> => {
659         let deferred = this.$q.defer();
660         let onSuccess = (response:any):void => {
661             this.capabilities = response.capabilities;
662             this.requirements = response.requirements;
663             deferred.resolve(response);
664         };
665         let onFailed = (error:any):void => {
666             deferred.reject(error);
667         };
668         this.componentService.getRequirementsCapabilities(this.uniqueId).then(onSuccess, onFailed);
669         return deferred.promise;
670     };
671
672     public getModuleForDisplay = (moduleId:string):ng.IPromise<DisplayModule> => {
673
674         let deferred = this.$q.defer();
675         let onSuccess = (response:DisplayModule):void => {
676             deferred.resolve(response);
677         };
678         let onFailed = (error:any):void => {
679             deferred.reject(error);
680         };
681         this.componentService.getModuleForDisplay(this.uniqueId, moduleId).then(onSuccess, onFailed);
682         return deferred.promise;
683     };
684
685     public getModuleInstanceForDisplay = (componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule> => {
686
687         let deferred = this.$q.defer();
688         let onSuccess = (response:DisplayModule):void => {
689             deferred.resolve(response);
690         };
691         let onFailed = (error:any):void => {
692             deferred.reject(error);
693         };
694         this.componentService.getComponentInstanceModule(this.uniqueId, componentInstanceId, moduleId).then(onSuccess, onFailed);
695         return deferred.promise;
696     };
697
698
699     // this function get all instances filtered by inputs and properties (optional) - if no search string insert - this function will
700     // get all the instances of the component (in service only VF instances)
701     public getComponentInstancesFilteredByInputsAndProperties = (searchText?:string):ng.IPromise<Array<ComponentInstance>> => {
702
703         let deferred = this.$q.defer();
704         let onSuccess = (response:Array<ComponentInstance>):void => {
705             deferred.resolve(response);
706         };
707         let onFailed = (error:any):void => {
708             deferred.reject(error);
709         };
710         this.componentService.getComponentInstancesFilteredByInputsAndProperties(this.uniqueId, searchText).then(onSuccess, onFailed);
711         return deferred.promise;
712     };
713
714
715     // get inputs for instance - Pagination function
716     public getComponentInputs = ():ng.IPromise<Array<InputModel>> => {
717
718         let deferred = this.$q.defer();
719         let onSuccess = (inputsRes:Array<InputModel>):void => {
720             this.inputs = inputsRes;
721             deferred.resolve(inputsRes);
722         };
723         let onFailed = (error:any):void => {
724             deferred.reject(error);
725         };
726         this.componentService.getComponentInputs(this.uniqueId).then(onSuccess, onFailed);
727         return deferred.promise;
728     };
729
730
731     // get inputs instance - Pagination function
732     public getComponentInstanceInputs = (componentInstanceId:string, originComponentUid:string):ng.IPromise<Array<InputModel>> => {
733
734         let deferred = this.$q.defer();
735         let onSuccess = (response:Array<InputModel>):void => {
736             deferred.resolve(response);
737         };
738         let onFailed = (error:any):void => {
739             deferred.reject(error);
740         };
741         this.componentService.getComponentInstanceInputs(this.uniqueId, componentInstanceId, originComponentUid).then(onSuccess, onFailed);
742         return deferred.promise;
743     };
744
745     // get inputs inatnce - Pagination function
746     public getComponentInstanceInputProperties = (componentInstanceId:string, inputId:string):ng.IPromise<Array<PropertyModel>> => {
747
748         let deferred = this.$q.defer();
749         let onSuccess = (response:Array<PropertyModel>):void => {
750             deferred.resolve(response);
751         };
752         let onFailed = (error:any):void => {
753             deferred.reject(error);
754         };
755         this.componentService.getComponentInstanceInputProperties(this.uniqueId, componentInstanceId, inputId).then(onSuccess, onFailed);
756         return deferred.promise;
757     };
758
759     // get inputs inatnce - Pagination function
760     public getComponentInstanceProperties = (componentInstanceId:string):ng.IPromise<Array<PropertyModel>> => {
761
762         let deferred = this.$q.defer();
763         let onSuccess = (response:Array<PropertyModel>):void => {
764             deferred.resolve(response);
765         };
766         let onFailed = (error:any):void => {
767             deferred.reject(error);
768         };
769         this.componentService.getComponentInstanceProperties(this.uniqueId, componentInstanceId).then(onSuccess, onFailed);
770         return deferred.promise;
771     };
772
773
774     public updateGroupMetadata = (module:Module):ng.IPromise<Module> => {
775
776         let deferred = this.$q.defer();
777
778         let onSuccess = (updatedModule:Module):void => {
779             let groupIndex:number = _.indexOf(this.groups, _.find(this.groups, (module:Module) => {
780                 return module.uniqueId === updatedModule.uniqueId;
781             }));
782
783             if (groupIndex !== -1) {
784                 this.groups[groupIndex] = updatedModule;
785             }
786             deferred.resolve(updatedModule);
787         };
788         let onFailed = (error:any):void => {
789             deferred.reject(error);
790         };
791
792         this.componentService.updateGroupMetadata(this.uniqueId, module).then(onSuccess, onFailed);
793
794         return deferred.promise;
795     };
796
797     //------------------------------------------ Help Functions ----------------------------------------------------------------//
798
799     public isService = ():boolean => {
800         return this instanceof Service;
801     };
802
803     public isResource = ():boolean => {
804         return this instanceof Resource;
805     };
806
807     public getComponentSubType = ():string => {
808         return this.componentType;
809     };
810
811     public isAlreadyCertified = ():boolean => {
812         return parseInt(this.version) >= 1;
813     };
814
815     public isComplex = ():boolean => {
816         return true;
817     };
818
819     //sort string version value from hash to sorted version (i.e 1.9 before 1.11)
820     private sortVersions = (v1:string, v2:string):number => {
821         let ver1 = v1.split('.');
822         let ver2 = v2.split('.');
823         let diff = parseInt(_.first(ver1)) - parseInt(_.first(ver2));
824         if (!diff) {
825             return parseInt(_.last(ver1)) - parseInt(_.last(ver2));
826         }
827         return diff;
828     };
829
830     public getAllVersionsAsSortedArray = ():Array<any> => {
831         let res = [];
832         if (this.allVersions) {
833             let keys = Object.keys(this.allVersions).sort(this.sortVersions);
834             _.forEach(keys, (key)=> {
835                 res.push({
836                     versionNumber: key,
837                     versionId: this.allVersions[key]
838                 })
839             });
840         }
841         return res;
842     };
843
844     public isLatestVersion = ():boolean => {
845         if (this.allVersions) {
846             return this.version === _.last(Object.keys(this.allVersions).sort(this.sortVersions));
847         } else {
848             return true;
849         }
850
851     };
852
853     public getAdditionalInformation = ():Array<AdditionalInformationModel> => {
854         let additionalInformationObject:any = _.find(this.additionalInformation, (obj:any):boolean => {
855             return obj.parentUniqueId == this.uniqueId;
856         });
857         if (additionalInformationObject) {
858             return additionalInformationObject.parameters;
859         }
860         return [];
861     };
862
863     public handleTags = ():void => {
864         let isContainTag = _.find(this.tags, (tag)=> {
865             return tag === this.name;
866         });
867         if (!isContainTag) {
868             this.tags.push(this.name);
869         }
870     };
871
872     public getArtifactsByType = (artifactGroupType:string):ArtifactGroupModel => {
873         switch (artifactGroupType) {
874             case ArtifactGroupType.DEPLOYMENT:
875                 return this.deploymentArtifacts;
876             case ArtifactGroupType.INFORMATION:
877                 return this.artifacts;
878         }
879     };
880
881     public getStatus = (sdcMenu:IAppMenu):string => {
882         let status:string = sdcMenu.LifeCycleStatuses[this.lifecycleState].text;
883         if (this.lifecycleState == "CERTIFIED" && sdcMenu.DistributionStatuses[this.distributionStatus]) {
884             status = sdcMenu.DistributionStatuses[this.distributionStatus].text;
885         }
886         return status;
887     };
888
889     public abstract setComponentDisplayData():void;
890     public abstract getTypeUrl():string;
891
892     public setComponentMetadata(componentMetadata: ComponentMetadata) {
893         this.abstract = componentMetadata.abstract;
894         this.uniqueId = componentMetadata.uniqueId;
895         this.uuid = componentMetadata.uuid;
896         this.invariantUUID = componentMetadata.invariantUUID;
897         this.contactId = componentMetadata.contactId;
898         this.categories = componentMetadata.categories;
899         this.creatorUserId = componentMetadata.creatorUserId;
900         this.creationDate = componentMetadata.creationDate;
901         this.creatorFullName = componentMetadata.creatorFullName;
902         this.description = componentMetadata.description;
903         this.icon = componentMetadata.icon;
904         this.lastUpdateDate = componentMetadata.lastUpdateDate;
905         this.lastUpdaterUserId = componentMetadata.lastUpdaterUserId;
906         this.lastUpdaterFullName = componentMetadata.lastUpdaterFullName;
907         this.lifecycleState = componentMetadata.lifecycleState;
908         this.name = componentMetadata.name;
909         this.version = componentMetadata.version;
910         this.tags = angular.copy(componentMetadata.tags, this.tags);
911         this.allVersions = componentMetadata.allVersions;
912         this.componentType = componentMetadata.componentType;
913         this.distributionStatus = componentMetadata.distributionStatus;
914         this.highestVersion = componentMetadata.highestVersion;
915         this.vendorName = componentMetadata.vendorName;
916         this.vendorRelease = componentMetadata.vendorRelease;
917         this.derivedList = componentMetadata.derivedList;
918         this.normalizedName = componentMetadata.normalizedName;
919         this.systemName = componentMetadata.systemName;
920         this.projectCode = componentMetadata.projectCode;
921         this.categories = componentMetadata.categories;
922
923     }
924
925     public toJSON = ():any => {
926         this.componentService = undefined;
927         this.filterTerm = undefined;
928         this.iconSprite = undefined;
929         this.mainCategory = undefined;
930         this.subCategory = undefined;
931         this.selectedInstance = undefined;
932         this.showMenu = undefined;
933         this.$q = undefined;
934         this.selectedCategory = undefined;
935         return this;
936     };
937 }
938