New audit info screen changes
[vid.git] / vid-app-common / src / main / java / org / onap / vid / services / AuditServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 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 package org.onap.vid.services;
22
23 import static org.apache.commons.lang3.ObjectUtils.notEqual;
24
25 import org.jetbrains.annotations.NotNull;
26 import org.onap.vid.dal.AsyncInstantiationRepository;
27 import org.onap.vid.job.Job;
28 import org.onap.vid.model.JobAuditStatus;
29 import org.onap.vid.mso.*;
30 import org.onap.vid.mso.rest.AsyncRequestStatus;
31 import org.onap.vid.mso.rest.AsyncRequestStatusList;
32 import org.springframework.stereotype.Service;
33 import java.text.MessageFormat;
34 import org.apache.commons.lang3.StringUtils;
35 import javax.inject.Inject;
36 import java.util.List;
37 import java.util.Objects;
38 import java.util.UUID;
39 import java.util.stream.Collectors;
40
41
42 @Service
43 public class AuditServiceImpl implements AuditService{
44
45     private final RestMsoImplementation restMso;
46     private final AsyncInstantiationRepository asyncInstantiationRepository;
47
48     @Inject
49     public AuditServiceImpl(RestMsoImplementation restMso, AsyncInstantiationRepository asyncInstantiationRepository) {
50         this.restMso = restMso;
51         this.asyncInstantiationRepository = asyncInstantiationRepository;
52     }
53
54     @Override
55     public void setFailedAuditStatusFromMso(UUID jobUuid, String requestId, int statusCode, String msoResponse){
56         final String failedMsoRequestStatus = "FAILED";
57         String additionalInfo = MsoUtil.formatExceptionAdditionalInfo(statusCode, msoResponse);
58         auditMsoStatus(jobUuid, failedMsoRequestStatus, requestId, additionalInfo);
59     }
60
61     @Override
62     public List<JobAuditStatus> getAuditStatusFromMsoByRequestId(UUID jobId, UUID requestId) {
63         String filter = "requestId:EQUALS:" + requestId + "&format=statusDetail";
64         return getAuditStatusFromMso(jobId, filter, null);
65     }
66
67     @Override
68     public List<JobAuditStatus> getAuditStatusFromMsoByInstanceId(JobAuditStatus.ResourceTypeFilter resourceTypeFilter, UUID instanceId, UUID jobId) {
69         String filter = resourceTypeFilter.getFilterBy() + ":EQUALS:" + instanceId + "&format=statusDetail";
70         return getAuditStatusFromMso(jobId, filter, instanceId);
71     }
72
73     @Override
74     public List<JobAuditStatus> getAuditStatusFromMsoByJobId(UUID jobId) {
75         List<JobAuditStatus> auditStatuses = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO);
76         String instanceName = getInstanceNameFromServiceInfo(jobId);
77         auditStatuses.stream().forEach(status ->
78                 status.setInstanceName(instanceName)
79         );
80         return auditStatuses;
81     }
82
83     @Override
84     public void auditVidStatus(UUID jobUUID, Job.JobStatus jobStatus){
85         JobAuditStatus vidStatus = new JobAuditStatus(jobUUID, jobStatus.toString(), JobAuditStatus.SourceStatus.VID);
86         auditStatus(vidStatus);
87     }
88
89     @Override
90     public void auditMsoStatus(UUID jobUUID, AsyncRequestStatus.Request msoRequestStatus){
91         auditMsoStatus(jobUUID, msoRequestStatus.requestStatus.getRequestState(), msoRequestStatus.requestId, msoRequestStatus.requestStatus.getStatusMessage());
92     }
93
94     @Override
95     public void auditMsoStatus(UUID jobUUID, String jobStatus, String requestId, String additionalInfo){
96         JobAuditStatus msoStatus = new JobAuditStatus(jobUUID, jobStatus, JobAuditStatus.SourceStatus.MSO,
97                 requestId != null ? UUID.fromString(requestId) : null,
98                 additionalInfo);
99         auditStatus(msoStatus);
100     }
101
102     private void auditStatus(JobAuditStatus jobAuditStatus){
103         JobAuditStatus latestStatus = getLatestAuditStatus(jobAuditStatus.getJobId(), jobAuditStatus.getSource());
104
105         if (notEqual(jobAuditStatus, latestStatus)) {
106             jobAuditStatus.setOrdinal(nextOrdinalAfter(latestStatus));
107             asyncInstantiationRepository.addJobAudiStatus(jobAuditStatus);
108         }
109     }
110
111     protected int nextOrdinalAfter(JobAuditStatus jobAuditStatus) {
112         return jobAuditStatus == null ? 0 : (jobAuditStatus.getOrdinal() + 1);
113     }
114
115     private JobAuditStatus getLatestAuditStatus(UUID jobUUID, JobAuditStatus.SourceStatus source){
116         List<JobAuditStatus> list = getAuditStatuses(jobUUID, source);
117         return !list.isEmpty() ? list.get(list.size()-1) : null;
118     }
119
120     public List<JobAuditStatus> getAuditStatuses(UUID jobUUID, JobAuditStatus.SourceStatus source) {
121         return asyncInstantiationRepository.getAuditStatuses(jobUUID, source);
122     }
123
124     @Override
125     //modelType is requestScope in MSO response
126     public List<AsyncRequestStatus.Request> retrieveRequestsFromMsoByServiceIdAndRequestTypeAndScope(String instanceId, String requestType, String modelType) {
127         String filter = JobAuditStatus.ResourceTypeFilter.SERVICE.getFilterBy() + ":EQUALS:" + instanceId;
128         List<AsyncRequestStatus> msoStatuses = getAsyncRequestStatusListFromMso(filter);
129         return msoStatuses.stream()
130                 .filter(x -> Objects.equals(x.request.requestType, requestType) && Objects.equals(x.request.requestScope, modelType))
131                 .map(x -> x.request)
132                 .collect(Collectors.toList());
133     }
134
135     private List<JobAuditStatus> getAuditStatusFromMso(UUID jobId, String filter, UUID instanceId) {
136
137         List<AsyncRequestStatus> msoStatuses = getAsyncRequestStatusListFromMso(filter);
138
139         //add service name from service info for each audit status (in case that serviceInstanceId is null all statuses belong to service)
140         String userInstanceName = (instanceId == null && jobId != null) ? getInstanceNameFromServiceInfo(jobId) : null;
141         return convertMsoResponseStatusToJobAuditStatus(msoStatuses, userInstanceName);
142     }
143
144     @NotNull
145     private List<AsyncRequestStatus> getAsyncRequestStatusListFromMso(String filter) {
146         String path = MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQS) + "filter=" + filter;
147         RestObject<AsyncRequestStatusList> msoResponse = restMso.GetForObject(path , AsyncRequestStatusList.class);
148         if (msoResponse.getStatusCode() >= 400 || msoResponse.get() == null) {
149             throw new BadResponseFromMso(msoResponse);
150         }
151         return msoResponse.get().getRequestList();
152     }
153
154     private String getInstanceNameFromServiceInfo(UUID jobId) {
155         return asyncInstantiationRepository.getServiceInfoByJobId(jobId).getServiceInstanceName();
156     }
157
158     protected List<JobAuditStatus> convertMsoResponseStatusToJobAuditStatus(List<AsyncRequestStatus> msoStatuses, String defaultName){
159         return msoStatuses.stream().map(status ->
160                 convertAsyncRequestStatusToJobAuditStatusAdditionalInfo(status, defaultName)
161         ).collect(Collectors.toList());
162     }
163     private JobAuditStatus convertAsyncRequestStatusToJobAuditStatusAdditionalInfo(AsyncRequestStatus status, String defaultName) {
164         if (status == null) {
165             return null;
166         }
167         UUID requestId = null;
168         String instanceName = defaultName;
169         String jobStatus = null;
170         String additionalInfo = null;
171         String finishTime = null;
172         String instanceType = null;
173         String modelType = "";
174         String startTime = null;
175         AsyncRequestStatus.Request request = status.request;
176         if (request != null) {
177             if (request.requestId != null) {
178                 requestId = UUID.fromString(request.requestId);
179             }
180             instanceName = extractInstanceName(instanceName, request);
181             instanceType = request.requestType;
182             if (request.requestDetails != null && request.requestDetails.modelInfo != null) {
183                 modelType = request.requestDetails.modelInfo.modelType;
184             }
185             startTime = request.startTime;
186
187             if (request.requestStatus != null) {
188                 jobStatus = request.requestStatus.getRequestState();
189                 additionalInfo = buildAdditionalInfo(request);
190
191                 if (!request.requestStatus.getAdditionalProperties().isEmpty() &&
192                     request.requestStatus.getAdditionalProperties().get("finishTime") != null) {
193                     finishTime = request.requestStatus.getAdditionalProperties().get("finishTime").toString();
194                 } else {
195                     finishTime = request.requestStatus.getTimestamp();
196                 }
197             }
198         }
199         return new JobAuditStatus(requestId, instanceName, modelType, instanceType, startTime, finishTime,
200             jobStatus, additionalInfo);
201     }
202     private String buildAdditionalInfo(AsyncRequestStatus.Request request) {
203         String source = "";
204         String statusMessage = "";
205         String flowStatus = "";
206         String subscriptionServiceType = "";
207         String alacarte = "";
208         String testApi = "";
209         String projectName = "";
210         String owningEntityId = "";
211         String owningEntityName = "";
212         String requestScope = "";
213         String tenantId = "";
214         String tenantName = "";
215         String cloudOwner = "";
216         String platformName = "";
217         String lineOfBusiness = "";
218         MessageFormat mfBasedOnService = null;
219         String otherInfo = "";
220         MessageFormat mf = new MessageFormat("{0}" +
221             "{1}" +
222             "{2}" +
223             "{3}" +
224             "{4}" +
225             "{5}"+
226             "{6}");
227         requestScope = request.requestScope;
228         statusMessage = request.requestStatus != null ? "<b>StatusMessage:</b>"+request.requestStatus.getStatusMessage()+ "</br>": "";
229         if(request.requestDetails != null && request.requestDetails.requestInfo != null) {
230             source = "<b>Source:</b> "+request.requestDetails.requestInfo.source + "</br>";
231         }
232         if(request.requestStatus != null && request.requestStatus.getFlowStatus() != null) {
233             flowStatus = "<b>FlowStatus:</b> "+request.requestStatus.getFlowStatus()+ "</br>";
234         }
235         if(request.requestDetails != null && request.requestDetails.requestParameters != null &&
236             request.requestDetails.requestParameters.subscriptionServiceType != null) {
237             subscriptionServiceType = "<b>SubscriptionServiceType:</b> "+request.requestDetails.requestParameters.subscriptionServiceType+ "</br>";
238         }
239         if(request.requestDetails != null && request.requestDetails.requestParameters != null &&
240             request.requestDetails.requestParameters.aLaCarte != null) {
241             alacarte = "<b>Alacarte:</b> "+request.requestDetails.requestParameters.aLaCarte+ "</br>";
242         }
243         if(request.requestDetails != null && request.requestDetails.requestParameters != null &&
244             request.requestDetails.requestParameters.testApi != null) {
245             testApi = "<b>TestAPI:</b> "+request.requestDetails.requestParameters.testApi+ "</br>";
246         }
247
248         if(request.requestDetails != null) {
249             if("service".equals(requestScope)) {
250                 mfBasedOnService = new MessageFormat("<b>ProjectName: {0}</br>" +
251                     "<b>OwningEntityId:</b> {1}</br>" +
252                     "<b>OwningEntityName:</b> {2}</br>");
253                 projectName = request.requestDetails.project != null ? request.requestDetails.project.projectName : "";
254                 owningEntityId = request.requestDetails.owningEntity != null ? request.requestDetails.owningEntity.owningEntityId : "";
255                 owningEntityName = request.requestDetails.owningEntity != null ? request.requestDetails.owningEntity.owningEntityName : "";
256                 Object[] arr1 = new Object[]{projectName, owningEntityId, owningEntityName};
257                 otherInfo = mfBasedOnService.format(arr1);
258             } else if("vnf".equals(requestScope)) {
259                 mfBasedOnService = new MessageFormat("<b>TenantId:</b> {0}</br>" +
260                     "<b>TenantName:</b> {1}</br>" +
261                     "<b>CloudOwner:</b> {2}</br>" +
262                     "<b>PlatformName:</b> {3}</br>" +
263                     "<b>LineOfBusiness:</b> {4}</br>");
264                 tenantId = request.requestDetails.cloudConfiguration != null ? request.requestDetails.cloudConfiguration.tenantId : "";
265                 tenantName= request.requestDetails.cloudConfiguration != null ? request.requestDetails.cloudConfiguration.tenantName : "";
266                 cloudOwner= request.requestDetails.cloudConfiguration != null ? request.requestDetails.cloudConfiguration.cloudOwner : "";
267                 platformName= request.requestDetails.platform != null ? request.requestDetails.platform.platformName : "";
268                 lineOfBusiness= request.requestDetails.lineOfBusiness != null ? request.requestDetails.lineOfBusiness.lineOfBusinessName : "";
269                 Object[] arr2 = new Object[]{tenantId, tenantName, cloudOwner,platformName,lineOfBusiness};
270                 otherInfo = mfBasedOnService.format(arr2);
271             } else if("vfModule".equals(requestScope)) {
272                 mfBasedOnService = new MessageFormat("<b>TenantId:</b> {0}</br>" +
273                     "<b>TenantName:</b> {1}</br>" +
274                     "<b>CloudOwner:</b> {2}</br>");
275                 tenantId = request.requestDetails.cloudConfiguration != null ? request.requestDetails.cloudConfiguration.tenantId : "";
276                 tenantName= request.requestDetails.cloudConfiguration != null ? request.requestDetails.cloudConfiguration.tenantName : "";
277                 cloudOwner= request.requestDetails.cloudConfiguration != null ? request.requestDetails.cloudConfiguration.cloudOwner : "";
278                 Object[] arr2 = new Object[]{tenantId, tenantName, cloudOwner};
279                 otherInfo = mfBasedOnService.format(arr2);
280             }
281         }
282         Object[] objArray = {source, statusMessage, flowStatus, subscriptionServiceType, alacarte, testApi, otherInfo};
283         return StringUtils.chomp(mf.format(objArray));
284     }
285     private JobAuditStatus convertAsyncRequestStatusToJobAuditStatus(AsyncRequestStatus status, String defaultName){
286         if (status == null) {
287             return null;
288         }
289
290         UUID requestId = null;
291         String instanceName = defaultName;
292         String jobStatus = null;
293         String additionalInfo = null;
294         String created = null;
295         String instanceType = null;
296
297         AsyncRequestStatus.Request request = status.request;
298         if(request != null) {
299             if (request.requestId != null) {
300                 requestId = UUID.fromString(request.requestId);
301             }
302             instanceName = extractInstanceName(instanceName, request);
303             instanceType = request.requestScope;
304             if(request.requestStatus != null) {
305                 jobStatus = request.requestStatus.getRequestState();
306                 additionalInfo = request.requestStatus.getStatusMessage();
307                 if(!request.requestStatus.getAdditionalProperties().isEmpty() &&
308                         request.requestStatus.getAdditionalProperties().get("finishTime") != null) {
309                     created = request.requestStatus.getAdditionalProperties().get("finishTime").toString();
310                 } else {
311                     created = request.requestStatus.getTimestamp();
312                 }
313             }
314         }
315         return new JobAuditStatus(instanceName, jobStatus, requestId, additionalInfo, created, instanceType);
316     }
317
318     private String extractInstanceName(String instanceName, AsyncRequestStatus.Request request) {
319         if(request.requestDetails != null && request.requestDetails.requestInfo != null && request.requestDetails.requestInfo.instanceName != null) {
320             instanceName = request.requestDetails.requestInfo.instanceName;
321         }
322         return instanceName;
323     }
324
325     @Override
326     public JobAuditStatus getResourceAuditStatus(String trackById) {
327         AsyncRequestStatus asyncRequestStatus = asyncInstantiationRepository.getResourceInfoByTrackId(trackById).getErrorMessage();
328         return convertAsyncRequestStatusToJobAuditStatus(asyncRequestStatus, null);
329     }
330
331
332     public static class BadResponseFromMso extends RuntimeException {
333         private final RestObject<AsyncRequestStatusList> msoResponse;
334
335         public BadResponseFromMso(RestObject<AsyncRequestStatusList> msoResponse) {
336             this.msoResponse = msoResponse;
337         }
338
339         public RestObject<AsyncRequestStatusList> getMsoResponse() {
340             return msoResponse;
341         }
342     }
343 }