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