Catalog alignment
[sdc.git] / catalog-ui / src / app / ng2 / pages / workspace / disribution / distribution.service.ts
1 import { HttpClient } from '@angular/common/http';
2 import { Inject, Injectable } from '@angular/core';
3 import { tap } from 'rxjs/operators';
4 import { Distribution } from '../../../../models/distribution';
5 import { ISdcConfig, SdcConfigToken } from '../../../config/sdc-config.config';
6
7 @Injectable()
8 export class DistributionService {
9     protected baseUrl;
10     private distributionList = [];
11     private distributionStatusesMap = {};
12
13     // tslint:disable:no-string-literal
14
15     constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) {
16         this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root;
17     }
18
19     // Once the distribution page is loaded or when the user wants to refresh the list
20      async initDistributionsList(componentUuid: string): Promise<object> {
21         const distributionsListURL = this.baseUrl + 'services/' + componentUuid + '/distribution';
22         const res = this.http.get<Distribution[]>(distributionsListURL).pipe(tap( (result) => {
23             this.distributionList = result['distributionStatusOfServiceList'];
24             this.insertDistrbutionsToMap();
25         }  ));
26         return res.toPromise();
27     }
28
29     // Once the user click on the relevant distribution ID in the distribution table (open and close)
30     async initDistributionsStatusForDistributionID(distributionID: string): Promise<object> {
31         const distributionStatus = this.baseUrl + 'services/distribution/' + distributionID;
32         const res = this.http.get<object>(distributionStatus).pipe(tap( (result) => {
33             this.insertDistributionStatusToDistributionsMap(distributionID, result['distributionStatusList']);
34         }  ));
35         return res.toPromise();
36     }
37
38     public getDistributionList(specificDistributionID?: string) {
39         if (specificDistributionID) {
40             return this.distributionList.filter((distribution) => {
41                 return distribution['distributionID'] === specificDistributionID;
42             });
43         } else {
44             return this.distributionList;
45         }
46     }
47
48     public getComponentsByDistributionID(distributionID: string) {
49         const components = [];
50         const distributionStatusMap = this.getStatusMapForDistributionID(distributionID);
51         if (distributionStatusMap) {
52             distributionStatusMap.forEach((component) => components.push(component.componentID));
53         }
54         return components;
55     }
56
57     // get array of artifacts per distributionID w/o componentName, sliced by artifact status
58     public getArtifactsForDistributionIDAndComponentByStatus(distributionID: string, statusToSearch: string, componentName?: string) {
59         const filteredArtifactsByStatus = [];
60
61         if (componentName) {
62             this.getArtifactstByDistributionIDAndComponentsName(distributionID, componentName).forEach ( (artifact) => {
63                 if (this.artifactStatusHasMatch(artifact, statusToSearch)) {
64                     filteredArtifactsByStatus.push(artifact);
65                 }
66             } );
67         } else {
68             this.getArtifactstByDistributionIDAndComponentsName(distributionID).forEach ( (artifact) => {
69                 if (this.artifactStatusHasMatch(artifact, statusToSearch)) {
70                     filteredArtifactsByStatus.push(artifact);
71                 }
72             } );
73         }
74         return filteredArtifactsByStatus;
75     }
76
77     public getArtifactstByDistributionIDAndComponentsName(distributionID: string, componentName?: string): any[] {
78         const artifacts = [];
79         if (this.getStatusMapForDistributionID(distributionID)) {
80             if (componentName) {
81                 if (this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName).length > 0) {
82                     const artifactsArr = this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName)[0]['artifacts']
83                     if (artifactsArr.length > 0) {
84                         artifactsArr.forEach((artifact) => {
85                             const artifactObj = {
86                                 url: artifact.artifactUrl,
87                                 name: artifact.artifactName,
88                                 statuses: artifact.statuses
89                             };
90                             artifacts.push(artifactObj);
91                         });
92                     }
93                 }
94             } else {
95                 const components = this.getComponentsByDistributionID(distributionID);
96                 components.forEach((componentName) => {
97                     if (this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName).length > 0) {
98                         const artifactsArr = this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName)[0]['artifacts']
99                         if (artifactsArr.length > 0) {
100                             artifactsArr.forEach((artifact) => {
101                                 const artifactObj = {
102                                     url: artifact.artifactUrl,
103                                     name: artifact.artifactName,
104                                     statuses: artifact.statuses
105                                 };
106                                 artifacts.push(artifactObj);
107                             });
108                         }
109                     }
110                 });
111             }
112         }
113         return artifacts;
114     }
115
116     public getStatusMapForDistributionID(distributionID: string) {
117         return this.distributionStatusesMap[distributionID];
118     }
119
120     public markDeploy(uniqueId: string, distributionID: string): Promise<object> {
121         const distributionStatus = this.baseUrl + 'services/' + uniqueId + '/distribution/' + distributionID + '/markDeployed';
122         const res = this.http.post<object>(distributionStatus, {}).pipe(tap( (result) => {
123             console.log(result);
124         }  ));
125         return res.toPromise();
126     }
127
128     public getMSOStatus(distributionID: string, componentName: string): string {
129         const msoStatus = this.distributionStatusesMap[distributionID].filter((component) => component.componentID === componentName)[0].msoStatus;
130         return msoStatus ? msoStatus : '';
131     }
132
133     private artifactStatusHasMatch(artifact: any, statusToSerach: string) {
134         for (let i = 0; i < artifact.statuses.length; i++) {
135             if (artifact.statuses[i].status === statusToSerach) {
136                 return true;
137             }
138         }
139         return false;
140     }
141
142     private insertDistributionStatusToDistributionsMap(distributionID: string, distributionStatusMapResponseFromServer: object[]) {
143
144         // // Clear the Distribution ID array - to avoid statuses duplications
145         const distribution = this.distributionStatusesMap[distributionID];
146         distribution.length = 0;
147
148         // Sort the response of statuses from Server, so it will be easy to pop the latest status when it will be required
149         const sortedResponseByTimeStamp = distributionStatusMapResponseFromServer.sort((a, b) => b['timestamp'] - a['timestamp'])
150
151         sortedResponseByTimeStamp.map((distributionStatus) => {
152             const formattedDate = this.formatDate(distributionStatus['timestamp']);
153
154             // if (distributionStatus['url'] === null) {
155             //     distributionStatus['url'] = "";
156             // }
157
158             const detailedArtifactStatus = {
159                 componentID: distributionStatus['omfComponentID'],
160                 artifactName: distributionStatus['url']? distributionStatus['url'].split('/').pop() : '',
161                 url: distributionStatus['url'],
162                 time: distributionStatus['timestamp'],
163                 status: distributionStatus['status'],
164             };
165
166
167
168             // Add Component to this.distributionStatusesMap in case not exist.
169             let componentPosition = _.findIndex(distribution, {componentID: detailedArtifactStatus.componentID})
170
171             if (componentPosition === -1) {
172                 this.addComponentIdToDistributionStatusMap(distributionID, detailedArtifactStatus.componentID);
173                 componentPosition = distribution.length - 1;
174             }
175
176             const component = distribution[componentPosition];
177
178
179             // Add Artifact to this.distributionStatusesMap[componentID] in case not exist.
180             let artifactPosition = _.findIndex(component.artifacts, {artifactUrl: detailedArtifactStatus.url})
181
182             if (artifactPosition === -1) {
183                 this.addArtifactToComponentId(distributionID, componentPosition, detailedArtifactStatus.artifactName, detailedArtifactStatus.url);
184                 artifactPosition = component.artifacts.length - 1;
185             }
186
187
188             // Add status to relevat artifact in relevent componentID.
189             if (detailedArtifactStatus.url) {
190                 // Case where there is a url -> should add its status
191                 component.artifacts[artifactPosition].statuses.push({
192                     timeStamp: detailedArtifactStatus.time,
193                     status: detailedArtifactStatus.status
194                 });
195             } else {
196                 // Should update the Component -> status from MSO
197                 this.distributionStatusesMap[distributionID][componentPosition].msoStatus = detailedArtifactStatus.status;
198             }
199
200
201         });
202     }
203
204     private addComponentIdToDistributionStatusMap(distributionID: string, componentIDValue: string) {
205         this.distributionStatusesMap[distributionID].push({
206             componentID: componentIDValue,
207             msoStatus: null,
208             artifacts: []
209             });
210     }
211
212     private addArtifactToComponentId(distributionID: string, componentPosition: number, artifactNameValue: string, artifactURLValue: any) {
213         if (artifactNameValue) {
214             this.distributionStatusesMap[distributionID][componentPosition].artifacts.push({
215                 artifactName: artifactNameValue,
216                 artifactUrl: artifactURLValue,
217                 statuses: []
218             });
219         }
220     }
221
222     private insertDistrbutionsToMap() {
223         this.distributionList.map((distribution) => this.distributionStatusesMap[distribution.distributionID] = []);
224     }
225
226     private formatDate(epochTime: string) {
227         const intEpochTime = new Date(parseInt(epochTime, 10));
228         const amOrPm = (intEpochTime.getHours() + 24) % 24 > 12 ? 'PM' : 'AM';
229         const formattedDate = (intEpochTime.getMonth() + 1) + '/' + intEpochTime.getDate() + '/' +  intEpochTime.getFullYear() + ' ' + intEpochTime.getHours() + ':' +
230             intEpochTime.getMinutes() + amOrPm;
231         return formattedDate;
232     }
233 }