2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.apihandlerinfra;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.POST;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response;
38 import org.apache.http.HttpResponse;
39 import org.apache.http.HttpStatus;
40 import org.codehaus.jackson.map.ObjectMapper;
41 import org.openecomp.mso.apihandler.common.ErrorNumbers;
42 import org.openecomp.mso.apihandler.common.RequestClient;
43 import org.openecomp.mso.apihandler.common.RequestClientFactory;
44 import org.openecomp.mso.apihandler.common.ResponseHandler;
45 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
46 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EUserParam;
47 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ServiceInstancesRequest;
48 import org.openecomp.mso.db.catalog.CatalogDatabase;
49 import org.openecomp.mso.db.catalog.beans.Service;
50 import org.openecomp.mso.db.catalog.beans.ServiceRecipe;
51 import org.openecomp.mso.logger.MessageEnum;
52 import org.openecomp.mso.logger.MsoAlarmLogger;
53 import org.openecomp.mso.logger.MsoLogger;
54 import org.openecomp.mso.requestsdb.InfraActiveRequests;
55 import org.openecomp.mso.requestsdb.RequestsDatabase;
56 import org.openecomp.mso.utils.UUIDChecker;
59 public class E2EServiceInstances {
61 private HashMap<String, String> instanceIdMap = new HashMap<String,String>();
62 private static MsoLogger msoLogger = MsoLogger.getMsoLogger (MsoLogger.Catalog.APIH);
63 private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
64 public final static String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
66 public E2EServiceInstances() {
70 @Path("e2eServiceInstances/{version:[vV][2-3]}")
71 @Consumes(MediaType.APPLICATION_JSON)
72 @Produces(MediaType.APPLICATION_JSON)
73 public Response createE2EServiceInstance(String request, @PathParam("version") String version) {
75 Response response = E2EserviceInstances(request, Action.createInstance, null, version);
81 @Path("e2eServiceInstances/{version:[vV][2-3]}/{serviceId}")
82 @Consumes(MediaType.APPLICATION_JSON)
83 @Produces(MediaType.APPLICATION_JSON)
84 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version) {
86 Response response = E2EserviceInstances(request, Action.deleteInstance, null, version);
91 private Response E2EserviceInstances(String requestJSON, Action action,
92 HashMap<String, String> instanceIdMap, String version) {
94 String requestId = UUIDChecker.generateUUID(msoLogger);
95 long startTime = System.currentTimeMillis();
96 msoLogger.debug("requestId is: " + requestId);
97 E2EServiceInstanceRequest sir = null;
99 MsoRequest msoRequest = new MsoRequest(requestId);
100 ObjectMapper mapper = new ObjectMapper();
103 .readValue(requestJSON, E2EServiceInstanceRequest.class);
105 } catch (Exception e) {
107 msoLogger.debug("Mapping of request to JSON object failed : ", e);
108 Response response = msoRequest.buildServiceErrorResponse(
109 HttpStatus.SC_BAD_REQUEST,
110 MsoException.ServiceException,
111 "Mapping of request to JSON object failed. "
112 + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER,
114 msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR,
115 MSO_PROP_APIHANDLER_INFRA, "", "",
116 MsoLogger.ErrorCode.SchemaError, requestJSON, e);
117 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
118 MsoLogger.ResponseCode.SchemaError,
119 "Mapping of request to JSON object failed");
120 msoLogger.debug("End of the transaction, the final response is: "
121 + (String) response.getEntity());
125 InfraActiveRequests dup = null;
126 String instanceName = sir.getService().getName();
127 String requestScope = sir.getService().getParameters().getNodeType();
130 if(!(instanceName==null && requestScope.equals("service") && (action == Action.createInstance || action == Action.activateInstance))){
131 dup = (RequestsDatabase.getInstance()).checkInstanceNameDuplicate (instanceIdMap, instanceName, requestScope);
133 } catch (Exception e) {
134 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC, MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.DataError, "Error during duplicate check ", e);
136 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, MsoException.ServiceException,
138 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
142 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Error during duplicate check");
143 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
148 // Found the duplicate record. Return the appropriate error.
149 String instance = null;
150 if(instanceName != null){
151 instance = instanceName;
153 instance = instanceIdMap.get(requestScope + "InstanceId");
155 String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") " + "already has a request being worked with a status of " + dup.getRequestStatus() + " (RequestId - " + dup.getRequestId() + "). The existing request must finish or be cleaned up before proceeding.";
157 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT, MsoException.ServiceException,
159 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
163 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError, "Duplicate request - Subscriber already has a request for this service");
164 msoRequest.createRequestRecord (Status.FAILED, action);
165 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, dupMessage);
166 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
170 CatalogDatabase db = null;
172 db = CatalogDatabase.getInstance();
173 } catch (Exception e) {
174 msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
175 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
176 Response response = msoRequest.buildServiceErrorResponse (HttpStatus.SC_NOT_FOUND,
177 MsoException.ServiceException,
178 "No communication to catalog DB " + e.getMessage (),
179 ErrorNumbers.SVC_NO_SERVER_RESOURCES,
181 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
182 MsoAlarmLogger.CRITICAL,
183 Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
184 msoRequest.createRequestRecord (Status.FAILED,action);
185 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while communciate with DB");
186 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
191 RecipeLookupResult recipeLookupResult = null;
194 recipeLookupResult = getServiceInstanceOrchestrationURI(db, sir, action);
195 } catch (Exception e) {
196 msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.DataError, "Exception while querying Catalog DB", e);
197 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
198 Response response = msoRequest.buildServiceErrorResponse (HttpStatus.SC_NOT_FOUND,
199 MsoException.ServiceException,
200 "Recipe could not be retrieved from catalog DB " + e.getMessage (),
201 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR,
203 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
204 MsoAlarmLogger.CRITICAL,
205 Messages.errors.get (ErrorNumbers.ERROR_FROM_CATALOG_DB));
206 msoRequest.createRequestRecord (Status.FAILED,action);
207 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while querying Catalog DB");
208 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
220 if (recipeLookupResult == null) {
221 msoLogger.error (MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.DataError, "No recipe found in DB");
222 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
223 Response response = msoRequest.buildServiceErrorResponse (HttpStatus.SC_NOT_FOUND,
224 MsoException.ServiceException,
225 "Recipe does not exist in catalog DB",
226 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR,
228 msoRequest.createRequestRecord (Status.FAILED, action);
229 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "No recipe found in DB");
230 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
236 String modelInfo = sir.getService().getParameters().getNodeTemplateName();
237 String[] arrayOfInfo = modelInfo.split(":");
238 String serviceInstanceType = arrayOfInfo[0];
242 String serviceInstanceId = "";
244 RequestClient requestClient = null;
245 HttpResponse response = null;
247 long subStartTime = System.currentTimeMillis();
248 String sirRequestJson = mappingObtainedRequestJSONToServiceInstanceRequest(sir);
251 requestClient = RequestClientFactory.getRequestClient (recipeLookupResult.getOrchestrationURI (), MsoPropertiesUtils.loadMsoProperties ());
253 // Capture audit event
254 msoLogger.debug ("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl ());
256 response = requestClient.post(requestId, false,
257 recipeLookupResult.getRecipeTimeout(),
258 action.name(), serviceInstanceId, null, null, null, null, serviceInstanceType,
259 null, null, null, sirRequestJson);
261 msoLogger.recordMetricEvent(subStartTime,
262 MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
263 "Successfully received response from BPMN engine", "BPMN",
264 recipeLookupResult.getOrchestrationURI(), null);
265 } catch (Exception e) {
266 msoLogger.recordMetricEvent(subStartTime,
267 MsoLogger.StatusCode.ERROR,
268 MsoLogger.ResponseCode.CommunicationError,
269 "Exception while communicate with BPMN engine", "BPMN",
270 recipeLookupResult.getOrchestrationURI(), null);
271 Response resp = msoRequest.buildServiceErrorResponse(
272 HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
273 "Failed calling bpmn " + e.getMessage(),
274 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
275 alarmLogger.sendAlarm("MsoConfigurationError",
276 MsoAlarmLogger.CRITICAL,
277 Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
278 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
279 MSO_PROP_APIHANDLER_INFRA, "", "",
280 MsoLogger.ErrorCode.AvailabilityError,
281 "Exception while communicate with BPMN engine");
282 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
283 MsoLogger.ResponseCode.CommunicationError,
284 "Exception while communicate with BPMN engine");
285 msoLogger.debug("End of the transaction, the final response is: "
286 + (String) resp.getEntity());
290 if (response == null) {
291 Response resp = msoRequest.buildServiceErrorResponse(
292 HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
293 "bpelResponse is null",
294 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
295 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
296 MSO_PROP_APIHANDLER_INFRA, "", "",
297 MsoLogger.ErrorCode.BusinessProcesssError,
298 "Null response from BPEL");
299 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
300 MsoLogger.ResponseCode.InternalError,
301 "Null response from BPMN");
302 msoLogger.debug("End of the transaction, the final response is: "
303 + (String) resp.getEntity());
307 ResponseHandler respHandler = new ResponseHandler(response,
308 requestClient.getType());
309 int bpelStatus = respHandler.getStatus();
311 // BPEL accepted the request, the request is in progress
312 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
313 String camundaJSONResponseBody = respHandler.getResponseBody();
315 .debug("Received from Camunda: " + camundaJSONResponseBody);
316 (RequestsDatabase.getInstance()).updateInfraStatus(requestId,
317 Status.IN_PROGRESS.toString(),
318 Constants.PROGRESS_REQUEST_IN_PROGRESS,
319 Constants.MODIFIED_BY_APIHANDLER);
321 msoLogger.recordAuditEvent(startTime,
322 MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
323 "BPMN accepted the request, the request is in progress");
324 msoLogger.debug("End of the transaction, the final response is: "
325 + (String) camundaJSONResponseBody);
326 return Response.status(HttpStatus.SC_ACCEPTED)
327 .entity(camundaJSONResponseBody).build();
329 List<String> variables = new ArrayList<String>();
330 variables.add(bpelStatus + "");
331 String camundaJSONResponseBody = respHandler.getResponseBody();
332 if (camundaJSONResponseBody != null
333 && !camundaJSONResponseBody.isEmpty()) {
334 Response resp = msoRequest.buildServiceErrorResponse(
335 bpelStatus, MsoException.ServiceException,
336 "Request Failed due to BPEL error with HTTP Status= %1 "
337 + '\n' + camundaJSONResponseBody,
338 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
339 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
340 requestClient.getUrl(), "", "",
341 MsoLogger.ErrorCode.BusinessProcesssError,
342 "Response from BPEL engine is failed with HTTP Status="
344 msoLogger.recordAuditEvent(startTime,
345 MsoLogger.StatusCode.ERROR,
346 MsoLogger.ResponseCode.InternalError,
347 "Response from BPMN engine is failed");
349 .debug("End of the transaction, the final response is: "
350 + (String) resp.getEntity());
353 Response resp = msoRequest
354 .buildServiceErrorResponse(
356 MsoException.ServiceException,
357 "Request Failed due to BPEL error with HTTP Status= %1",
358 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
360 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
361 requestClient.getUrl(), "", "",
362 MsoLogger.ErrorCode.BusinessProcesssError,
363 "Response from BPEL engine is empty");
364 msoLogger.recordAuditEvent(startTime,
365 MsoLogger.StatusCode.ERROR,
366 MsoLogger.ResponseCode.InternalError,
367 "Response from BPEL engine is empty");
369 .debug("End of the transaction, the final response is: "
370 + (String) resp.getEntity());
376 private RecipeLookupResult getServiceInstanceOrchestrationURI(
377 CatalogDatabase db, E2EServiceInstanceRequest sir, Action action) {
379 RecipeLookupResult recipeLookupResult = null;
381 recipeLookupResult = getServiceURI(db, sir, action);
383 if (recipeLookupResult != null) {
384 msoLogger.debug ("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: " + Integer.toString(recipeLookupResult.getRecipeTimeout ()));
387 msoLogger.debug("No matching recipe record found");
389 return recipeLookupResult;
392 private RecipeLookupResult getServiceURI(CatalogDatabase db,
393 E2EServiceInstanceRequest sir, Action action) {
395 String defaultServiceModelName = "UUI_DEFAULT";
397 Service serviceRecord = null;
398 ServiceRecipe recipe = null;
400 serviceRecord = db.getServiceByModelName(defaultServiceModelName);
401 recipe = db.getServiceRecipeByModelUUID(serviceRecord.getModelUUID(), action.name());
403 if (recipe == null) {
406 return new RecipeLookupResult(recipe.getOrchestrationUri(),
407 recipe.getRecipeTimeout());
411 private String mappingObtainedRequestJSONToServiceInstanceRequest(E2EServiceInstanceRequest e2eSir){
413 ServiceInstancesRequest sir = new ServiceInstancesRequest();
415 String returnString = null;
418 sir.getRequestDetails().getModelInfo().setModelInvariantId(e2eSir.getService().getServiceDefId());
421 sir.getRequestDetails().getModelInfo().setModelNameVersionId(e2eSir.getService().getTemplateId());
423 String modelInfo = e2eSir.getService().getParameters().getNodeTemplateName();
424 String[] arrayOfInfo = modelInfo.split(":");
425 String modelName = arrayOfInfo[0];
426 String modelVersion = arrayOfInfo[0];
429 sir.getRequestDetails().getModelInfo().setModelName(modelName);
432 sir.getRequestDetails().getModelInfo().setModelVersion(modelVersion);
435 if(ModelType.service.equals(e2eSir.getService().getParameters().getNodeType())){
436 sir.getRequestDetails().getModelInfo().setModelType(ModelType.service);
439 sir.getRequestDetails().getModelInfo().getModelType();
442 sir.getRequestDetails().getSubscriberInfo().setGlobalSubscriberId(e2eSir.getService().getParameters().getGlobalSubscriberId());
445 sir.getRequestDetails().getSubscriberInfo().setSubscriberName(e2eSir.getService().getParameters().getSubscriberName());
448 sir.getRequestDetails().getRequestInfo().setInstanceName(e2eSir.getService().getName());
451 sir.getRequestDetails().getRequestInfo().setSource("UUI");
454 sir.getRequestDetails().getRequestInfo().setSuppressRollback(true);
456 //subscriptionServiceType
457 sir.getRequestDetails().getRequestParameters().setSubscriptionServiceType("MOG");
460 List<E2EUserParam> userParams = new ArrayList<>();
461 userParams = e2eSir.getService().getParameters().getRequestParameters().getUserParams();
462 List<Map<String, String>> userParamList = new ArrayList<Map<String,String>>();
463 Map<String,String> userParamMap= new HashMap<String, String>();
464 for(E2EUserParam userp: userParams){
465 userParamMap.put(userp.getName(), userp.getValue());
466 userParamList.add(userParamMap);
469 sir.getRequestDetails().getRequestParameters().setUserParams(userParamList);
471 //converting to string
472 ObjectMapper mapper = new ObjectMapper();
474 returnString = mapper.writeValueAsString(sir);
475 } catch (IOException e) {
476 msoLogger.debug("Exception while converting ServiceInstancesRequest object to string", e);