blob: 47fc2ad80dc26390f9a2dad4506c982da8cb666e [file] [log] [blame]
Isabel Lloret523d6752025-04-29 08:06:54 +00001/*
2 Copyright 2020 TATA ELXSI
3
4 Licensed under the Apache License, Version 2.0 (the 'License');
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 Author: I.Lloret <illoret@minsait.com>
17*/
18/**
19 * @file ShowVduConsoleComponent Component
20 */
21import { HttpHeaders } from '@angular/common/http';
22import { Component, Injector, Input, OnInit } from '@angular/core';
23import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
24import { Router } from '@angular/router';
25import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
26import { TranslateService } from '@ngx-translate/core';
27import { NotifierService } from 'angular-notifier';
28import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
29import { environment } from 'environment';
30import { ShowVduConsole, OperateVnfResult } from 'NSInstanceModel';
31import { RestService } from 'RestService';
32import { SharedService, isNullOrUndefined } from 'SharedService';
33import { DF, VNFD } from 'VNFDModel';
34import { InstanceData, VDUR, VNFInstanceDetails } from 'VNFInstanceModel';
35
36/**
37 * Creating component
38 * @Component takes ShowVduConsoleComponent.html as template url
39 */
40@Component({
41 selector: 'app-show-vdu-console',
42 templateUrl: './ShowVduConsoleComponent.html',
43 styleUrls: ['./ShowVduConsoleComponent.scss']
44})
45export class ShowVduConsoleComponent implements OnInit {
46 /** To inject services @public */
47 public injector: Injector;
48 /** Instance for active modal service @public */
49 public activeModal: NgbActiveModal;
50 /** Check the loading results @public */
51 public isLoadingResults: Boolean = false;
52 /** Give the message for the loading @public */
53 public message: string = 'PLEASEWAIT';
54 /** FormGroup instance added to the form @ html @public */
55 public consoleForm: FormGroup;
56 /** Items for the memberVNFIndex @public */
57 public memberTypes: {}[];
58 /** Contains MemberVNFIndex values @public */
59 public memberVnfIndex: {}[] = [];
60 /** Contains vnfInstanceId of the selected MemberVnfIndex @public */
61 public instanceId: string;
62 /** Items for vduId & countIndex @public */
63 public vdu: {}[];
64 /** Selected VNFInstanceId @public */
65 public selectedvnfId: string = '';
66 /** Check day1-2 operation @public */
67 /** TODO - show remove this probably */
68 public 'day1-2': boolean;
69 /** Array holds VNFR Data filtered with nsr ID @public */
70 public nsIdFilteredData: {}[] = [];
71 /** Form valid on submit trigger @public */
72 public submitted: boolean = false;
73 /** Contains vduId @public */
74 public vduId: {};
75 /** Items for countIndex @public */
76 public countIndex: {}[];
77 /** Input contains component objects @private */
78 @Input() private params: URLPARAMS;
79 /** FormBuilder instance added to the formBuilder @private */
80 private formBuilder: FormBuilder;
81 /** Instance of the rest service @private */
82 private restService: RestService;
83 /** Notifier service to popup notification @private */
84 private notifierService: NotifierService;
85 /** Contains tranlsate instance @private */
86 private translateService: TranslateService;
87 /** Controls the header form @private */
88 private headers: HttpHeaders;
89 private consoleRequestStartTime: number;
90 /** Contains all methods related to shared @private */
91 private sharedService: SharedService;
92 /** Holds the instance of AuthService class of type AuthService @private */
93 private router: Router;
94 constructor(injector: Injector) {
95 this.injector = injector;
96 this.restService = this.injector.get(RestService);
97 this.notifierService = this.injector.get(NotifierService);
98 this.translateService = this.injector.get(TranslateService);
99 this.activeModal = this.injector.get(NgbActiveModal);
100 this.formBuilder = this.injector.get(FormBuilder);
101 this.sharedService = this.injector.get(SharedService);
102 this.router = this.injector.get(Router);
103 }
104 /** convenience getter for easy access to form fields */
105 get f(): FormGroup['controls'] { return this.consoleForm.controls; }
106 /**
107 * Lifecyle Hooks the trigger before component is instantiate
108 */
109 public ngOnInit(): void {
110 this.initializeForm();
111 this.getMemberVnfIndex();
112 this.headers = new HttpHeaders({
113 'Content-Type': 'application/json',
114 Accept: 'application/json',
115 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
116 });
117 }
118 /** Initialize start, stop or rebuild Forms @public */
119 public initializeForm(): void {
120 this.consoleForm = this.formBuilder.group({
121 memberVnfIndex: [null, [Validators.required]],
122 vduId: [null, [Validators.required]],
123 countIndex: [null, [Validators.required]]
124 });
125 }
126
127 /** Getting MemberVnfIndex using VNFInstances API @public */
128 public getMemberVnfIndex(): void {
129 this.isLoadingResults = true;
130 const vnfInstanceData: {}[] = [];
131 this.restService.getResource(environment.VNFINSTANCES_URL).subscribe((vnfInstancesData: VNFInstanceDetails[]): void => {
132 vnfInstancesData.forEach((vnfData: VNFInstanceDetails): void => {
133 const vnfdRef: string = 'vnfd-ref';
134 const memberIndex: string = 'member-vnf-index-ref';
135 const nsrId: string = 'nsr-id-ref';
136 const vnfId: string = 'vnfd-id';
137 const vnfDataObj: {} =
138 {
139 // eslint-disable-next-line security/detect-object-injection
140 VNFD: vnfData[vnfdRef],
141 VNFInstanceId: vnfData._id,
142 // eslint-disable-next-line security/detect-object-injection
143 MemberIndex: vnfData[memberIndex],
144 // eslint-disable-next-line security/detect-object-injection
145 NS: vnfData[nsrId],
146 // eslint-disable-next-line security/detect-object-injection
147 VNFID: vnfData[vnfId]
148 };
149 vnfInstanceData.push(vnfDataObj);
150 });
151 const nsId: string = 'NS';
152 // eslint-disable-next-line security/detect-object-injection
153 this.nsIdFilteredData = vnfInstanceData.filter((vnfdData: {}[]): boolean => vnfdData[nsId] === this.params.id);
154 this.nsIdFilteredData.forEach((resVNF: InstanceData): void => {
155 const assignMemberIndex: {} = {
156 id: resVNF.MemberIndex,
157 vnfinstanceId: resVNF.VNFInstanceId
158 };
159 this.memberVnfIndex.push(assignMemberIndex);
160 });
161 this.memberTypes = this.memberVnfIndex;
162 this.isLoadingResults = false;
163 }, (error: ERRORDATA): void => {
164 this.restService.handleError(error, 'get');
165 this.isLoadingResults = false;
166 });
167 }
168
169 /** Getting vdu-id & count-index from VNFInstance API */
170 public getVdu(id: string): void {
171 const vnfInstanceData: {}[] = [];
172 this.getFormControl('vduId').setValue(null);
173 this.getFormControl('countIndex').setValue(null);
174 if (!isNullOrUndefined(id)) {
175 this.restService.getResource(environment.VNFINSTANCES_URL + '/' + id).
176 subscribe((vnfInstanceDetail: VNFInstanceDetails[]): void => {
177 this.instanceId = id;
178 this.selectedvnfId = vnfInstanceDetail['vnfd-ref'];
179 const VDU: string = 'vdur';
180 // eslint-disable-next-line security/detect-object-injection
181 if (vnfInstanceDetail[VDU] !== undefined) {
182 // eslint-disable-next-line security/detect-object-injection
183 vnfInstanceDetail[VDU].forEach((vdu: VDUR): void => {
184 const vnfInstanceDataObj: {} =
185 {
186 'count-index': vdu['count-index'],
187 VDU: vdu['vdu-id-ref']
188 };
189 vnfInstanceData.push(vnfInstanceDataObj);
190 });
191 this.vdu = vnfInstanceData;
192 const vduName: string = 'VDU';
193 this.vduId = this.vdu.filter((vdu: {}, index: number, self: {}[]): {} =>
194 index === self.findIndex((t: {}): {} => (
195 // eslint-disable-next-line security/detect-object-injection
196 t[vduName] === vdu[vduName]
197 ))
198 );
199 }
200 this.checkDay12Operation(this.selectedvnfId);
201 }, (error: ERRORDATA): void => {
202 this.restService.handleError(error, 'get');
203 this.isLoadingResults = false;
204 });
205 }
206 }
207
208 /** Getting count-index by filtering id */
209 public getCountIndex(id: string): void {
210 const VDU: string = 'VDU';
211 // eslint-disable-next-line security/detect-object-injection
212 this.countIndex = this.vdu.filter((vnfdData: {}[]): boolean => vnfdData[VDU] === id);
213 }
214
215 /** To check primitve actions from VNFR */
216 public checkDay12Operation(id: string): void {
217 const apiUrl: string = environment.VNFPACKAGES_URL + '?id=' + id;
218 this.restService.getResource(apiUrl).subscribe((vnfdInfo: VNFD[]): void => {
219 const vnfInstances: VNFD = vnfdInfo[0];
220 if (!isNullOrUndefined(vnfInstances.df)) {
221 vnfInstances.df.forEach((df: DF): void => {
222 if (df['lcm-operations-configuration'] !== undefined) {
223 if (df['lcm-operations-configuration']['operate-vnf-op-config']['day1-2'] !== undefined) {
224 this['day1-2'] = true;
225 }
226 } else {
227 this['day1-2'] = false;
228 }
229 });
230 }
231 }, (error: ERRORDATA): void => {
232 this.isLoadingResults = false;
233 this.restService.handleError(error, 'get');
234 });
235 }
236
237 /** Check and sends a request to get console */
238 public prepareGetConsole(): void {
239 this.submitted = true;
240 this.sharedService.cleanForm(this.consoleForm);
241 if (this.consoleForm.invalid) { return; } // Proceed, onces form is valid
242 const prepareConsolePayload: ShowVduConsole = {
243 updateType: 'OPERATE_VNF',
244 operateVnfData: {
245 vnfInstanceId: this.instanceId,
246 changeStateTo: 'console',
247 additionalParam: {
248 'run-day1': false,
249 vdu_id: this.consoleForm.value.vduId,
250 'count-index': this.consoleForm.value.countIndex
251 }
252 }
253 };
254 this.startGetConsole(prepareConsolePayload);
255 }
256
257 /** Initialize get console operation @public */
258 public startGetConsole(prepareConsolePayload: object): void {
259 this.message = 'LAUNCHINGCONSOLE';
260 this.consoleRequestStartTime = Date.now();
261 this.isLoadingResults = true;
262 const apiURLHeader: APIURLHEADER = {
263 url: environment.NSDINSTANCES_URL + '/' + this.params.id + '/update',
264 httpOptions: { headers: this.headers }
265 };
266 const modalData: MODALCLOSERESPONSEDATA = {
267 message: 'Done'
268 };
269 this.restService.postResource(apiURLHeader, prepareConsolePayload).subscribe((result: OperateVnfResult): void => {
270 // Start waiting for the operation to complete
271 this.waitOperationCompleted(result.id);
272 }, (error: ERRORDATA): void => {
273 this.restService.handleError(error, 'post');
274 this.isLoadingResults = false;
275 });
276 }
277
278 private waitOperationCompleted(operationId: string): void {
279 let elapsedTime = 0;
280 const interval = 3000; // 3 seconds interval between status checks
281 const maxWaitTime = 2 * 60 * 1000; // 2 minutes in milliseconds
282
283 // Set interval to periodically check if the operation is completed
284 const checkInterval = setInterval(() => {
285 if (elapsedTime >= maxWaitTime) {
286 clearInterval(checkInterval); // Stop polling after 2 minutes
287 this.notifierService.notify('error', this.translateService.instant('OPERATIONFAILED'));
288 this.isLoadingResults = false;
289 return;
290 }
291
292 this.getOperationStatus(operationId).subscribe((operationData: any) => {
293 if (operationData && operationData.operationState === 'COMPLETED') {
294 clearInterval(checkInterval); // Stop polling when operation is completed
295 elapsedTime = (Date.now() - this.consoleRequestStartTime);
296 this.openVmrcConsole(operationData.operationResultData.url);
297 // Close the modal window now
298 const modalData: MODALCLOSERESPONSEDATA = {
299 message: 'Done'
300 };
301 this.activeModal.close(modalData);
302 this.router.navigate(['/instances/ns/']).catch((): void => {
303 // Catch Navigation Error
304 });
305 } else if (operationData && operationData.operationState === 'FAILED') {
306 clearInterval(checkInterval); // Stop polling on error
307 this.notifierService.notify('error', this.translateService.instant('OPERATIONFAILED'));
308 this.isLoadingResults = false;
309 }
310 }, (error: ERRORDATA) => {
311 clearInterval(checkInterval); // Stop polling on error
312 this.restService.handleError(error, 'post');
313 this.isLoadingResults = false;
314 });
315 elapsedTime += interval;
316 }, interval);
317 }
318
319 /** obtain the status of the getconsole operation */
320 private getOperationStatus(operationId: string) {
321 const operationQueryUrl: string = environment.NSHISTORYOPERATIONS_URL + '/' + operationId;
322 // Make GET request to check operation status
323 return this.restService.getResource(operationQueryUrl);
324 }
325
326 private openVmrcConsole(vmrcUrl) {
327 const link = document.createElement('a');
328 link.href = vmrcUrl;
329 link.style.display = 'none';
330 document.body.appendChild(link);
331 link.click();
332 document.body.removeChild(link);
333 }
334
335 /** Used to get the AbstractControl of controlName passed @private */
336 private getFormControl(controlName: string): AbstractControl {
337 // eslint-disable-next-line security/detect-object-injection
338 return this.consoleForm.controls[controlName];
339 }
340}