Merge "Missing VNF Recipe for Optical service"
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / onap / so / apihandlerinfra / RequestHandlerUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7  * Modifications Copyright (C) 2019 IBM.
8  * ================================================================================
9  * Modifications Copyright (c) 2019 Samsung
10  * ================================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  * 
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  * 
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.so.apihandlerinfra;
26
27
28 import static org.onap.so.logger.HttpHeadersConstants.REQUESTOR_ID;
29 import java.io.IOException;
30 import java.net.URL;
31 import java.sql.Timestamp;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Optional;
37 import javax.ws.rs.container.ContainerRequestContext;
38 import javax.ws.rs.core.MultivaluedMap;
39 import javax.ws.rs.core.Response;
40 import org.apache.commons.lang.StringUtils;
41 import org.apache.http.HttpResponse;
42 import org.apache.http.HttpStatus;
43 import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
44 import org.onap.logging.ref.slf4j.ONAPLogConstants;
45 import org.onap.so.apihandler.camundabeans.CamundaResponse;
46 import org.onap.so.apihandler.common.CommonConstants;
47 import org.onap.so.apihandler.common.ErrorNumbers;
48 import org.onap.so.apihandler.common.RequestClient;
49 import org.onap.so.apihandler.common.RequestClientFactory;
50 import org.onap.so.apihandler.common.RequestClientParameter;
51 import org.onap.so.apihandler.common.ResponseBuilder;
52 import org.onap.so.apihandler.common.ResponseHandler;
53 import org.onap.so.apihandlerinfra.exceptions.ApiException;
54 import org.onap.so.apihandlerinfra.exceptions.BPMNFailureException;
55 import org.onap.so.apihandlerinfra.exceptions.ClientConnectionException;
56 import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException;
57 import org.onap.so.apihandlerinfra.exceptions.DuplicateRequestException;
58 import org.onap.so.apihandlerinfra.exceptions.RecipeNotFoundException;
59 import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException;
60 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
61 import org.onap.so.apihandlerinfra.exceptions.VfModuleNotFoundException;
62 import org.onap.so.apihandlerinfra.infra.rest.handler.AbstractRestHandler;
63 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
64 import org.onap.so.constants.Status;
65 import org.onap.so.db.catalog.beans.NetworkResource;
66 import org.onap.so.db.catalog.beans.NetworkResourceCustomization;
67 import org.onap.so.db.catalog.beans.Recipe;
68 import org.onap.so.db.catalog.beans.ServiceRecipe;
69 import org.onap.so.db.catalog.beans.VfModule;
70 import org.onap.so.db.catalog.beans.VfModuleCustomization;
71 import org.onap.so.db.catalog.beans.VnfRecipe;
72 import org.onap.so.db.catalog.beans.VnfResource;
73 import org.onap.so.db.catalog.beans.VnfResourceCustomization;
74 import org.onap.so.db.catalog.client.CatalogDbClient;
75 import org.onap.so.db.request.beans.InfraActiveRequests;
76 import org.onap.so.exceptions.ValidationException;
77 import org.onap.logging.filter.base.ErrorCode;
78 import org.onap.so.logger.LogConstants;
79 import org.onap.so.logger.MessageEnum;
80 import org.onap.so.serviceinstancebeans.CloudConfiguration;
81 import org.onap.so.serviceinstancebeans.ModelInfo;
82 import org.onap.so.serviceinstancebeans.ModelType;
83 import org.onap.so.serviceinstancebeans.Networks;
84 import org.onap.so.serviceinstancebeans.RelatedInstance;
85 import org.onap.so.serviceinstancebeans.RelatedInstanceList;
86 import org.onap.so.serviceinstancebeans.RequestDetails;
87 import org.onap.so.serviceinstancebeans.RequestParameters;
88 import org.onap.so.serviceinstancebeans.Service;
89 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
90 import org.onap.so.serviceinstancebeans.ServiceInstancesResponse;
91 import org.onap.so.serviceinstancebeans.VfModules;
92 import org.onap.so.serviceinstancebeans.Vnfs;
93 import org.onap.so.utils.UUIDChecker;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96 import org.slf4j.MDC;
97 import org.springframework.beans.factory.annotation.Autowired;
98 import org.springframework.core.env.Environment;
99 import org.springframework.http.ResponseEntity;
100 import org.springframework.stereotype.Component;
101 import org.springframework.web.client.RestClientException;
102 import com.fasterxml.jackson.annotation.JsonInclude.Include;
103 import com.fasterxml.jackson.databind.ObjectMapper;
104
105 @Component
106 public class RequestHandlerUtils extends AbstractRestHandler {
107
108     private static Logger logger = LoggerFactory.getLogger(RequestHandlerUtils.class);
109
110     protected static final String SAVE_TO_DB = "save instance to db";
111     private static final String NAME = "name";
112     private static final String VALUE = "value";
113
114     @Autowired
115     private Environment env;
116
117     @Autowired
118     private RequestClientFactory reqClientFactory;
119
120     @Autowired
121     private ResponseBuilder builder;
122
123     @Autowired
124     private MsoRequest msoRequest;
125
126     @Autowired
127     private CamundaRequestHandler camundaRequestHandler;
128
129     @Autowired
130     private CatalogDbClient catalogDbClient;
131
132     public Response postBPELRequest(InfraActiveRequests currentActiveReq, RequestClientParameter requestClientParameter,
133             String orchestrationUri, String requestScope) throws ApiException {
134         HttpResponse response = null;
135         RequestClient requestClient = null;
136
137         try {
138             requestClient = reqClientFactory.getRequestClient(orchestrationUri);
139             response = requestClient.post(requestClientParameter);
140         } catch (Exception e) {
141             logger.error("Error posting request to BPMN", e);
142             ErrorLoggerInfo errorLoggerInfo =
143                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, ErrorCode.AvailabilityError)
144                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
145             String url = requestClient != null ? requestClient.getUrl() : "";
146             ClientConnectionException clientException =
147                     new ClientConnectionException.Builder(url, HttpStatus.SC_BAD_GATEWAY,
148                             ErrorNumbers.SVC_NO_SERVER_RESOURCES).cause(e).errorInfo(errorLoggerInfo).build();
149             updateStatus(currentActiveReq, Status.FAILED, clientException.getMessage());
150             throw clientException;
151         }
152
153         if (response == null) {
154
155             ErrorLoggerInfo errorLoggerInfo =
156                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, ErrorCode.BusinessProcessError)
157                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
158             ClientConnectionException clientException = new ClientConnectionException.Builder(requestClient.getUrl(),
159                     HttpStatus.SC_BAD_GATEWAY, ErrorNumbers.SVC_NO_SERVER_RESOURCES).errorInfo(errorLoggerInfo).build();
160             updateStatus(currentActiveReq, Status.FAILED, clientException.getMessage());
161             throw clientException;
162         }
163
164         ResponseHandler respHandler = null;
165         int bpelStatus = 500;
166         try {
167             respHandler = new ResponseHandler(response, requestClient.getType());
168             bpelStatus = respHandler.getStatus();
169         } catch (ApiException e) {
170             logger.error("Exception occurred", e);
171             ErrorLoggerInfo errorLoggerInfo =
172                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
173                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
174             ValidateException validateException =
175                     new ValidateException.Builder("Exception caught mapping Camunda JSON response to object",
176                             HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).cause(e)
177                                     .errorInfo(errorLoggerInfo).build();
178             updateStatus(currentActiveReq, Status.FAILED, validateException.getMessage());
179             throw validateException;
180         }
181
182         // BPEL accepted the request, the request is in progress
183         if (bpelStatus == HttpStatus.SC_ACCEPTED) {
184             ServiceInstancesResponse jsonResponse;
185             CamundaResponse camundaResp = respHandler.getResponse();
186
187             if ("Success".equalsIgnoreCase(camundaResp.getMessage())) {
188                 try {
189                     ObjectMapper mapper = new ObjectMapper();
190                     jsonResponse = mapper.readValue(camundaResp.getResponse(), ServiceInstancesResponse.class);
191                     jsonResponse.getRequestReferences().setRequestId(requestClientParameter.getRequestId());
192                     Optional<URL> selfLinkUrl =
193                             buildSelfLinkUrl(currentActiveReq.getRequestUrl(), requestClientParameter.getRequestId());
194                     if (selfLinkUrl.isPresent()) {
195                         jsonResponse.getRequestReferences().setRequestSelfLink(selfLinkUrl.get());
196                     } else {
197                         jsonResponse.getRequestReferences().setRequestSelfLink(null);
198                     }
199                 } catch (IOException e) {
200                     logger.error("Exception occurred", e);
201                     ErrorLoggerInfo errorLoggerInfo =
202                             new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
203                                     .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
204                     ValidateException validateException =
205                             new ValidateException.Builder("Exception caught mapping Camunda JSON response to object",
206                                     HttpStatus.SC_NOT_ACCEPTABLE, ErrorNumbers.SVC_BAD_PARAMETER).cause(e)
207                                             .errorInfo(errorLoggerInfo).build();
208                     updateStatus(currentActiveReq, Status.FAILED, validateException.getMessage());
209                     throw validateException;
210                 }
211                 return builder.buildResponse(HttpStatus.SC_ACCEPTED, requestClientParameter.getRequestId(),
212                         jsonResponse, requestClientParameter.getApiVersion());
213             }
214         }
215
216         List<String> variables = new ArrayList<>();
217         variables.add(bpelStatus + "");
218         String camundaJSONResponseBody = respHandler.getResponseBody();
219         if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
220
221             ErrorLoggerInfo errorLoggerInfo =
222                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.BusinessProcessError)
223                             .errorSource(requestClient.getUrl()).build();
224             BPMNFailureException bpmnException =
225                     new BPMNFailureException.Builder(String.valueOf(bpelStatus) + camundaJSONResponseBody, bpelStatus,
226                             ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).errorInfo(errorLoggerInfo).build();
227
228             updateStatus(currentActiveReq, Status.FAILED, bpmnException.getMessage());
229
230             throw bpmnException;
231         } else {
232
233             ErrorLoggerInfo errorLoggerInfo =
234                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.BusinessProcessError)
235                             .errorSource(requestClient.getUrl()).build();
236
237
238             BPMNFailureException servException = new BPMNFailureException.Builder(String.valueOf(bpelStatus),
239                     bpelStatus, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).errorInfo(errorLoggerInfo).build();
240             updateStatus(currentActiveReq, Status.FAILED, servException.getMessage());
241
242             throw servException;
243         }
244     }
245
246
247
248     @Override
249     public void updateStatus(InfraActiveRequests aq, Status status, String errorMessage)
250             throws RequestDbFailureException {
251         if ((status == Status.FAILED) || (status == Status.COMPLETE)) {
252             aq.setStatusMessage(errorMessage);
253             aq.setProgress(new Long(100));
254             aq.setRequestStatus(status.toString());
255             Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
256             aq.setEndTime(endTimeStamp);
257             try {
258                 infraActiveRequestsClient.save(aq);
259             } catch (Exception e) {
260                 ErrorLoggerInfo errorLoggerInfo =
261                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
262                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
263                 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
264                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
265                                 .errorInfo(errorLoggerInfo).build();
266             }
267         }
268     }
269
270     public String deriveRequestScope(Actions action, ServiceInstancesRequest sir, String requestUri) {
271         if (action == Action.inPlaceSoftwareUpdate || action == Action.applyUpdatedConfig) {
272             return (ModelType.vnf.name());
273         } else if (action == Action.addMembers || action == Action.removeMembers) {
274             return (ModelType.instanceGroup.toString());
275         } else {
276             String requestScope = requestScopeFromUri(requestUri);;
277
278             if (sir.getRequestDetails() == null) {
279                 return requestScope;
280             }
281             if (sir.getRequestDetails().getModelInfo() == null) {
282                 return requestScope;
283             }
284             if (sir.getRequestDetails().getModelInfo().getModelType() == null) {
285                 return requestScope;
286             }
287             requestScope = sir.getRequestDetails().getModelInfo().getModelType().name();
288             return requestScope;
289         }
290     }
291
292
293     public void validateHeaders(ContainerRequestContext context) throws ValidationException {
294         MultivaluedMap<String, String> headers = context.getHeaders();
295         if (!headers.containsKey(ONAPLogConstants.Headers.REQUEST_ID)) {
296             throw new ValidationException(ONAPLogConstants.Headers.REQUEST_ID + " header", true);
297         }
298         if (!headers.containsKey(ONAPLogConstants.Headers.PARTNER_NAME)) {
299             throw new ValidationException(ONAPLogConstants.Headers.PARTNER_NAME + " header", true);
300         }
301         if (!headers.containsKey(REQUESTOR_ID)) {
302             throw new ValidationException(REQUESTOR_ID + " header", true);
303         }
304     }
305
306     public String getRequestUri(ContainerRequestContext context, String uriPrefix) {
307         String requestUri = context.getUriInfo().getPath();
308         String httpUrl = MDC.get(LogConstants.URI_BASE).concat(requestUri);
309         MDC.put(LogConstants.HTTP_URL, httpUrl);
310         requestUri = requestUri.substring(requestUri.indexOf(uriPrefix) + uriPrefix.length());
311         return requestUri;
312     }
313
314     public void checkForDuplicateRequests(Actions action, HashMap<String, String> instanceIdMap, String requestScope,
315             InfraActiveRequests currentActiveReq, String instanceName) throws ApiException {
316         InfraActiveRequests dup = null;
317         boolean inProgress = false;
318
319         dup = duplicateCheck(action, instanceIdMap, instanceName, requestScope, currentActiveReq);
320
321         if (dup != null) {
322             inProgress = camundaHistoryCheck(dup, currentActiveReq);
323         }
324
325         if (dup != null && inProgress) {
326             buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, instanceName, requestScope, dup);
327         }
328     }
329
330     public InfraActiveRequests duplicateCheck(Actions action, HashMap<String, String> instanceIdMap,
331             String instanceName, String requestScope, InfraActiveRequests currentActiveReq) throws ApiException {
332         InfraActiveRequests dup = null;
333         try {
334             if (!(instanceName == null && "service".equals(requestScope) && (action == Action.createInstance
335                     || action == Action.activateInstance || action == Action.assignInstance))) {
336                 dup = infraActiveRequestsClient.checkInstanceNameDuplicate(instanceIdMap, instanceName, requestScope);
337             }
338         } catch (Exception e) {
339             ErrorLoggerInfo errorLoggerInfo =
340                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_DUPLICATE_CHECK_EXC, ErrorCode.DataError)
341                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
342             RequestDbFailureException requestDbFailureException =
343                     new RequestDbFailureException.Builder("check for duplicate instance", e.toString(),
344                             HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
345                                     .errorInfo(errorLoggerInfo).build();
346             updateStatus(currentActiveReq, Status.FAILED, requestDbFailureException.getMessage());
347             throw requestDbFailureException;
348         }
349         return dup;
350     }
351
352     public boolean camundaHistoryCheck(InfraActiveRequests duplicateRecord, InfraActiveRequests currentActiveReq)
353             throws RequestDbFailureException, ContactCamundaException {
354         String requestId = duplicateRecord.getRequestId();
355         ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
356         try {
357             response = camundaRequestHandler.getCamundaProcessInstanceHistory(requestId, true, true, false);
358         } catch (RestClientException e) {
359             logger.error("Error querying Camunda for process-instance history for requestId: {}, exception: {}",
360                     requestId, e.getMessage());
361             ContactCamundaException contactCamundaException =
362                     new ContactCamundaException.Builder("process-instance", requestId, e.toString(),
363                             HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
364                                     .build();
365             updateStatus(currentActiveReq, Status.FAILED, contactCamundaException.getMessage());
366             throw contactCamundaException;
367         }
368
369         if (response.getBody().isEmpty()) {
370             updateStatus(duplicateRecord, Status.COMPLETE, "Request Completed");
371         } else {
372             return true;
373         }
374         return false;
375     }
376
377     public ServiceInstancesRequest convertJsonToServiceInstanceRequest(String requestJSON, Actions action,
378             String requestId, String requestUri) throws ApiException {
379         try {
380             ObjectMapper mapper = new ObjectMapper();
381             return mapper.readValue(requestJSON, ServiceInstancesRequest.class);
382
383         } catch (IOException e) {
384
385             ErrorLoggerInfo errorLoggerInfo =
386                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
387                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
388
389             ValidateException validateException =
390                     new ValidateException.Builder("Error mapping request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
391                             ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
392             String requestScope = requestScopeFromUri(requestUri);
393
394             msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
395                     requestScope, requestJSON);
396
397             throw validateException;
398         }
399     }
400
401     public void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Actions action,
402             String version, String requestJSON, Boolean aLaCarte, String requestId,
403             InfraActiveRequests currentActiveReq) throws ValidateException, RequestDbFailureException {
404         int reqVersion = Integer.parseInt(version.substring(1));
405         try {
406             msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
407         } catch (Exception e) {
408             logger.error("failed to parse request", e);
409             ErrorLoggerInfo errorLoggerInfo =
410                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
411                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
412             ValidateException validateException =
413                     new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
414                             ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
415
416             updateStatus(currentActiveReq, Status.FAILED, validateException.getMessage());
417
418             throw validateException;
419         }
420     }
421
422     public void buildErrorOnDuplicateRecord(InfraActiveRequests currentActiveReq, Actions action,
423             HashMap<String, String> instanceIdMap, String instanceName, String requestScope, InfraActiveRequests dup)
424             throws ApiException {
425
426         String instance = null;
427         if (instanceName != null) {
428             instance = instanceName;
429         } else {
430             instance = instanceIdMap.get(requestScope + "InstanceId");
431         }
432         ErrorLoggerInfo errorLoggerInfo =
433                 new ErrorLoggerInfo.Builder(MessageEnum.APIH_DUPLICATE_FOUND, ErrorCode.SchemaError)
434                         .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
435
436         DuplicateRequestException dupException =
437                 new DuplicateRequestException.Builder(requestScope, instance, dup.getRequestStatus(),
438                         dup.getRequestId(), HttpStatus.SC_CONFLICT, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR)
439                                 .errorInfo(errorLoggerInfo).build();
440
441         updateStatus(currentActiveReq, Status.FAILED, dupException.getMessage());
442
443         throw dupException;
444     }
445
446     @Override
447     public String getRequestId(ContainerRequestContext requestContext) throws ValidateException {
448         String requestId = null;
449         if (requestContext.getProperty("requestId") != null) {
450             requestId = requestContext.getProperty("requestId").toString();
451         }
452         if (UUIDChecker.isValidUUID(requestId)) {
453             return requestId;
454         } else {
455             ErrorLoggerInfo errorLoggerInfo =
456                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
457                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
458             ValidateException validateException =
459                     new ValidateException.Builder("Request Id " + requestId + " is not a valid UUID",
460                             HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER)
461                                     .errorInfo(errorLoggerInfo).build();
462
463             throw validateException;
464         }
465     }
466
467     public void setInstanceId(InfraActiveRequests currentActiveReq, String requestScope, String instanceId,
468             Map<String, String> instanceIdMap) {
469         if (StringUtils.isNotBlank(instanceId)) {
470             if (ModelType.service.name().equalsIgnoreCase(requestScope)) {
471                 currentActiveReq.setServiceInstanceId(instanceId);
472             } else if (ModelType.vnf.name().equalsIgnoreCase(requestScope)) {
473                 currentActiveReq.setVnfId(instanceId);
474             } else if (ModelType.vfModule.name().equalsIgnoreCase(requestScope)) {
475                 currentActiveReq.setVfModuleId(instanceId);
476             } else if (ModelType.volumeGroup.name().equalsIgnoreCase(requestScope)) {
477                 currentActiveReq.setVolumeGroupId(instanceId);
478             } else if (ModelType.network.name().equalsIgnoreCase(requestScope)) {
479                 currentActiveReq.setNetworkId(instanceId);
480             } else if (ModelType.configuration.name().equalsIgnoreCase(requestScope)) {
481                 currentActiveReq.setConfigurationId(instanceId);
482             } else if (ModelType.instanceGroup.toString().equalsIgnoreCase(requestScope)) {
483                 currentActiveReq.setInstanceGroupId(instanceId);
484             }
485         } else if (instanceIdMap != null && !instanceIdMap.isEmpty()) {
486             if (instanceIdMap.get("serviceInstanceId") != null) {
487                 currentActiveReq.setServiceInstanceId(instanceIdMap.get("serviceInstanceId"));
488             }
489             if (instanceIdMap.get("vnfInstanceId") != null) {
490                 currentActiveReq.setVnfId(instanceIdMap.get("vnfInstanceId"));
491             }
492             if (instanceIdMap.get("vfModuleInstanceId") != null) {
493                 currentActiveReq.setVfModuleId(instanceIdMap.get("vfModuleInstanceId"));
494             }
495             if (instanceIdMap.get("volumeGroupInstanceId") != null) {
496                 currentActiveReq.setVolumeGroupId(instanceIdMap.get("volumeGroupInstanceId"));
497             }
498             if (instanceIdMap.get("networkInstanceId") != null) {
499                 currentActiveReq.setNetworkId(instanceIdMap.get("networkInstanceId"));
500             }
501             if (instanceIdMap.get("configurationInstanceId") != null) {
502                 currentActiveReq.setConfigurationId(instanceIdMap.get("configurationInstanceId"));
503             }
504             if (instanceIdMap.get(CommonConstants.INSTANCE_GROUP_INSTANCE_ID) != null) {
505                 currentActiveReq.setInstanceGroupId(instanceIdMap.get(CommonConstants.INSTANCE_GROUP_INSTANCE_ID));
506             }
507             if (instanceIdMap.get("pnfName") != null) {
508                 currentActiveReq.setPnfName(instanceIdMap.get("pnfName"));
509             }
510         }
511     }
512
513     public String mapJSONtoMSOStyle(String msoRawRequest, ServiceInstancesRequest serviceInstRequest,
514             boolean isAlaCarte, Actions action) throws IOException {
515         ObjectMapper mapper = new ObjectMapper();
516         mapper.setSerializationInclusion(Include.NON_NULL);
517         if (serviceInstRequest != null) {
518             return mapper.writeValueAsString(serviceInstRequest);
519         } else {
520             return msoRawRequest;
521         }
522     }
523
524     public Optional<String> retrieveModelName(RequestParameters requestParams) {
525         String requestTestApi = null;
526         TestApi testApi = null;
527
528         if (requestParams != null) {
529             requestTestApi = requestParams.getTestApi();
530         }
531
532         if (requestTestApi == null) {
533             if (requestParams != null && requestParams.getALaCarte() != null && !requestParams.getALaCarte()) {
534                 requestTestApi = env.getProperty(CommonConstants.MACRO_TEST_API);
535             } else {
536                 requestTestApi = env.getProperty(CommonConstants.ALACARTE_TEST_API);
537             }
538         }
539
540         try {
541             testApi = TestApi.valueOf(requestTestApi);
542             return Optional.of(testApi.getModelName());
543         } catch (Exception e) {
544             logger.warn("Catching the exception on the valueOf enum call and continuing", e);
545             throw new IllegalArgumentException("Invalid TestApi is provided", e);
546         }
547     }
548
549     public String getDefaultModel(ServiceInstancesRequest sir) {
550         String defaultModel = sir.getRequestDetails().getRequestInfo().getSource() + "_DEFAULT";
551         Optional<String> oModelName = retrieveModelName(sir.getRequestDetails().getRequestParameters());
552         if (oModelName.isPresent()) {
553             defaultModel = oModelName.get();
554         }
555         return defaultModel;
556     }
557
558     public String getServiceType(String requestScope, ServiceInstancesRequest sir, Boolean aLaCarteFlag) {
559         String serviceType = null;
560         if (requestScope.equalsIgnoreCase(ModelType.service.toString())) {
561             String defaultServiceModelName = getDefaultModel(sir);
562             org.onap.so.db.catalog.beans.Service serviceRecord;
563             if (aLaCarteFlag) {
564                 serviceRecord = catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
565                 if (serviceRecord != null) {
566                     serviceType = serviceRecord.getServiceType();
567                 }
568             } else {
569                 serviceRecord =
570                         catalogDbClient.getServiceByID(sir.getRequestDetails().getModelInfo().getModelVersionId());
571                 if (serviceRecord != null) {
572                     serviceType = serviceRecord.getServiceType();
573                 } else {
574                     serviceRecord = catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
575                     if (serviceRecord != null) {
576                         serviceType = serviceRecord.getServiceType();
577                     }
578                 }
579             }
580         } else {
581             serviceType = msoRequest.getServiceInstanceType(sir, requestScope);
582         }
583         return serviceType;
584     }
585
586     protected String setServiceInstanceId(String requestScope, ServiceInstancesRequest sir) {
587         if (sir.getServiceInstanceId() != null) {
588             return sir.getServiceInstanceId();
589         } else if (requestScope.equalsIgnoreCase(ModelType.instanceGroup.toString())) {
590             RelatedInstanceList[] relatedInstances = sir.getRequestDetails().getRelatedInstanceList();
591             if (relatedInstances != null) {
592                 for (RelatedInstanceList relatedInstanceList : relatedInstances) {
593                     RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance();
594                     if (relatedInstance.getModelInfo().getModelType() == ModelType.service) {
595                         return relatedInstance.getInstanceId();
596                     }
597                 }
598             }
599         }
600         return null;
601     }
602
603     private String requestScopeFromUri(String requestUri) {
604         String requestScope;
605         if (requestUri.contains(ModelType.network.name())) {
606             requestScope = ModelType.network.name();
607         } else if (requestUri.contains(ModelType.vfModule.name())) {
608             requestScope = ModelType.vfModule.name();
609         } else if (requestUri.contains(ModelType.volumeGroup.name())) {
610             requestScope = ModelType.volumeGroup.name();
611         } else if (requestUri.contains(ModelType.configuration.name())) {
612             requestScope = ModelType.configuration.name();
613         } else if (requestUri.contains(ModelType.vnf.name())) {
614             requestScope = ModelType.vnf.name();
615         } else if (requestUri.contains(ModelType.pnf.name())) {
616             requestScope = ModelType.pnf.name();
617         } else {
618             requestScope = ModelType.service.name();
619         }
620         return requestScope;
621     }
622
623     protected InfraActiveRequests createNewRecordCopyFromInfraActiveRequest(InfraActiveRequests infraActiveRequest,
624             String requestId, Timestamp startTimeStamp, String source, String requestUri, String requestorId,
625             String originalRequestId) throws ApiException {
626         InfraActiveRequests request = new InfraActiveRequests();
627         request.setRequestId(requestId);
628         request.setStartTime(startTimeStamp);
629         request.setSource(source);
630         request.setRequestUrl(requestUri);
631         request.setProgress(new Long(5));
632         request.setRequestorId(requestorId);
633         request.setRequestStatus(Status.IN_PROGRESS.toString());
634         request.setOriginalRequestId(originalRequestId);
635         request.setLastModifiedBy(Constants.MODIFIED_BY_APIHANDLER);
636         if (infraActiveRequest != null) {
637             request.setTenantId(infraActiveRequest.getTenantId());
638             request.setRequestBody(updateRequestorIdInRequestBody(infraActiveRequest, requestorId));
639             request.setCloudRegion(infraActiveRequest.getCloudRegion());
640             request.setRequestScope(infraActiveRequest.getRequestScope());
641             request.setRequestAction(infraActiveRequest.getRequestAction());
642             setInstanceIdAndName(infraActiveRequest, request);
643         }
644         return request;
645     }
646
647     protected void setInstanceIdAndName(InfraActiveRequests infraActiveRequest,
648             InfraActiveRequests currentActiveRequest) throws ApiException {
649         String requestScope = infraActiveRequest.getRequestScope();
650         try {
651             ModelType type = ModelType.valueOf(requestScope);
652             String instanceName = type.getName(infraActiveRequest);
653             if (instanceName == null && type.equals(ModelType.vfModule)) {
654                 logger.error("vfModule for requestId: {} being resumed does not have an instanceName.",
655                         infraActiveRequest.getRequestId());
656                 ValidateException validateException = new ValidateException.Builder(
657                         "vfModule for requestId: " + infraActiveRequest.getRequestId()
658                                 + " being resumed does not have an instanceName.",
659                         HttpStatus.SC_BAD_REQUEST, ErrorNumbers.SVC_BAD_PARAMETER).build();
660                 updateStatus(currentActiveRequest, Status.FAILED, validateException.getMessage());
661                 throw validateException;
662             }
663             if (instanceName != null) {
664                 type.setName(currentActiveRequest, instanceName);
665             }
666             type.setId(currentActiveRequest, type.getId(infraActiveRequest));
667         } catch (IllegalArgumentException e) {
668             logger.error(
669                     "requestScope \"{}\" does not match a ModelType enum. Unable to set instanceId and instanceName from the original request.",
670                     requestScope);
671         }
672     }
673
674     protected Boolean getIsBaseVfModule(ModelInfo modelInfo, Actions action, String vnfType,
675             String sdcServiceModelVersion, InfraActiveRequests currentActiveReq) throws ApiException {
676         // Get VF Module-specific base module indicator
677         VfModule vfm = null;
678         String modelVersionId = modelInfo.getModelVersionId();
679         Boolean isBaseVfModule = false;
680
681         if (modelVersionId != null) {
682             vfm = catalogDbClient.getVfModuleByModelUUID(modelVersionId);
683         } else if (modelInfo.getModelInvariantId() != null && modelInfo.getModelVersion() != null) {
684             vfm = catalogDbClient.getVfModuleByModelInvariantUUIDAndModelVersion(modelInfo.getModelInvariantId(),
685                     modelInfo.getModelVersion());
686         }
687
688         if (vfm != null) {
689             if (vfm.getIsBase()) {
690                 isBaseVfModule = true;
691             }
692         } else if (action == Action.createInstance || action == Action.updateInstance) {
693             String serviceVersionText = "";
694             if (sdcServiceModelVersion != null && !sdcServiceModelVersion.isEmpty()) {
695                 serviceVersionText = " with version " + sdcServiceModelVersion;
696             }
697             String errorMessage = "VnfType " + vnfType + " and VF Module Model Name " + modelInfo.getModelName()
698                     + serviceVersionText + " not found in MSO Catalog DB";
699             ErrorLoggerInfo errorLoggerInfo =
700                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, ErrorCode.DataError)
701                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
702             VfModuleNotFoundException vfModuleException = new VfModuleNotFoundException.Builder(errorMessage,
703                     HttpStatus.SC_NOT_FOUND, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo).build();
704             updateStatus(currentActiveReq, Status.FAILED, vfModuleException.getMessage());
705             throw vfModuleException;
706         }
707         return isBaseVfModule;
708     }
709
710     protected ModelType getModelType(Actions action, ModelInfo modelInfo) {
711         if (action == Action.applyUpdatedConfig || action == Action.inPlaceSoftwareUpdate) {
712             return ModelType.vnf;
713         } else if (action == Action.addMembers || action == Action.removeMembers) {
714             return ModelType.instanceGroup;
715         } else {
716             return modelInfo.getModelType();
717         }
718     }
719
720     protected String updateRequestorIdInRequestBody(InfraActiveRequests infraActiveRequest, String newRequestorId) {
721         String requestBody = infraActiveRequest.getRequestBody();
722         return requestBody.replaceAll(
723                 "(?s)(\"requestInfo\"\\s*?:\\s*?\\{.*?\"requestorId\"\\s*?:\\s*?\")(.*?)(\"[ ]*(?:,|\\R|\\}))",
724                 "$1" + newRequestorId + "$3");
725     }
726
727     public RecipeLookupResult getServiceInstanceOrchestrationURI(ServiceInstancesRequest sir, Actions action,
728             boolean alaCarteFlag, InfraActiveRequests currentActiveReq) throws ApiException {
729         RecipeLookupResult recipeLookupResult = null;
730         // if the aLaCarte flag is set to TRUE, the API-H should choose the VID_DEFAULT recipe for the requested action
731         ModelInfo modelInfo = sir.getRequestDetails().getModelInfo();
732         // Query MSO Catalog DB
733
734         if (action == Action.applyUpdatedConfig || action == Action.inPlaceSoftwareUpdate) {
735             recipeLookupResult = getDefaultVnfUri(sir, action);
736         } else if (action == Action.addMembers || action == Action.removeMembers) {
737             recipeLookupResult = new RecipeLookupResult("/mso/async/services/WorkflowActionBB", 180);
738         } else if (modelInfo.getModelType().equals(ModelType.service)) {
739             try {
740                 recipeLookupResult = getServiceURI(sir, action, alaCarteFlag);
741             } catch (IOException e) {
742                 ErrorLoggerInfo errorLoggerInfo =
743                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
744                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
745
746
747                 ValidateException validateException =
748                         new ValidateException.Builder(e.getMessage(), HttpStatus.SC_BAD_REQUEST,
749                                 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
750
751                 updateStatus(currentActiveReq, Status.FAILED, validateException.getMessage());
752
753                 throw validateException;
754             }
755         } else if (modelInfo.getModelType().equals(ModelType.vfModule)
756                 || modelInfo.getModelType().equals(ModelType.volumeGroup)
757                 || modelInfo.getModelType().equals(ModelType.vnf)) {
758             try {
759                 recipeLookupResult = getVnfOrVfModuleUri(sir, action);
760             } catch (ValidationException e) {
761                 ErrorLoggerInfo errorLoggerInfo =
762                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
763                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
764
765
766                 ValidateException validateException =
767                         new ValidateException.Builder(e.getMessage(), HttpStatus.SC_BAD_REQUEST,
768                                 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
769
770                 updateStatus(currentActiveReq, Status.FAILED, validateException.getMessage());
771
772                 throw validateException;
773             }
774         } else if (modelInfo.getModelType().equals(ModelType.network)) {
775             try {
776                 recipeLookupResult = getNetworkUri(sir, action);
777             } catch (ValidationException e) {
778
779                 ErrorLoggerInfo errorLoggerInfo =
780                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
781                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
782
783
784                 ValidateException validateException =
785                         new ValidateException.Builder(e.getMessage(), HttpStatus.SC_BAD_REQUEST,
786                                 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
787                 updateStatus(currentActiveReq, Status.FAILED, validateException.getMessage());
788
789                 throw validateException;
790             }
791         } else if (modelInfo.getModelType().equals(ModelType.instanceGroup)) {
792             recipeLookupResult = new RecipeLookupResult("/mso/async/services/WorkflowActionBB", 180);
793         }
794
795         if (recipeLookupResult == null) {
796             ErrorLoggerInfo errorLoggerInfo =
797                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
798                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
799
800
801             RecipeNotFoundException recipeNotFoundExceptionException =
802                     new RecipeNotFoundException.Builder("Recipe could not be retrieved from catalog DB.",
803                             HttpStatus.SC_NOT_FOUND, ErrorNumbers.SVC_GENERAL_SERVICE_ERROR).errorInfo(errorLoggerInfo)
804                                     .build();
805
806             updateStatus(currentActiveReq, Status.FAILED, recipeNotFoundExceptionException.getMessage());
807             throw recipeNotFoundExceptionException;
808         }
809         return recipeLookupResult;
810     }
811
812     protected RecipeLookupResult getServiceURI(ServiceInstancesRequest servInstReq, Actions action,
813             boolean alaCarteFlag) throws IOException {
814         // SERVICE REQUEST
815         // Construct the default service name
816         // TODO need to make this a configurable property
817         String defaultServiceModelName = getDefaultModel(servInstReq);
818         RequestDetails requestDetails = servInstReq.getRequestDetails();
819         ModelInfo modelInfo = requestDetails.getModelInfo();
820         org.onap.so.db.catalog.beans.Service serviceRecord;
821         List<org.onap.so.db.catalog.beans.Service> serviceRecordList;
822         ServiceRecipe recipe = null;
823
824         if (alaCarteFlag) {
825             serviceRecord = catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
826             if (serviceRecord != null) {
827                 recipe = catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceRecord.getModelUUID(),
828                         action.toString());
829             }
830         } else {
831             serviceRecord = catalogDbClient.getServiceByID(modelInfo.getModelVersionId());
832             recipe = catalogDbClient.getFirstByServiceModelUUIDAndAction(modelInfo.getModelVersionId(),
833                     action.toString());
834             if (recipe == null) {
835                 serviceRecordList = catalogDbClient
836                         .getServiceByModelInvariantUUIDOrderByModelVersionDesc(modelInfo.getModelInvariantId());
837                 if (!serviceRecordList.isEmpty()) {
838                     for (org.onap.so.db.catalog.beans.Service record : serviceRecordList) {
839                         recipe = catalogDbClient.getFirstByServiceModelUUIDAndAction(record.getModelUUID(),
840                                 action.toString());
841                         if (recipe != null) {
842                             break;
843                         }
844                     }
845                 }
846             }
847         }
848
849         // if an aLaCarte flag was sent in the request, throw an error if the recipe was not found
850         RequestParameters reqParam = requestDetails.getRequestParameters();
851         if (reqParam != null && alaCarteFlag && recipe == null) {
852             return null;
853         } else if (!alaCarteFlag && recipe != null && Action.createInstance.equals(action)) {
854             mapToLegacyRequest(requestDetails);
855         } else if (recipe == null) { // aLaCarte wasn't sent, so we'll try the default
856             serviceRecord = catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
857             recipe = catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceRecord.getModelUUID(),
858                     action.toString());
859         }
860         if (modelInfo.getModelVersionId() == null) {
861             modelInfo.setModelVersionId(serviceRecord.getModelUUID());
862         }
863         if (recipe == null) {
864             return null;
865         }
866         return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout());
867     }
868
869     protected void mapToLegacyRequest(RequestDetails requestDetails) throws IOException {
870         RequestParameters reqParam;
871         if (requestDetails.getRequestParameters() == null) {
872             reqParam = new RequestParameters();
873         } else {
874             reqParam = requestDetails.getRequestParameters();
875         }
876         if (requestDetails.getCloudConfiguration() == null) {
877             CloudConfiguration cloudConfig = configureCloudConfig(reqParam);
878             if (cloudConfig != null) {
879                 requestDetails.setCloudConfiguration(cloudConfig);
880             }
881         }
882
883         List<Map<String, Object>> userParams = configureUserParams(reqParam);
884         if (!userParams.isEmpty()) {
885             if (reqParam == null) {
886                 requestDetails.setRequestParameters(new RequestParameters());
887             }
888             requestDetails.getRequestParameters().setUserParams(userParams);
889         }
890     }
891
892     private Service serviceMapper(Map<String, Object> params) throws IOException {
893         ObjectMapper obj = new ObjectMapper();
894         String input = obj.writeValueAsString(params.get("service"));
895         return obj.readValue(input, Service.class);
896     }
897
898     private void addUserParams(Map<String, Object> targetUserParams, List<Map<String, String>> sourceUserParams) {
899         for (Map<String, String> map : sourceUserParams) {
900             for (Map.Entry<String, String> entry : map.entrySet()) {
901                 targetUserParams.put(entry.getKey(), entry.getValue());
902             }
903         }
904     }
905
906     protected List<Map<String, Object>> configureUserParams(RequestParameters reqParams) throws IOException {
907         logger.debug("Configuring UserParams for Macro Request");
908         Map<String, Object> userParams = new HashMap<>();
909
910         for (Map<String, Object> params : reqParams.getUserParams()) {
911             if (params.containsKey("service")) {
912                 Service service = serviceMapper(params);
913
914                 addUserParams(userParams, service.getInstanceParams());
915
916                 for (Networks network : service.getResources().getNetworks()) {
917                     addUserParams(userParams, network.getInstanceParams());
918                 }
919
920                 for (Vnfs vnf : service.getResources().getVnfs()) {
921                     addUserParams(userParams, vnf.getInstanceParams());
922
923                     for (VfModules vfModule : vnf.getVfModules()) {
924                         addUserParams(userParams, vfModule.getInstanceParams());
925                     }
926                 }
927             }
928         }
929
930         return mapFlatMapToNameValue(userParams);
931     }
932
933     protected List<Map<String, Object>> mapFlatMapToNameValue(Map<String, Object> flatMap) {
934         List<Map<String, Object>> targetUserParams = new ArrayList<>();
935
936         for (Map.Entry<String, Object> map : flatMap.entrySet()) {
937             Map<String, Object> targetMap = new HashMap<>();
938             targetMap.put(NAME, map.getKey());
939             targetMap.put(VALUE, map.getValue());
940             targetUserParams.add(targetMap);
941         }
942         return targetUserParams;
943     }
944
945     protected CloudConfiguration configureCloudConfig(RequestParameters reqParams) throws IOException {
946
947         for (Map<String, Object> params : reqParams.getUserParams()) {
948             if (params.containsKey("service")) {
949                 Service service = serviceMapper(params);
950
951                 Optional<CloudConfiguration> targetConfiguration = addCloudConfig(service.getCloudConfiguration());
952
953                 if (targetConfiguration.isPresent()) {
954                     return targetConfiguration.get();
955                 } else {
956                     for (Networks network : service.getResources().getNetworks()) {
957                         targetConfiguration = addCloudConfig(network.getCloudConfiguration());
958                         if (targetConfiguration.isPresent()) {
959                             return targetConfiguration.get();
960                         }
961                     }
962
963                     for (Vnfs vnf : service.getResources().getVnfs()) {
964                         targetConfiguration = addCloudConfig(vnf.getCloudConfiguration());
965
966                         if (targetConfiguration.isPresent()) {
967                             return targetConfiguration.get();
968                         }
969
970                         for (VfModules vfModule : vnf.getVfModules()) {
971                             targetConfiguration = addCloudConfig(vfModule.getCloudConfiguration());
972
973                             if (targetConfiguration.isPresent()) {
974                                 return targetConfiguration.get();
975                             }
976                         }
977                     }
978                 }
979             }
980         }
981
982         return null;
983     }
984
985     private RecipeLookupResult getDefaultVnfUri(ServiceInstancesRequest sir, Actions action) {
986         String defaultSource = getDefaultModel(sir);
987         VnfRecipe vnfRecipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(defaultSource, action.toString());
988         if (vnfRecipe == null) {
989             return null;
990         }
991         return new RecipeLookupResult(vnfRecipe.getOrchestrationUri(), vnfRecipe.getRecipeTimeout());
992     }
993
994
995     private RecipeLookupResult getNetworkUri(ServiceInstancesRequest sir, Actions action) throws ValidationException {
996         String defaultNetworkType = getDefaultModel(sir);
997         ModelInfo modelInfo = sir.getRequestDetails().getModelInfo();
998         String modelName = modelInfo.getModelName();
999         Recipe recipe = null;
1000
1001         if (modelInfo.getModelCustomizationId() != null) {
1002             NetworkResourceCustomization networkResourceCustomization = catalogDbClient
1003                     .getNetworkResourceCustomizationByModelCustomizationUUID(modelInfo.getModelCustomizationId());
1004             if (networkResourceCustomization != null) {
1005                 NetworkResource networkResource = networkResourceCustomization.getNetworkResource();
1006                 if (networkResource != null) {
1007                     if (modelInfo.getModelVersionId() == null) {
1008                         modelInfo.setModelVersionId(networkResource.getModelUUID());
1009                     }
1010                     recipe = catalogDbClient.getFirstNetworkRecipeByModelNameAndAction(networkResource.getModelName(),
1011                             action.toString());
1012                 } else {
1013                     throw new ValidationException("no catalog entry found");
1014                 }
1015             } else if (action != Action.deleteInstance) {
1016                 throw new ValidationException("modelCustomizationId for networkResourceCustomization lookup", true);
1017             }
1018         } else {
1019             // ok for version < 3 and action delete
1020             if (modelName != null) {
1021                 recipe = catalogDbClient.getFirstNetworkRecipeByModelNameAndAction(modelName, action.toString());
1022             }
1023         }
1024
1025         if (recipe == null) {
1026             recipe = catalogDbClient.getFirstNetworkRecipeByModelNameAndAction(defaultNetworkType, action.toString());
1027         }
1028
1029         return recipe != null ? new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout()) : null;
1030     }
1031
1032
1033     private Optional<CloudConfiguration> addCloudConfig(CloudConfiguration sourceCloudConfiguration) {
1034         CloudConfiguration targetConfiguration = new CloudConfiguration();
1035         if (sourceCloudConfiguration != null) {
1036             targetConfiguration.setAicNodeClli(sourceCloudConfiguration.getAicNodeClli());
1037             targetConfiguration.setTenantId(sourceCloudConfiguration.getTenantId());
1038             targetConfiguration.setLcpCloudRegionId(sourceCloudConfiguration.getLcpCloudRegionId());
1039             targetConfiguration.setCloudOwner(sourceCloudConfiguration.getCloudOwner());
1040             return Optional.of(targetConfiguration);
1041         }
1042         return Optional.empty();
1043     }
1044
1045     private RecipeLookupResult getVnfOrVfModuleUri(ServiceInstancesRequest servInstReq, Actions action)
1046             throws ValidationException {
1047
1048         ModelInfo modelInfo = servInstReq.getRequestDetails().getModelInfo();
1049         String vnfComponentType = modelInfo.getModelType().name();
1050
1051         RelatedInstanceList[] instanceList = null;
1052         if (servInstReq.getRequestDetails() != null) {
1053             instanceList = servInstReq.getRequestDetails().getRelatedInstanceList();
1054         }
1055
1056         Recipe recipe;
1057         String defaultSource = getDefaultModel(servInstReq);
1058         String modelCustomizationId = modelInfo.getModelCustomizationId();
1059         String modelCustomizationName = modelInfo.getModelCustomizationName();
1060         String relatedInstanceModelVersionId = null;
1061         String relatedInstanceModelInvariantId = null;
1062         String relatedInstanceVersion = null;
1063         String relatedInstanceModelCustomizationName = null;
1064
1065         if (instanceList != null) {
1066
1067             for (RelatedInstanceList relatedInstanceList : instanceList) {
1068
1069                 RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance();
1070                 ModelInfo relatedInstanceModelInfo = relatedInstance.getModelInfo();
1071                 if (relatedInstanceModelInfo.getModelType().equals(ModelType.service)) {
1072                     relatedInstanceModelVersionId = relatedInstanceModelInfo.getModelVersionId();
1073                     relatedInstanceVersion = relatedInstanceModelInfo.getModelVersion();
1074                 }
1075
1076                 if (relatedInstanceModelInfo.getModelType().equals(ModelType.vnf)) {
1077                     relatedInstanceModelVersionId = relatedInstanceModelInfo.getModelVersionId();
1078                     relatedInstanceModelInvariantId = relatedInstanceModelInfo.getModelInvariantId();
1079                     relatedInstanceVersion = relatedInstanceModelInfo.getModelVersion();
1080                     relatedInstanceModelCustomizationName = relatedInstanceModelInfo.getModelCustomizationName();
1081                 }
1082             }
1083
1084             if (modelInfo.getModelType().equals(ModelType.vnf)) {
1085                 // a. For a vnf request (only create, no update currently):
1086                 // i. (v3-v4) If modelInfo.modelCustomizationId is provided, use it to validate catalog DB has record in
1087                 // vnf_resource_customization.model_customization_uuid.
1088                 // ii. (v2-v4) If modelInfo.modelCustomizationId is NOT provided (because it is a pre-1702 ASDC model or
1089                 // pre-v3), then modelInfo.modelCustomizationName must have
1090                 // been provided (else create request should be rejected). APIH should use the
1091                 // relatedInstance.modelInfo[service].modelVersionId** + modelInfo[vnf].modelCustomizationName
1092                 // to â€œjoinâ€�? service_to_resource_customizations with vnf_resource_customization to confirm a
1093                 // vnf_resource_customization.model_customization_uuid record exists.
1094                 // **If relatedInstance.modelInfo[service].modelVersionId was not provided, use
1095                 // relatedInstance.modelInfo[service].modelInvariantId + modelVersion instead to lookup modelVersionId
1096                 // (MODEL_UUID) in SERVICE table.
1097                 // iii. Regardless of how the value was provided/obtained above, APIH must always populate
1098                 // vnfModelCustomizationId in bpmnRequest. It would be assumed it was MSO generated
1099                 // during 1707 data migration if VID did not provide it originally on request.
1100                 // iv. Note: continue to construct the â€œvnf-typeâ€�? value and pass to BPMN (must still be populated
1101                 // in A&AI).
1102                 // 1. If modelCustomizationName is NOT provided on a vnf/vfModule request, use modelCustomizationId to
1103                 // look it up in our catalog to construct vnf-type value to pass to BPMN.
1104
1105                 VnfResource vnfResource = null;
1106                 VnfResourceCustomization vrc = null;
1107                 // Validation for vnfResource
1108
1109                 if (modelCustomizationId != null) {
1110                     vrc = catalogDbClient.getVnfResourceCustomizationByModelCustomizationUUID(modelCustomizationId);
1111                     if (vrc != null) {
1112                         vnfResource = vrc.getVnfResources();
1113                     }
1114                 } else {
1115                     org.onap.so.db.catalog.beans.Service service =
1116                             catalogDbClient.getServiceByID(relatedInstanceModelVersionId);
1117                     if (service == null) {
1118                         service = catalogDbClient.getServiceByModelVersionAndModelInvariantUUID(relatedInstanceVersion,
1119                                 relatedInstanceModelInvariantId);
1120                     }
1121
1122                     if (service == null) {
1123                         throw new ValidationException("service in relatedInstance");
1124                     }
1125                     for (VnfResourceCustomization vnfResourceCustom : service.getVnfCustomizations()) {
1126                         if (vnfResourceCustom.getModelInstanceName().equals(modelCustomizationName)) {
1127                             vrc = vnfResourceCustom;
1128                         }
1129                     }
1130
1131                     if (vrc != null) {
1132                         vnfResource = vrc.getVnfResources();
1133                         modelInfo.setModelCustomizationId(vrc.getModelCustomizationUUID());
1134                         modelInfo.setModelCustomizationUuid(vrc.getModelCustomizationUUID());
1135                     }
1136                 }
1137
1138                 if (vnfResource == null) {
1139                     throw new ValidationException("vnfResource");
1140                 } else {
1141                     if (modelInfo.getModelVersionId() == null) {
1142                         modelInfo.setModelVersionId(vnfResource.getModelUUID());
1143                     }
1144                 }
1145
1146                 VnfRecipe vnfRecipe = null;
1147
1148                 if (vrc != null) {
1149                     String nfRole = vrc.getNfRole();
1150                     if (nfRole != null) {
1151                         vnfRecipe =
1152                                 catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(vrc.getNfRole(), action.toString());
1153                     }
1154                 }
1155
1156                 if (vnfRecipe == null) {
1157                     vnfRecipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(defaultSource, action.toString());
1158                 }
1159
1160                 if (vnfRecipe == null) {
1161                     return null;
1162                 }
1163
1164                 return new RecipeLookupResult(vnfRecipe.getOrchestrationUri(), vnfRecipe.getRecipeTimeout());
1165             } else {
1166                 /*
1167                  * (v5-v7) If modelInfo.modelCustomizationId is NOT provided (because it is a pre-1702 ASDC model or
1168                  * pre-v3), then modelInfo.modelCustomizationName must have // been provided (else create request should
1169                  * be rejected). APIH should use the relatedInstance.modelInfo[vnf].modelVersionId +
1170                  * modelInfo[vnf].modelCustomizationName // to join vnf_to_resource_customizations with
1171                  * vf_resource_customization to confirm a vf_resource_customization.model_customization_uuid record
1172                  * exists. // Once the vnfs model_customization_uuid has been obtained, use it to find all vfModule
1173                  * customizations for that vnf customization in the vnf_res_custom_to_vf_module_custom join table. //
1174                  * For each vf_module_cust_model_customization_uuid value returned, use that UUID to query
1175                  * vf_module_customization table along with modelInfo[vfModule|volumeGroup].modelVersionId to // confirm
1176                  * record matches request data (and to identify the modelCustomizationId associated with the vfModule in
1177                  * the request). This means taking each record found // in vf_module_customization and looking up in
1178                  * vf_module (using vf_module_customization’s FK into vf_module) to find a match on
1179                  * MODEL_INVARIANT_UUID (modelInvariantId) // and MODEL_VERSION (modelVersion).
1180                  */
1181                 VfModuleCustomization vfmc = null;
1182                 VnfResource vnfr;
1183                 VnfResourceCustomization vnfrc;
1184                 VfModule vfModule = null;
1185
1186                 if (modelInfo.getModelCustomizationId() != null) {
1187                     vfmc = catalogDbClient
1188                             .getVfModuleCustomizationByModelCuztomizationUUID(modelInfo.getModelCustomizationId());
1189                 } else {
1190                     vnfr = catalogDbClient.getVnfResourceByModelUUID(relatedInstanceModelVersionId);
1191                     if (vnfr == null) {
1192                         vnfr = catalogDbClient.getFirstVnfResourceByModelInvariantUUIDAndModelVersion(
1193                                 relatedInstanceModelInvariantId, relatedInstanceVersion);
1194                     }
1195                     vnfrc = catalogDbClient.getFirstVnfResourceCustomizationByModelInstanceNameAndVnfResources(
1196                             relatedInstanceModelCustomizationName, vnfr);
1197
1198                     List<VfModuleCustomization> list = vnfrc.getVfModuleCustomizations();
1199
1200                     String vfModuleModelUUID = modelInfo.getModelVersionId();
1201                     for (VfModuleCustomization vf : list) {
1202                         VfModuleCustomization vfmCustom;
1203                         if (vfModuleModelUUID != null) {
1204                             vfmCustom = catalogDbClient
1205                                     .getVfModuleCustomizationByModelCustomizationUUIDAndVfModuleModelUUID(
1206                                             vf.getModelCustomizationUUID(), vfModuleModelUUID);
1207                             if (vfmCustom != null) {
1208                                 vfModule = vfmCustom.getVfModule();
1209                             }
1210                         } else {
1211                             vfmCustom = catalogDbClient
1212                                     .getVfModuleCustomizationByModelCuztomizationUUID(vf.getModelCustomizationUUID());
1213                             if (vfmCustom != null) {
1214                                 vfModule = vfmCustom.getVfModule();
1215                             } else {
1216                                 vfModule = catalogDbClient.getVfModuleByModelInvariantUUIDAndModelVersion(
1217                                         relatedInstanceModelInvariantId, relatedInstanceVersion);
1218                             }
1219                         }
1220
1221                         if (vfModule != null) {
1222                             modelInfo.setModelCustomizationId(vf.getModelCustomizationUUID());
1223                             modelInfo.setModelCustomizationUuid(vf.getModelCustomizationUUID());
1224                             break;
1225                         }
1226                     }
1227                 }
1228
1229                 if (vfmc == null && vfModule == null) {
1230                     throw new ValidationException("vfModuleCustomization");
1231                 } else if (vfModule == null && vfmc != null) {
1232                     vfModule = vfmc.getVfModule(); // can't be null as vfModuleModelUUID is not-null property in
1233                                                    // VfModuleCustomization table
1234                 }
1235
1236                 if (modelInfo.getModelVersionId() == null) {
1237                     modelInfo.setModelVersionId(vfModule.getModelUUID());
1238                 }
1239
1240
1241                 recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(
1242                         vfModule.getModelUUID(), vnfComponentType, action.toString());
1243                 if (recipe == null) {
1244                     List<VfModule> vfModuleRecords = catalogDbClient
1245                             .getVfModuleByModelInvariantUUIDOrderByModelVersionDesc(vfModule.getModelInvariantUUID());
1246                     if (!vfModuleRecords.isEmpty()) {
1247                         for (VfModule record : vfModuleRecords) {
1248                             recipe = catalogDbClient
1249                                     .getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(
1250                                             record.getModelUUID(), vnfComponentType, action.toString());
1251                             if (recipe != null) {
1252                                 break;
1253                             }
1254                         }
1255                     }
1256                 }
1257                 if (recipe == null) {
1258                     recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(
1259                             defaultSource, vnfComponentType, action.toString());
1260                     if (recipe == null) {
1261                         recipe = catalogDbClient.getFirstVnfComponentsRecipeByVnfComponentTypeAndAction(
1262                                 vnfComponentType, action.toString());
1263                     }
1264
1265                     if (recipe == null) {
1266                         return null;
1267                     }
1268                 }
1269             }
1270         } else {
1271
1272             if (modelInfo.getModelType().equals(ModelType.vnf)) {
1273                 recipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(defaultSource, action.toString());
1274                 if (recipe == null) {
1275                     return null;
1276                 }
1277             } else {
1278                 recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(
1279                         defaultSource, vnfComponentType, action.toString());
1280
1281                 if (recipe == null) {
1282                     return null;
1283                 }
1284             }
1285         }
1286
1287         return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout());
1288     }
1289 }