re base code
[sdc.git] / catalog-ui / src / app / ng2 / pages / automated-upgrade / automated-upgrade.service.ts
1 import {SdcUiComponents} from "sdc-ui/lib/angular";
2 import {Injectable, Inject} from "@angular/core";
3 import {IModalConfig} from "sdc-ui/lib/angular/modals/models/modal-config";
4 import {AutomatedUpgradeComponent} from "./automated-upgrade.component";
5 import {Component} from "../../../models/components/component";
6 import {ComponentServiceNg2} from "../../services/component-services/component.service";
7 import {GeneralStatus, ComponentType} from "../../../utils/constants";
8 import {IDependenciesServerResponse} from "../../services/responses/dependencies-server-response";
9 import {AutomatedUpgradeStatusComponent} from "./automated-upgrade-status/automated-upgrade-status.component";
10 import {AutomatedUpgradeStatusResponse} from "../../services/responses/automated-upgrade-response";
11 import Dictionary = _.Dictionary;
12 import {TranslateService, ITranslateArgs} from "../../shared/translator/translate.service";
13 import {
14     ServiceContainerToUpgradeUiObject,
15     AllottedResourceInstanceUiObject, VspInstanceUiObject
16 } from "./automated-upgrade-models/ui-component-to-upgrade";
17
18 export interface IAutomatedUpgradeRequestObj {
19     serviceId:string;
20     resourceId?:string;
21 }
22
23 export enum Placement {
24     left = "left"
25 }
26
27 @Injectable()
28 export class AutomatedUpgradeService {
29
30     private vspComponent:Component;
31     private uiComponentsToUpgrade:Array<ServiceContainerToUpgradeUiObject>;
32     private componentType:string;
33
34     constructor(private modalService:SdcUiComponents.ModalService,
35                 private componentService:ComponentServiceNg2,
36                 private translateService:TranslateService) {
37     }
38
39
40     public convertToServerRequest = (selectedServices:Array<string>):Array<IAutomatedUpgradeRequestObj> => {
41
42         let automatedRequest:Array<IAutomatedUpgradeRequestObj> = [];
43         _.forEach(selectedServices, (serviceId:string) => {
44             let serviceToUpgrade:ServiceContainerToUpgradeUiObject = _.find(this.uiComponentsToUpgrade, (service:ServiceContainerToUpgradeUiObject) => {
45                 return serviceId === service.uniqueId;
46             });
47
48             if (serviceToUpgrade.vspInstances[0] instanceof AllottedResourceInstanceUiObject) { // If this is allotted resource instances, we need to take the origin vf id (all the instances have the save origin vspId
49                 automatedRequest.push({
50                     serviceId: serviceId,
51                     resourceId: (<AllottedResourceInstanceUiObject> serviceToUpgrade.vspInstances[0]).originVfId
52                 });
53             } else {
54                 automatedRequest.push({serviceId: serviceId});
55             }
56         });
57         return automatedRequest;
58     }
59
60     private getStatusText = (statusMap:Dictionary<AutomatedUpgradeStatusResponse>):string => {
61         let failedUpgraded = _.filter(_.flatMap(statusMap), (upgradeStatus:AutomatedUpgradeStatusResponse) => {
62             return upgradeStatus.status !== GeneralStatus.OK
63         });
64
65         if (failedUpgraded.length > 0) {
66             return this.getTextByComponentType("_UPGRADE_STATUS_FAIL");
67         }
68         return this.getTextByComponentType("_UPGRADE_STATUS_SUCCESS");
69     }
70
71     private disabledAllModalButtons = ():void => {
72         this.modalService.getCurrentInstance().innerModalContent.instance.disabled = true;
73         this.modalService.getCurrentInstance().buttons[0].show_spinner = true;
74         this.modalService.getCurrentInstance().buttons[1].disabled = true;
75     }
76
77     public changeUpgradeButtonState = (isDisabled:boolean):void => {
78         if (this.modalService.getCurrentInstance().buttons[0].disabled !== isDisabled) {
79             this.modalService.getCurrentInstance().buttons[0].disabled = isDisabled;
80         }
81     }
82
83     //TODO We will need to replace this function after sdc-ui modal new design, this is just a workaround
84     public automatedUpgrade = ():void => {
85
86         let selectedServices = this.modalService.getCurrentInstance().innerModalContent.instance.selectedComponentsToUpgrade;
87         this.disabledAllModalButtons();
88         this.componentService.automatedUpgrade(this.vspComponent.componentType, this.vspComponent.uniqueId, this.convertToServerRequest(selectedServices)).subscribe((automatedUpgradeStatus:any) => {
89
90             if (automatedUpgradeStatus.status === GeneralStatus.OK) {
91
92                 let statusMap:Dictionary<AutomatedUpgradeStatusResponse> = _.keyBy(automatedUpgradeStatus.componentToUpgradeStatus, 'name');
93                 // In the status modal we only showing the upgraded component that the user selected, not the entire list
94                 let upgradedComponent:Array<ServiceContainerToUpgradeUiObject> = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
95                     return selectedServices.indexOf(component.uniqueId) > -1;
96                 });
97
98                 _.forEach(upgradedComponent, (upgradedComponent:ServiceContainerToUpgradeUiObject) => { // If upgrade success we need to upgrade the version  all success
99                     if (statusMap[upgradedComponent.name].status === GeneralStatus.OK) {
100                         upgradedComponent.version = statusMap[upgradedComponent.name].version;
101                         _.forEach(upgradedComponent.vspInstances, (instance:VspInstanceUiObject) => {
102                             instance.vspVersion = this.vspComponent.version;
103                         });
104                     }
105                 });
106
107                 let statusModalTitle = this.getTextByComponentType("_UPGRADE_STATUS_TITLE");
108                 this.modalService.getCurrentInstance().setTitle(statusModalTitle);
109                 this.modalService.getCurrentInstance().getButtons().splice(0, 1); // Remove the upgrade button
110                 this.modalService.getCurrentInstance().buttons[0].disabled = false; // enable close again
111                 this.modalService.getCurrentInstance().innerModalContent.destroy();
112                 this.modalService.createInnnerComponent(AutomatedUpgradeStatusComponent, {
113                     upgradedComponentsList: upgradedComponent,
114                     upgradeStatusMap: statusMap,
115                     statusText: this.getStatusText(statusMap)
116                 });
117             }
118         });
119     }
120
121     public isAlreadyAdded = (uniqueId:string):ServiceContainerToUpgradeUiObject => {
122         let componentToUpgrade = _.find(this.uiComponentsToUpgrade, (componentToUpgrade:ServiceContainerToUpgradeUiObject) => {
123             return componentToUpgrade.uniqueId === uniqueId;
124         });
125         return componentToUpgrade;
126     }
127
128     public initVfUpgradeData = (serviceToUpgrade:IDependenciesServerResponse, vsp:IDependenciesServerResponse) => {
129
130         let existed = this.isAlreadyAdded(serviceToUpgrade.uniqueId);
131         if (existed) { // We will take the VF with the lower version existed - only one exist all the time in vf upgrade
132             if (vsp.version < existed.vspInstances[0].vspVersion) {
133                 existed.vspInstances = [];
134                 existed.addVfInstance(vsp, this.vspComponent.version);
135             }
136         } else {
137             let dependencyUiObj:ServiceContainerToUpgradeUiObject = new ServiceContainerToUpgradeUiObject(serviceToUpgrade);
138             dependencyUiObj.addVfInstance(vsp, this.vspComponent.version);
139             this.uiComponentsToUpgrade.push(dependencyUiObj);
140         }
141     }
142
143     // Service data will create instances of proxy or allotted resources
144     public initServiceUpgradeData = (serviceToUpgrade:IDependenciesServerResponse, vsp:IDependenciesServerResponse, instanceNames:Array<string>, allottedOriginVf?:IDependenciesServerResponse) => {
145
146         let existedService = this.isAlreadyAdded(serviceToUpgrade.uniqueId);
147         if (existedService) {
148             existedService.addMultipleInstances(vsp, this.vspComponent.version, instanceNames, allottedOriginVf);
149         }
150         else {
151             let dependencyUiObj:ServiceContainerToUpgradeUiObject = new ServiceContainerToUpgradeUiObject(serviceToUpgrade);
152             dependencyUiObj.addMultipleInstances(vsp, this.vspComponent.version, instanceNames, allottedOriginVf);
153             this.uiComponentsToUpgrade.push(dependencyUiObj);
154         }
155     }
156
157     /*
158      The server return response of 3 level nested object
159      First level - Vsp data by version
160      Each vsp have a decencies (the services contains the vsp - By default this is vf upgrade
161      If instancesNames exist - this can be proxy or allotted
162      If we have second layer of dependencies than this is allotted
163      Since we display the data the opposite way the BE return, this function will order the data in order to display it
164      */
165     public convertToComponentsToUpgradeUiObjArray = (dependenciesServerResponse:Array<IDependenciesServerResponse>):void => {
166
167         this.uiComponentsToUpgrade = [];
168
169         _.forEach(dependenciesServerResponse, (vsp:IDependenciesServerResponse) => { // 3 nested levels - 1 level for vf, 2 level proxy, 3 levels allotted
170             if (vsp.dependencies) {
171                 _.forEach(vsp.dependencies, (dependency:IDependenciesServerResponse) => {
172                     if (dependency.instanceNames) { // Init service upgrade data
173                         if (dependency.dependencies) {
174                             _.forEach(dependency.dependencies, (serviceContainer:IDependenciesServerResponse) => { // Initiate allotted_resource instances
175                                 this.initServiceUpgradeData(serviceContainer, vsp, dependency.instanceNames, dependency);
176                             });
177                         } else { //Init service_proxy instances
178                             this.initServiceUpgradeData(dependency, vsp, dependency.instanceNames);
179                         }
180                     } else { // Init vf upgrade data
181                         this.initVfUpgradeData(dependency, vsp);
182                     }
183                 })
184             }
185         });
186     }
187
188     public isAllComponentsUpgraded = ():boolean => {
189         let isAllComponentUpgrade = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
190             return !component.isAlreadyUpgrade;
191         });
192         return isAllComponentUpgrade.length === 0;
193     }
194
195     public isAllComponentsLocked = ():boolean => {
196         let unLockedComponents = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
197             return !component.isLock;
198         });
199         return unLockedComponents.length === 0;
200     }
201
202     public isUpgradeNeeded = ():boolean => {
203         let neededUpgradeList = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
204             return !component.isLock && !component.isAlreadyUpgrade;
205         });
206         return neededUpgradeList.length > 0;
207     }
208
209     private getTextByComponentType (textLabel: string, params?:ITranslateArgs) {
210         return this.translateService.translate(this.componentType + textLabel, params);
211     }
212     public getInformationTextToDisplay = ():string => {
213
214         let isAllComponentsUpgraded = this.isAllComponentsUpgraded();
215         let isAllComponentsLocked = this.isAllComponentsLocked();
216         let params = {vspName: this.vspComponent.name, vspVersion: this.vspComponent.version};
217
218         if (this.uiComponentsToUpgrade.length === 0) {
219             return this.getTextByComponentType("_NOTHING_TO_UPGRADE", params);
220         }
221
222         switch (true) {
223             
224             case this.isUpgradeNeeded():
225             {
226                 return this.getTextByComponentType("_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE", params);
227             }
228             case  !this.isUpgradeNeeded() && isAllComponentsLocked:
229             {
230                 return this.getTextByComponentType("_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED", params);
231             }
232             case !this.isUpgradeNeeded() && !isAllComponentsLocked && isAllComponentsUpgraded:
233             {
234                 return this.getTextByComponentType("_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED", params);
235             }
236             case !this.isUpgradeNeeded() && !isAllComponentsLocked && !isAllComponentsUpgraded:
237             {
238                 return this.getTextByComponentType("_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED", params);
239             }
240         }
241     }
242
243     public openAutomatedUpgradeModal = (componentsToUpgrade:Array<IDependenciesServerResponse>, component:Component, isAfterCertification?:boolean):void => {
244
245         this.vspComponent = component;
246         this.componentType = this.vspComponent.isResource() ? ComponentType.RESOURCE : ComponentType.SERVICE;
247
248         this.convertToComponentsToUpgradeUiObjArray(componentsToUpgrade);
249         let informationalText = this.getInformationTextToDisplay();
250         let modalTitle = this.getTextByComponentType("_UPGRADE_TITLE");
251         let certificationText = isAfterCertification ? this.getTextByComponentType("_CERTIFICATION_STATUS_TEXT", {resourceName: this.vspComponent.name}) : undefined;
252
253         let upgradeVspModalConfig:IModalConfig = {
254             title: modalTitle,
255             size: "md",
256             type: "custom",
257             testId: "upgradeVspModal",
258             buttons: [
259                 {
260                     text: this.vspComponent.isResource() ? "UPGRADE" : "UPDATE",
261                     spinner_position: Placement.left,
262                     size: 'sm',
263                     callback: this.automatedUpgrade,
264                     closeModal: false,
265                     disabled: !this.isUpgradeNeeded(),
266
267                 },
268                 {text: 'CLOSE', size: 'sm', closeModal: true, type: 'secondary'}
269             ]
270         };
271
272         this.modalService.openCustomModal(upgradeVspModalConfig, AutomatedUpgradeComponent, {
273             componentsToUpgrade: this.uiComponentsToUpgrade,
274             informationText: informationalText,
275             certificationStatusText: certificationText
276         });
277     }
278 }
279