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