34dcd4b0c45e2c7c05ae89e57bb0de27082738ba
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.apihandlerinfra;
24
25 import java.io.IOException;
26 import java.text.SimpleDateFormat;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import javax.transaction.Transactional;
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.GET;
34 import javax.ws.rs.POST;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.PathParam;
37 import javax.ws.rs.Produces;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.MultivaluedMap;
41 import javax.ws.rs.core.Response;
42 import javax.ws.rs.core.UriInfo;
43 import org.apache.commons.lang.StringUtils;
44 import org.apache.http.HttpStatus;
45 import org.onap.so.apihandler.common.ErrorNumbers;
46 import org.onap.so.apihandler.common.ResponseBuilder;
47 import org.onap.so.apihandlerinfra.exceptions.ApiException;
48 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
49 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
50 import org.onap.so.db.request.beans.InfraActiveRequests;
51 import org.onap.so.db.request.beans.RequestProcessingData;
52 import org.onap.so.db.request.client.RequestsDbClient;
53 import org.onap.so.exceptions.ValidationException;
54 import org.onap.so.logger.ErrorCode;
55 import org.onap.so.logger.MessageEnum;
56 import org.onap.so.serviceinstancebeans.GetOrchestrationListResponse;
57 import org.onap.so.serviceinstancebeans.GetOrchestrationResponse;
58 import org.onap.so.serviceinstancebeans.InstanceReferences;
59 import org.onap.so.serviceinstancebeans.Request;
60 import org.onap.so.serviceinstancebeans.RequestDetails;
61 import org.onap.so.serviceinstancebeans.RequestList;
62 import org.onap.so.serviceinstancebeans.RequestStatus;
63 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66 import org.springframework.beans.factory.annotation.Autowired;
67 import org.springframework.stereotype.Component;
68 import com.fasterxml.jackson.databind.ObjectMapper;
69 import io.swagger.annotations.Api;
70 import io.swagger.annotations.ApiOperation;
71
72 @Path("onap/so/infra/orchestrationRequests")
73 @Api(value = "onap/so/infra/orchestrationRequests", description = "API Requests for Orchestration requests")
74 @Component
75 public class OrchestrationRequests {
76
77     private static Logger logger = LoggerFactory.getLogger(OrchestrationRequests.class);
78
79
80     @Autowired
81     private RequestsDbClient requestsDbClient;
82
83     @Autowired
84     private MsoRequest msoRequest;
85
86     @Autowired
87     private ResponseBuilder builder;
88
89     @GET
90     @Path("/{version:[vV][4-7]}/{requestId}")
91     @ApiOperation(value = "Find Orchestrated Requests for a given requestId", response = Response.class)
92     @Produces(MediaType.APPLICATION_JSON)
93     @Transactional
94     public Response getOrchestrationRequest(@PathParam("requestId") String requestId,
95             @PathParam("version") String version) throws ApiException {
96
97         String apiVersion = version.substring(1);
98         GetOrchestrationResponse orchestrationResponse = new GetOrchestrationResponse();
99
100
101         InfraActiveRequests infraActiveRequest = null;
102         List<org.onap.so.db.request.beans.RequestProcessingData> requestProcessingData = null;
103         try {
104             infraActiveRequest = requestsDbClient.getInfraActiveRequestbyRequestId(requestId);
105             requestProcessingData = requestsDbClient.getRequestProcessingDataBySoRequestId(requestId);
106
107         } catch (Exception e) {
108             logger.error("Exception occurred", e);
109             ErrorLoggerInfo errorLoggerInfo =
110                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.AvailabilityError).build();
111
112
113
114             ValidateException validateException =
115                     new ValidateException.Builder("Exception while communciate with Request DB - Infra Request Lookup",
116                             HttpStatus.SC_NOT_FOUND, ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB).cause(e)
117                                     .errorInfo(errorLoggerInfo).build();
118
119
120             throw validateException;
121
122         }
123
124         if (infraActiveRequest == null) {
125
126             ErrorLoggerInfo errorLoggerInfo = new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
127                     ErrorCode.BusinessProcesssError).build();
128
129
130             ValidateException validateException =
131                     new ValidateException.Builder("Orchestration RequestId " + requestId + " is not found in DB",
132                             HttpStatus.SC_NO_CONTENT, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR)
133                                     .errorInfo(errorLoggerInfo).build();
134
135             throw validateException;
136         }
137
138         Request request = mapInfraActiveRequestToRequest(infraActiveRequest);
139         if (!requestProcessingData.isEmpty()) {
140             request.setRequestProcessingData(mapRequestProcessingData(requestProcessingData));
141         }
142         request.setRequestId(requestId);
143         orchestrationResponse.setRequest(request);
144
145         return builder.buildResponse(HttpStatus.SC_OK, requestId, orchestrationResponse, apiVersion);
146     }
147
148     @GET
149     @Path("/{version:[vV][4-7]}")
150     @ApiOperation(value = "Find Orchestrated Requests for a URI Information", response = Response.class)
151     @Produces(MediaType.APPLICATION_JSON)
152     @Transactional
153     public Response getOrchestrationRequest(@Context UriInfo ui, @PathParam("version") String version)
154             throws ApiException {
155
156         long startTime = System.currentTimeMillis();
157
158         MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
159
160         List<InfraActiveRequests> activeRequests = null;
161
162         GetOrchestrationListResponse orchestrationList = null;
163         Map<String, List<String>> orchestrationMap;
164         String apiVersion = version.substring(1);
165
166         try {
167             orchestrationMap = msoRequest.getOrchestrationFilters(queryParams);
168             if (orchestrationMap.isEmpty()) {
169                 throw new ValidationException("At least one filter query param must be specified");
170             }
171         } catch (ValidationException ex) {
172             logger.error("Exception occurred", ex);
173             ErrorLoggerInfo errorLoggerInfo =
174                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.DataError).build();
175             ValidateException validateException =
176                     new ValidateException.Builder(ex.getMessage(), HttpStatus.SC_BAD_REQUEST,
177                             ErrorNumbers.SVC_GENERAL_SERVICE_ERROR).cause(ex).errorInfo(errorLoggerInfo).build();
178             throw validateException;
179
180         }
181
182         activeRequests = requestsDbClient.getOrchestrationFiltersFromInfraActive(orchestrationMap);
183
184         orchestrationList = new GetOrchestrationListResponse();
185         List<RequestList> requestLists = new ArrayList<>();
186
187         for (InfraActiveRequests infraActive : activeRequests) {
188             List<RequestProcessingData> requestProcessingData =
189                     requestsDbClient.getRequestProcessingDataBySoRequestId(infraActive.getRequestId());
190             RequestList requestList = new RequestList();
191             Request request = mapInfraActiveRequestToRequest(infraActive);
192             if (!requestProcessingData.isEmpty()) {
193                 request.setRequestProcessingData(mapRequestProcessingData(requestProcessingData));
194             }
195             requestList.setRequest(request);
196             requestLists.add(requestList);
197         }
198
199         orchestrationList.setRequestList(requestLists);
200         return builder.buildResponse(HttpStatus.SC_OK, null, orchestrationList, apiVersion);
201     }
202
203
204     @POST
205     @Path("/{version: [vV][4-7]}/{requestId}/unlock")
206     @Consumes(MediaType.APPLICATION_JSON)
207     @Produces(MediaType.APPLICATION_JSON)
208     @ApiOperation(value = "Unlock Orchestrated Requests for a given requestId", response = Response.class)
209     @Transactional
210     public Response unlockOrchestrationRequest(String requestJSON, @PathParam("requestId") String requestId,
211             @PathParam("version") String version) throws ApiException {
212
213         long startTime = System.currentTimeMillis();
214         logger.debug("requestId is: {}", requestId);
215         ServiceInstancesRequest sir = null;
216
217         InfraActiveRequests infraActiveRequest = null;
218         Request request = null;
219
220         try {
221             ObjectMapper mapper = new ObjectMapper();
222             sir = mapper.readValue(requestJSON, ServiceInstancesRequest.class);
223         } catch (IOException e) {
224             logger.error("Exception occurred", e);
225             ErrorLoggerInfo errorLoggerInfo =
226                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
227                             .build();
228             ValidateException validateException =
229                     new ValidateException.Builder("Mapping of request to JSON object failed : " + e.getMessage(),
230                             HttpStatus.SC_BAD_REQUEST, ErrorNumbers.SVC_BAD_PARAMETER).cause(e)
231                                     .errorInfo(errorLoggerInfo).build();
232
233             throw validateException;
234
235         }
236         try {
237             msoRequest.parseOrchestration(sir);
238         } catch (Exception e) {
239             logger.error("Exception occurred", e);
240             ErrorLoggerInfo errorLoggerInfo =
241                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
242                             .build();
243             ValidateException validateException =
244                     new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
245                             ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
246             throw validateException;
247         }
248
249         infraActiveRequest = requestsDbClient.getInfraActiveRequestbyRequestId(requestId);
250         if (infraActiveRequest == null) {
251             ErrorLoggerInfo errorLoggerInfo = new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND,
252                     ErrorCode.BusinessProcesssError).build();
253
254
255             ValidateException validateException =
256                     new ValidateException.Builder("Null response from RequestDB when searching by RequestId",
257                             HttpStatus.SC_NOT_FOUND, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).errorInfo(errorLoggerInfo)
258                                     .build();
259
260             throw validateException;
261
262         } else {
263             String status = infraActiveRequest.getRequestStatus();
264             if (status.equalsIgnoreCase("IN_PROGRESS") || status.equalsIgnoreCase("PENDING")
265                     || status.equalsIgnoreCase("PENDING_MANUAL_TASK")) {
266                 infraActiveRequest.setRequestStatus("UNLOCKED");
267                 infraActiveRequest.setLastModifiedBy(Constants.MODIFIED_BY_APIHANDLER);
268                 infraActiveRequest.setRequestId(requestId);
269                 requestsDbClient.save(infraActiveRequest);
270             } else {
271
272                 ErrorLoggerInfo errorLoggerInfo =
273                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, ErrorCode.DataError)
274                                 .build();
275
276
277                 ValidateException validateException = new ValidateException.Builder(
278                         "Orchestration RequestId " + requestId + " has a status of " + status
279                                 + " and can not be unlocked",
280                         HttpStatus.SC_BAD_REQUEST, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).errorInfo(errorLoggerInfo)
281                                 .build();
282
283                 throw validateException;
284             }
285         }
286         return Response.status(HttpStatus.SC_NO_CONTENT).entity("").build();
287     }
288
289     private Request mapInfraActiveRequestToRequest(InfraActiveRequests iar) throws ApiException {
290
291         String requestBody = iar.getRequestBody();
292         Request request = new Request();
293
294         ObjectMapper mapper = new ObjectMapper();
295
296         request.setRequestId(iar.getRequestId());
297         request.setRequestScope(iar.getRequestScope());
298         request.setRequestType(iar.getRequestAction());
299         String rollbackStatusMessage = iar.getRollbackStatusMessage();
300         String flowStatusMessage = iar.getFlowStatus();
301         String retryStatusMessage = iar.getRetryStatusMessage();
302
303
304         InstanceReferences ir = new InstanceReferences();
305         if (iar.getNetworkId() != null)
306             ir.setNetworkInstanceId(iar.getNetworkId());
307         if (iar.getNetworkName() != null)
308             ir.setNetworkInstanceName(iar.getNetworkName());
309         if (iar.getServiceInstanceId() != null)
310             ir.setServiceInstanceId(iar.getServiceInstanceId());
311         if (iar.getServiceInstanceName() != null)
312             ir.setServiceInstanceName(iar.getServiceInstanceName());
313         if (iar.getVfModuleId() != null)
314             ir.setVfModuleInstanceId(iar.getVfModuleId());
315         if (iar.getVfModuleName() != null)
316             ir.setVfModuleInstanceName(iar.getVfModuleName());
317         if (iar.getVnfId() != null)
318             ir.setVnfInstanceId(iar.getVnfId());
319         if (iar.getVnfName() != null)
320             ir.setVnfInstanceName(iar.getVnfName());
321         if (iar.getVolumeGroupId() != null)
322             ir.setVolumeGroupInstanceId(iar.getVolumeGroupId());
323         if (iar.getVolumeGroupName() != null)
324             ir.setVolumeGroupInstanceName(iar.getVolumeGroupName());
325         if (iar.getRequestorId() != null)
326             ir.setRequestorId(iar.getRequestorId());
327         if (iar.getInstanceGroupId() != null)
328             ir.setInstanceGroupId(iar.getInstanceGroupId());
329         if (iar.getInstanceGroupName() != null)
330             ir.setInstanceGroupName(iar.getInstanceGroupName());
331
332
333
334         request.setInstanceReferences(ir);
335
336         RequestDetails requestDetails = null;
337
338         if (StringUtils.isNotBlank(requestBody)) {
339             try {
340                 if (requestBody.contains("\"requestDetails\":")) {
341                     ServiceInstancesRequest sir = mapper.readValue(requestBody, ServiceInstancesRequest.class);
342                     requestDetails = sir.getRequestDetails();
343                 } else {
344                     requestDetails = mapper.readValue(requestBody, RequestDetails.class);
345                 }
346             } catch (IOException e) {
347                 logger.error("Exception occurred", e);
348                 ErrorLoggerInfo errorLoggerInfo =
349                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
350                                 .build();
351                 ValidateException validateException =
352                         new ValidateException.Builder("Mapping of request to JSON object failed : ",
353                                 HttpStatus.SC_BAD_REQUEST, ErrorNumbers.SVC_BAD_PARAMETER).cause(e)
354                                         .errorInfo(errorLoggerInfo).build();
355
356                 throw validateException;
357             }
358         }
359         request.setRequestDetails(requestDetails);
360
361         if (iar.getStartTime() != null) {
362             String startTimeStamp =
363                     new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss").format(iar.getStartTime()) + " GMT";
364             request.setStartTime(startTimeStamp);
365         }
366         if (iar.getEndTime() != null) {
367             String endTimeStamp = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss").format(iar.getEndTime()) + " GMT";
368             request.setFinishTime(endTimeStamp);
369         }
370         String statusMessages = null;
371         RequestStatus status = new RequestStatus();
372         if (iar.getStatusMessage() != null) {
373             statusMessages = "STATUS: " + iar.getStatusMessage();
374         }
375         if (flowStatusMessage != null) {
376             if (statusMessages != null) {
377                 statusMessages = statusMessages + " " + "FLOW STATUS: " + flowStatusMessage;
378             } else {
379                 statusMessages = "FLOW STATUS: " + flowStatusMessage;
380             }
381         }
382         if (retryStatusMessage != null) {
383             if (statusMessages != null) {
384                 statusMessages = statusMessages + " " + "RETRY STATUS: " + retryStatusMessage;
385             } else {
386                 statusMessages = "RETRY STATUS: " + retryStatusMessage;
387             }
388         }
389         if (rollbackStatusMessage != null) {
390             if (statusMessages != null) {
391                 statusMessages = statusMessages + " " + "ROLLBACK STATUS: " + rollbackStatusMessage;
392             } else {
393                 statusMessages = "ROLLBACK STATUS: " + rollbackStatusMessage;
394             }
395         }
396         if (statusMessages != null) {
397             status.setStatusMessage(statusMessages);
398         }
399         if (iar.getModifyTime() != null) {
400             String timeStamp = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss").format(iar.getModifyTime()) + " GMT";
401             status.setTimeStamp(timeStamp);
402         }
403
404
405         if (iar.getRequestStatus() != null) {
406             status.setRequestState(iar.getRequestStatus());
407         }
408
409         if (iar.getProgress() != null) {
410             status.setPercentProgress(iar.getProgress().intValue());
411         }
412
413         request.setRequestStatus(status);
414
415         return request;
416     }
417
418     public List<org.onap.so.serviceinstancebeans.RequestProcessingData> mapRequestProcessingData(
419             List<org.onap.so.db.request.beans.RequestProcessingData> processingData) {
420         List<org.onap.so.serviceinstancebeans.RequestProcessingData> addedRequestProcessingData = new ArrayList<>();
421         org.onap.so.serviceinstancebeans.RequestProcessingData finalProcessingData =
422                 new org.onap.so.serviceinstancebeans.RequestProcessingData();
423         String currentGroupingId = null;
424         HashMap<String, String> tempMap = new HashMap<>();
425         List<HashMap<String, String>> tempList = new ArrayList<>();
426         for (RequestProcessingData data : processingData) {
427             String groupingId = data.getGroupingId();
428             String tag = data.getTag();
429             if (currentGroupingId == null || !currentGroupingId.equals(groupingId)) {
430                 if (!tempMap.isEmpty()) {
431                     tempList.add(tempMap);
432                     finalProcessingData.setDataPairs(tempList);
433                     addedRequestProcessingData.add(finalProcessingData);
434                 }
435                 finalProcessingData = new org.onap.so.serviceinstancebeans.RequestProcessingData();
436                 if (groupingId != null) {
437                     finalProcessingData.setGroupingId(groupingId);
438                 }
439                 if (tag != null) {
440                     finalProcessingData.setTag(tag);
441                 }
442                 currentGroupingId = groupingId;
443                 tempMap = new HashMap<>();
444                 tempList = new ArrayList<>();
445                 if (data.getName() != null && data.getValue() != null) {
446                     tempMap.put(data.getName(), data.getValue());
447                 }
448             } else {
449                 if (data.getName() != null && data.getValue() != null) {
450                     tempMap.put(data.getName(), data.getValue());
451                 }
452             }
453         }
454         if (tempMap.size() > 0) {
455             tempList.add(tempMap);
456             finalProcessingData.setDataPairs(tempList);
457         }
458         addedRequestProcessingData.add(finalProcessingData);
459         return addedRequestProcessingData;
460     }
461 }