d3a279fd8efda45b35d7bafcb4c7d997af8b85a5
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.apihandlerinfra;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.UUID;
31 import javax.ws.rs.Consumes;
32 import javax.ws.rs.DELETE;
33 import javax.ws.rs.GET;
34 import javax.ws.rs.POST;
35 import javax.ws.rs.PUT;
36 import javax.ws.rs.Path;
37 import javax.ws.rs.PathParam;
38 import javax.ws.rs.Produces;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41 import org.onap.so.logger.LoggingAnchor;
42 import org.apache.http.HttpResponse;
43 import org.apache.http.HttpStatus;
44 import org.json.JSONObject;
45 import org.onap.so.apihandler.common.ErrorNumbers;
46 import org.onap.so.apihandler.common.RequestClient;
47 import org.onap.so.apihandler.common.RequestClientFactory;
48 import org.onap.so.apihandler.common.RequestClientParameter;
49 import org.onap.so.apihandler.common.ResponseBuilder;
50 import org.onap.so.apihandler.common.ResponseHandler;
51 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.CompareModelsRequest;
52 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
53 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
54 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceScaleRequest;
55 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
56 import org.onap.so.apihandlerinfra.exceptions.ApiException;
57 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
58 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
59 import org.onap.so.constants.Status;
60 import org.onap.so.db.catalog.beans.Service;
61 import org.onap.so.db.catalog.beans.ServiceRecipe;
62 import org.onap.so.db.catalog.client.CatalogDbClient;
63 import org.onap.so.db.request.beans.OperationStatus;
64 import org.onap.so.db.request.client.RequestsDbClient;
65 import org.onap.so.logger.ErrorCode;
66 import org.onap.so.logger.MessageEnum;
67 import org.onap.so.serviceinstancebeans.ModelInfo;
68 import org.onap.so.serviceinstancebeans.ModelType;
69 import org.onap.so.serviceinstancebeans.RequestDetails;
70 import org.onap.so.serviceinstancebeans.RequestInfo;
71 import org.onap.so.serviceinstancebeans.RequestParameters;
72 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
73 import org.onap.so.serviceinstancebeans.SubscriberInfo;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
76 import org.springframework.beans.factory.annotation.Autowired;
77 import org.springframework.stereotype.Component;
78 import com.fasterxml.jackson.databind.ObjectMapper;
79 import io.swagger.annotations.Api;
80 import io.swagger.annotations.ApiOperation;
81
82
83 @Component
84 @Path("/onap/so/infra/e2eServiceInstances")
85 @Api(value = "/onap/so/infra/e2eServiceInstances", description = "API Requests for E2E Service Instances")
86 public class E2EServiceInstances {
87
88     private HashMap<String, String> instanceIdMap = new HashMap<>();
89     private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
90
91     private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
92
93     private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
94
95     private static final String SERVICE_ID = "serviceId";
96
97     @Autowired
98     private MsoRequest msoRequest;
99
100     @Autowired
101     private RequestClientFactory requestClientFactory;
102
103     @Autowired
104     private RequestsDbClient requestsDbClient;
105
106     @Autowired
107     private CatalogDbClient catalogDbClient;
108
109     @Autowired
110     private ResponseBuilder builder;
111
112     /**
113      * POST Requests for E2E Service create Instance on a version provided
114      * 
115      * @throws ApiException
116      */
117
118     @POST
119     @Path("/{version:[vV][3-5]}")
120     @Consumes(MediaType.APPLICATION_JSON)
121     @Produces(MediaType.APPLICATION_JSON)
122     @ApiOperation(value = "Create an E2E Service Instance on a version provided", response = Response.class)
123     public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
124
125         return processE2EserviceInstances(request, Action.createInstance, null, version);
126     }
127
128     /**
129      * PUT Requests for E2E Service update Instance on a version provided
130      * 
131      * @throws ApiException
132      */
133
134     @PUT
135     @Path("/{version:[vV][3-5]}/{serviceId}")
136     @Consumes(MediaType.APPLICATION_JSON)
137     @Produces(MediaType.APPLICATION_JSON)
138     @ApiOperation(value = "Update an E2E Service Instance on a version provided and serviceId",
139             response = Response.class)
140     public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
141             @PathParam("serviceId") String serviceId) throws ApiException {
142
143         instanceIdMap.put(SERVICE_ID, serviceId);
144
145         return updateE2EserviceInstances(request, Action.updateInstance, version);
146     }
147
148     /**
149      * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
150      * 
151      * @throws ApiException
152      */
153
154     @DELETE
155     @Path("/{version:[vV][3-5]}/{serviceId}")
156     @Consumes(MediaType.APPLICATION_JSON)
157     @Produces(MediaType.APPLICATION_JSON)
158     @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
159     public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
160             @PathParam(SERVICE_ID) String serviceId) throws ApiException {
161
162         instanceIdMap.put(SERVICE_ID, serviceId);
163
164         return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
165     }
166
167     @GET
168     @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
169     @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId",
170             response = Response.class)
171     @Produces(MediaType.APPLICATION_JSON)
172     public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
173             @PathParam("version") String version, @PathParam("operationId") String operationId) {
174         return getE2EServiceInstance(serviceId, operationId, version);
175     }
176
177     /**
178      * Scale Requests for E2E Service scale Instance on a specified version
179      * 
180      * @throws ApiException
181      */
182
183     @POST
184     @Path("/{version:[vV][3-5]}/{serviceId}/scale")
185     @Consumes(MediaType.APPLICATION_JSON)
186     @Produces(MediaType.APPLICATION_JSON)
187     @ApiOperation(value = "Scale E2E Service Instance on a specified version", response = Response.class)
188     public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
189             @PathParam(SERVICE_ID) String serviceId) throws ApiException {
190
191         logger.debug("------------------scale begin------------------");
192         instanceIdMap.put(SERVICE_ID, serviceId);
193         return scaleE2EserviceInstances(request, Action.scaleInstance, version);
194     }
195
196     /**
197      * GET Requests for Comparing model of service instance with target version
198      * 
199      * @throws ApiException
200      */
201
202     @POST
203     @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
204     @Consumes(MediaType.APPLICATION_JSON)
205     @Produces(MediaType.APPLICATION_JSON)
206     @ApiOperation(
207             value = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
208             response = Response.class)
209     public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
210             @PathParam("version") String version) throws ApiException {
211
212         instanceIdMap.put(SERVICE_ID, serviceId);
213
214         return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
215     }
216
217     private Response compareModelwithTargetVersion(String requestJSON, Action action,
218             HashMap<String, String> instanceIdMap, String version) throws ApiException {
219
220         String requestId = UUID.randomUUID().toString();
221
222         CompareModelsRequest e2eCompareModelReq;
223
224         ObjectMapper mapper = new ObjectMapper();
225         try {
226             e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
227
228         } catch (Exception e) {
229
230             logger.debug("Mapping of request to JSON object failed : ", e);
231             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
232                     MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
233                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
234             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
235                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
236             logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
237
238             return response;
239         }
240
241         return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
242
243     }
244
245     private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
246             String requestId, Action action, String version) throws ApiException {
247
248         // Define RecipeLookupResult info here instead of query DB for efficiency
249         String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
250         int recipeTimeout = 180;
251
252         RequestClient requestClient;
253         HttpResponse response;
254
255         try {
256             requestClient = requestClientFactory.getRequestClient(workflowUrl);
257
258             JSONObject jjo = new JSONObject(requestJSON);
259             String bpmnRequest = jjo.toString();
260
261             // Capture audit event
262             logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
263             String serviceId = instanceIdMap.get(SERVICE_ID);
264             String serviceType = e2eCompareModelReq.getServiceType();
265             RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
266                     .setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
267                     .setServiceInstanceId(serviceId).setServiceType(serviceType).setRequestDetails(bpmnRequest)
268                     .setALaCarte(false).build();
269             response = requestClient.post(postParam);
270         } catch (Exception e) {
271             Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
272                     MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
273                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
274             logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
275                     ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
276             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
277             return resp;
278         }
279
280         if (response == null) {
281             Response resp =
282                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
283                             "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
284             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
285                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
286             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
287             return resp;
288         }
289
290         ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
291         int bpelStatus = respHandler.getStatus();
292
293         return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
294     }
295
296     private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
297
298         GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
299
300         String apiVersion = version.substring(1);
301
302         OperationStatus operationStatus;
303
304         try {
305             operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
306         } catch (Exception e) {
307             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
308                     ErrorCode.AvailabilityError.getValue(),
309                     "Exception while communciate with Request DB - Infra Request Lookup", e);
310             Response response =
311                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
312                             e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
313             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
314             return response;
315
316         }
317
318         if (operationStatus == null) {
319             Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
320                     MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
321                     ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
322             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
323                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(),
324                     "Null response from RequestDB when searching by serviceId");
325             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
326             return resp;
327
328         }
329
330         e2eServiceResponse.setOperation(operationStatus);
331
332         return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
333     }
334
335     private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
336             String version) throws ApiException {
337         // TODO should be a new one or the same service instance Id
338         E2EServiceInstanceDeleteRequest e2eDelReq;
339
340         ObjectMapper mapper = new ObjectMapper();
341         try {
342             e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
343
344         } catch (Exception e) {
345
346             logger.debug("Mapping of request to JSON object failed : ", e);
347             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
348                     MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
349                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
350             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
351                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
352             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
353             return response;
354         }
355
356         String requestId = UUID.randomUUID().toString();
357         RecipeLookupResult recipeLookupResult;
358         try {
359             // TODO Get the service template model version uuid from AAI.
360             recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
361         } catch (Exception e) {
362             logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
363                     ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
364
365             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
366                     MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
367                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
368
369             msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
370                     "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
371             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
372             return response;
373         }
374         if (recipeLookupResult == null) {
375             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
376                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
377             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
378                     MsoException.ServiceException, "Recipe does not exist in catalog DB",
379                     ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
380
381             msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
382                     ModelType.service.name(), requestJSON);
383             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
384             return response;
385         }
386
387         RequestClient requestClient;
388         HttpResponse response;
389
390         try {
391             requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
392
393             JSONObject jjo = new JSONObject(requestJSON);
394             jjo.put("operationId", requestId);
395
396             String bpmnRequest = jjo.toString();
397
398             // Capture audit event
399             logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
400             String serviceId = instanceIdMap.get(SERVICE_ID);
401             String serviceInstanceType = e2eDelReq.getServiceType();
402             RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
403                     .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
404                     .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
405                     .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
406                     .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
407             response = requestClient.post(clientParam);
408
409         } catch (Exception e) {
410             Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
411                     MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
412                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
413             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
414                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
415                     "Exception while communicate with BPMN engine");
416             logger.debug("End of the transaction, the final response is: " + resp.getEntity());
417             return resp;
418         }
419
420         if (response == null) {
421             Response resp =
422                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
423                             "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
424             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
425                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
426             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
427             return resp;
428         }
429
430         ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
431         int bpelStatus = respHandler.getStatus();
432
433         return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
434     }
435
436     private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
437
438         String requestId = UUID.randomUUID().toString();
439         E2EServiceInstanceRequest e2eSir;
440         String serviceId = instanceIdMap.get(SERVICE_ID);
441
442         ObjectMapper mapper = new ObjectMapper();
443         try {
444             e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
445
446         } catch (Exception e) {
447
448             logger.debug("Mapping of request to JSON object failed : ", e);
449             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
450                     MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
451                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
452             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
453                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
454             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
455             return response;
456         }
457
458         ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
459         sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
460         try {
461             parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
462         } catch (Exception e) {
463             logger.debug("Validation failed: ", e);
464             Response response =
465                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
466                             "Error parsing request.  " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
467             if (requestId != null) {
468                 logger.debug("Logging failed message to the database");
469             }
470             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
471                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
472             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
473             return response;
474         }
475
476         RecipeLookupResult recipeLookupResult;
477         try {
478             recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
479         } catch (Exception e) {
480             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
481                     ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
482             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
483                     MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
484                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
485
486             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
487
488             return response;
489         }
490
491         if (recipeLookupResult == null) {
492             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
493                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
494             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
495                     MsoException.ServiceException, "Recipe does not exist in catalog DB",
496                     ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
497             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
498
499             return response;
500         }
501
502         String serviceInstanceType = e2eSir.getService().getServiceType();
503
504         RequestClient requestClient;
505         HttpResponse response;
506
507         String sirRequestJson = convertToString(sir);
508
509         try {
510             requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
511
512             // Capture audit event
513             logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
514             RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
515                     .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
516                     .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
517                     .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
518                     .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
519             response = requestClient.post(postParam);
520         } catch (Exception e) {
521             logger.debug("Exception while communicate with BPMN engine", e);
522             Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
523                     MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
524                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
525
526             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
527                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
528                     "Exception while communicate with BPMN engine");
529             logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
530
531             return getBPMNResp;
532         }
533
534         if (response == null) {
535             Response getBPMNResp =
536                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
537                             "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
538             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
539                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
540             logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
541             return getBPMNResp;
542         }
543
544         ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
545         int bpelStatus = respHandler.getStatus();
546
547         return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
548     }
549
550     private Response processE2EserviceInstances(String requestJSON, Action action,
551             HashMap<String, String> instanceIdMap, String version) throws ApiException {
552
553         String requestId = UUID.randomUUID().toString();
554         E2EServiceInstanceRequest e2eSir;
555
556         MsoRequest msoRequest = new MsoRequest();
557         ObjectMapper mapper = new ObjectMapper();
558         try {
559             e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
560
561         } catch (Exception e) {
562
563             logger.debug("Mapping of request to JSON object failed : ", e);
564             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
565                     MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
566                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
567             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
568                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
569             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
570             return response;
571         }
572
573         ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
574         sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
575         try {
576             parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
577         } catch (Exception e) {
578             logger.debug("Validation failed: ", e);
579             Response response =
580                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
581                             "Error parsing request.  " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
582             if (requestId != null) {
583                 logger.debug("Logging failed message to the database");
584             }
585             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
586                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
587             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
588             return response;
589         }
590
591         RecipeLookupResult recipeLookupResult;
592         try {
593             recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
594         } catch (Exception e) {
595             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
596                     ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
597             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
598                     MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
599                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
600             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
601             return response;
602         }
603
604         if (recipeLookupResult == null) {
605             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
606                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
607             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
608                     MsoException.ServiceException, "Recipe does not exist in catalog DB",
609                     ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
610             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
611             return response;
612         }
613
614         String serviceInstanceType = e2eSir.getService().getServiceType();
615
616         String serviceId = e2eSir.getService().getServiceId();
617         RequestClient requestClient;
618         HttpResponse response;
619
620         String sirRequestJson = convertToString(sir);
621
622         try {
623             requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
624
625             // Capture audit event
626             logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
627             RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
628                     .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
629                     .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
630                     .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
631                     .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
632             response = requestClient.post(parameter);
633         } catch (Exception e) {
634             Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
635                     MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
636                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
637
638             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
639                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
640                     "Exception while communicate with BPMN engine");
641             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
642             return resp;
643         }
644
645         if (response == null) {
646             Response resp =
647                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
648                             "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
649             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
650                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
651             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
652             return resp;
653         }
654
655         ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
656         int bpelStatus = respHandler.getStatus();
657
658         return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
659     }
660
661     private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
662
663         String requestId = UUID.randomUUID().toString();
664         E2EServiceInstanceScaleRequest e2eScaleReq;
665
666         ObjectMapper mapper = new ObjectMapper();
667         try {
668             e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
669
670         } catch (Exception e) {
671
672             logger.debug("Mapping of request to JSON object failed : ", e);
673             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
674                     MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
675                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
676             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
677                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
678             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
679             return response;
680         }
681
682         RecipeLookupResult recipeLookupResult;
683         try {
684             // TODO Get the service template model version uuid from AAI.
685             recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
686         } catch (Exception e) {
687             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
688                     ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
689
690             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
691                     MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
692                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
693
694             msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
695                     "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
696             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
697             return response;
698         }
699         if (recipeLookupResult == null) {
700             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
701                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
702
703             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
704                     MsoException.ServiceException, "Recipe does not exist in catalog DB",
705                     ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
706             msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
707                     ModelType.service.name(), requestJSON);
708             logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
709             return response;
710         }
711
712         RequestClient requestClient;
713         HttpResponse response;
714
715         try {
716             requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
717
718             JSONObject jjo = new JSONObject(requestJSON);
719             jjo.put("operationId", requestId);
720
721             String bpmnRequest = jjo.toString();
722
723             // Capture audit event
724             logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
725             String serviceId = instanceIdMap.get(SERVICE_ID);
726             String serviceInstanceType = e2eScaleReq.getService().getServiceType();
727             RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
728                     .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
729                     .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
730                     .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
731                     .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
732             response = requestClient.post(postParam);
733         } catch (Exception e) {
734             Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
735                     MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
736                     ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
737
738             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
739                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
740                     "Exception while communicate with BPMN engine", e);
741             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
742             return resp;
743         }
744
745         if (response == null) {
746             Response resp =
747                     msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
748                             "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
749             logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
750                     MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
751             logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
752             return resp;
753         }
754
755         ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
756         int bpelStatus = respHandler.getStatus();
757
758         return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
759     }
760
761     private Response beplStatusUpdate(RequestClient requestClient, ResponseHandler respHandler, int bpelStatus,
762             String version) {
763
764         String apiVersion = version.substring(1);
765
766         // BPMN accepted the request, the request is in progress
767         if (bpelStatus == HttpStatus.SC_ACCEPTED) {
768             String camundaJSONResponseBody = respHandler.getResponseBody();
769             logger.debug("Received from Camunda: " + camundaJSONResponseBody);
770             logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
771             return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
772         } else {
773             List<String> variables = new ArrayList<>();
774             variables.add(bpelStatus + "");
775             String camundaJSONResponseBody = respHandler.getResponseBody();
776             if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
777                 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
778                         "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
779                         ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
780                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
781                         requestClient.getUrl(), ErrorCode.BusinessProcesssError.getValue(),
782                         "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
783                 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
784                 return resp;
785             } else {
786                 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
787                         "Request Failed due to BPEL error with HTTP Status= %1",
788                         ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
789                 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
790                         ErrorCode.BusinessProcesssError.getValue(), "Response from BPEL engine is empty");
791                 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
792                 return resp;
793             }
794         }
795     }
796
797     /**
798      * Getting recipes from catalogDb
799      * 
800      * @param serviceModelUUID the service model version uuid
801      * @param action the action for the service
802      * @return the service recipe result
803      */
804     private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
805
806         RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
807
808         if (recipeLookupResult != null) {
809             logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
810                     + Integer.toString(recipeLookupResult.getRecipeTimeout()));
811         } else {
812             logger.debug("No matching recipe record found");
813         }
814         return recipeLookupResult;
815     }
816
817     /**
818      * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
819      * 
820      * @param serviceModelUUID the service version uuid
821      * @param action the action of the service.
822      * @return the service recipe result.
823      */
824     private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
825
826         String defaultServiceModelName = "UUI_DEFAULT";
827
828         Service defaultServiceRecord =
829                 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
830         // set recipe as default generic recipe
831         ServiceRecipe recipe =
832                 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
833         // check the service special recipe
834         if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
835             ServiceRecipe serviceSpecialRecipe =
836                     catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
837             if (null != serviceSpecialRecipe) {
838                 // set service special recipe.
839                 recipe = serviceSpecialRecipe;
840             }
841         }
842
843         if (recipe == null) {
844             return null;
845         }
846         return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
847
848     }
849
850     /**
851      * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
852      * 
853      * @param e2eSir
854      * @return
855      */
856     private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
857
858         ServiceInstancesRequest sir = new ServiceInstancesRequest();
859
860         RequestDetails requestDetails = new RequestDetails();
861         ModelInfo modelInfo = new ModelInfo();
862
863         // ModelInvariantId
864         modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
865
866         // modelNameVersionId
867         modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
868
869         // String modelInfoValue =
870         // e2eSir.getService().getParameters().getNodeTemplateName();
871         // String[] arrayOfInfo = modelInfoValue.split(":");
872         // String modelName = arrayOfInfo[0];
873         // String modelVersion = arrayOfInfo[1];
874
875         // TODO: To ensure, if we dont get the values from the UUI
876         String modelName = "voLTE";
877         String modelVersion = "1.0";
878         // modelName
879         modelInfo.setModelName(modelName);
880
881         // modelVersion
882         modelInfo.setModelVersion(modelVersion);
883
884         // modelType
885         modelInfo.setModelType(ModelType.service);
886
887         // setting modelInfo to requestDetails
888         requestDetails.setModelInfo(modelInfo);
889
890         SubscriberInfo subscriberInfo = new SubscriberInfo();
891
892         // globalsubscriberId
893         subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
894
895         // setting subscriberInfo to requestDetails
896         requestDetails.setSubscriberInfo(subscriberInfo);
897
898         RequestInfo requestInfo = new RequestInfo();
899
900         // instanceName
901         requestInfo.setInstanceName(e2eSir.getService().getName());
902
903         // source
904         requestInfo.setSource("UUI");
905
906         // suppressRollback
907         requestInfo.setSuppressRollback(true);
908
909         // setting requestInfo to requestDetails
910         requestDetails.setRequestInfo(requestInfo);
911
912         RequestParameters requestParameters = new RequestParameters();
913
914         // subscriptionServiceType
915         requestParameters.setSubscriptionServiceType("MOG");
916
917
918         List<Map<String, Object>> userParamList = new ArrayList<>();
919         Map<String, Object> userParamMap = new HashMap<>();
920         // complete json request updated in the camunda
921         userParamMap.put("UUIRequest", requestJSON);
922         userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
923
924
925         userParamList.add(userParamMap);
926         requestParameters.setUserParams(userParamList);
927
928         // setting requestParameters to requestDetails
929         requestDetails.setRequestParameters(requestParameters);
930
931         sir.setRequestDetails(requestDetails);
932
933         return sir;
934     }
935
936
937     private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
938             String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
939         int reqVersion = Integer.parseInt(version.substring(1));
940         try {
941             msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
942         } catch (Exception e) {
943             ErrorLoggerInfo errorLoggerInfo =
944                     new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
945                             .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
946             ValidateException validateException =
947                     new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
948                             ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
949
950             msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
951                     ModelType.service.name(), requestJSON);
952
953             throw validateException;
954         }
955     }
956
957     private String convertToString(ServiceInstancesRequest sir) {
958         String returnString = null;
959         // converting to string
960         ObjectMapper mapper = new ObjectMapper();
961         try {
962             returnString = mapper.writeValueAsString(sir);
963         } catch (IOException e) {
964             logger.debug("Exception while converting ServiceInstancesRequest object to string", e);
965         }
966
967         return returnString;
968     }
969 }