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