cbbfdf359a496a2640a8bd137e643f3d59a20b11
[so.git] / adapters / mso-openstack-adapters / src / main / java / org / onap / so / adapters / vnf / VolumeAdapterRestV2.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (C) 2018 IBM.
8  * Modifications Copyright (c) 2019 Samsung
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.so.adapters.vnf;
25
26
27 import io.swagger.annotations.Api;
28 import io.swagger.annotations.ApiOperation;
29 import io.swagger.annotations.ApiParam;
30 import io.swagger.annotations.ApiResponse;
31 import io.swagger.annotations.ApiResponses;
32 import java.util.HashMap;
33 import java.util.Map;
34 import javax.inject.Provider;
35 import javax.ws.rs.Consumes;
36 import javax.ws.rs.DELETE;
37 import javax.ws.rs.GET;
38 import javax.ws.rs.POST;
39 import javax.ws.rs.PUT;
40 import javax.ws.rs.Path;
41 import javax.ws.rs.PathParam;
42 import javax.ws.rs.Produces;
43 import javax.ws.rs.QueryParam;
44 import javax.ws.rs.core.GenericEntity;
45 import javax.ws.rs.core.MediaType;
46 import javax.ws.rs.core.Response;
47 import javax.xml.ws.Holder;
48 import org.apache.http.HttpStatus;
49 import org.onap.so.adapters.vnf.exceptions.VnfException;
50 import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest;
51 import org.onap.so.adapters.vnfrest.CreateVolumeGroupResponse;
52 import org.onap.so.adapters.vnfrest.DeleteVolumeGroupRequest;
53 import org.onap.so.adapters.vnfrest.DeleteVolumeGroupResponse;
54 import org.onap.so.adapters.vnfrest.QueryVolumeGroupResponse;
55 import org.onap.so.adapters.vnfrest.RollbackVolumeGroupRequest;
56 import org.onap.so.adapters.vnfrest.RollbackVolumeGroupResponse;
57 import org.onap.so.adapters.vnfrest.UpdateVolumeGroupRequest;
58 import org.onap.so.adapters.vnfrest.UpdateVolumeGroupResponse;
59 import org.onap.so.adapters.vnfrest.VolumeGroupExceptionResponse;
60 import org.onap.so.adapters.vnfrest.VolumeGroupRollback;
61 import org.onap.so.entity.MsoRequest;
62 import org.onap.so.logger.ErrorCode;
63 import org.onap.so.logger.MessageEnum;
64 import org.onap.so.openstack.beans.VnfRollback;
65 import org.onap.so.openstack.beans.VnfStatus;
66 import org.onap.so.openstack.exceptions.MsoExceptionCategory;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69 import org.springframework.beans.factory.annotation.Autowired;
70 import org.springframework.stereotype.Component;
71
72 /**
73  * This class services calls to the REST interface for VNF Volumes (http://host:port/vnfs/rest/v1/volume-groups)
74  * Both XML and JSON can be produced/consumed.  Set Accept: and Content-Type: headers appropriately.  XML is the default.
75  * For testing, call with cloudSiteId = ___TESTING___
76  * To test exceptions, also set tenantId = ___TESTING___
77  *
78  * V2 incorporates run-time selection of sub-orchestrator implementation (Heat or Cloudify)
79  * based on the target cloud.
80  */
81 @Path("/v2/volume-groups")
82 @Api(value = "/v2/volume-groups", description = "root of volume-groups adapters restful web service v2")
83 @Component
84 public class VolumeAdapterRestV2 {
85
86     private static final Logger logger = LoggerFactory.getLogger(VolumeAdapterRestV2.class);
87         private static final String TESTING_KEYWORD = "___TESTING___";
88         private static final String RESP=", resp=";
89         private static final String EXCEPTION="Exception :";
90         private static final String VOLUME_GROUPID_MISSING="VolumeGroupId in URL does not match content";
91
92         @Autowired
93         private VnfAdapterRestUtils vnfAdapterRestUtils;
94
95         @Autowired
96         private Provider<BpelRestClient> bpelRestClientProvider;
97
98         @POST
99         @Path("")
100         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
101         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
102         @ApiOperation(value = "CreateVNFVolumes",
103                 response = Response.class,
104                 notes = "Create a new vnfVolume")
105         @ApiResponses({
106                 @ApiResponse(code = 200, message = "vnfVolume has been successfully created"),
107                 @ApiResponse(code = 202, message = "create vnfVolume request has been successfully accepted (async only)"),
108                 @ApiResponse(code = 500, message = "create vnfVolume failed, examine entity object for details") })
109         public Response createVNFVolumes(
110                         @ApiParam(value = "mode", required = true)
111                         @QueryParam("mode") String mode,
112                         @ApiParam(value = "CreateVolumeGroupRequest", required = true)
113                         final CreateVolumeGroupRequest req)
114         {
115       logger.debug("createVNFVolumes enter: {}", req.toJsonString());
116                 CreateVNFVolumesTask task = new CreateVNFVolumesTask(req, mode);
117                 if (req.isSynchronous()) {
118                         // This is a synchronous request
119                         task.run();
120                         return Response
121                                 .status(task.getStatusCode())
122                                 .entity(task.getGenericEntityResponse())
123                                 .build();
124                 } else {
125                         // This is an asynchronous request
126                         try {
127                                 Thread t1 = new Thread(task);
128                                 t1.start();
129                         } catch (Exception e) {
130                                 // problem handling create, send generic failure as sync resp to caller
131           logger.error("{} {} Exception - createVNFVolumes: ", MessageEnum.RA_CREATE_VNF_ERR,
132               ErrorCode.BusinessProcesssError.getValue(), e);
133                                 return Response.serverError().build();
134                         }
135                         // send sync response (ACK) to caller
136         logger.debug("createVNFVolumes exit");
137                         return Response.status(HttpStatus.SC_ACCEPTED).build();
138                 }
139         }
140
141         public class CreateVNFVolumesTask implements Runnable {
142                 private final CreateVolumeGroupRequest req;
143                 private CreateVolumeGroupResponse response = null;
144                 private VolumeGroupExceptionResponse eresp = null;
145                 private boolean sendxml;
146                 private String mode;
147
148                 public CreateVNFVolumesTask(CreateVolumeGroupRequest req, String mode) {
149                         this.req = req;
150                         this.sendxml = true; // can be set with a field or header later
151                         this.mode = mode;
152                 }
153                 public int getStatusCode() {
154                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
155                 }
156                 public Object getGenericEntityResponse() {
157                         return (response != null)
158                                 ? new GenericEntity<CreateVolumeGroupResponse>(response) {}
159                                 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
160                 }
161                 private String getResponse() {
162                         if (response != null) {
163                                 return sendxml ? response.toXmlString() : response.toJsonString();
164                         } else {
165                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
166                         }
167                 }
168                 @Override
169                 public void run() {
170         logger.debug("CreateVFModule VolumesTask start");
171                         try {
172                                 // Synchronous Web Service Outputs
173                                 Holder<String> stackId = new Holder<>();
174                                 Holder<Map<String, String>> outputs = new Holder<>();
175                                 Holder<VnfRollback> vnfRollback = new Holder<>();
176                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
177           logger.debug("in createVfModuleVolumes - completeVnfVfModuleType={}", completeVnfVfModuleType);
178
179                                 String cloudsiteId = req.getCloudSiteId();
180                                 if (cloudsiteId != null && cloudsiteId.equals(TESTING_KEYWORD)) {
181                                         String tenant = req.getTenantId();
182                                         if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
183                                                 throw new VnfException("testing.");
184                                         }
185                                         stackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
186                                         outputs.value = testMap();
187                                 } else {
188                                         // Support different Adapter Implementations
189                                         MsoVnfAdapter vnfAdapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsiteId);
190                                         vnfAdapter.createVfModule(
191                                                         req.getCloudSiteId(), //cloudSiteId,
192                                                         req.getCloudOwner(), //cloudOwner,
193                                                         req.getTenantId(), //tenantId,
194                                                         completeVnfVfModuleType, //vnfType,
195                                                         req.getVnfVersion(), //vnfVersion,
196                                                         "", // genericVnfId
197                                                         req.getVolumeGroupName(), //vnfName,
198                                                         "", // vfModuleId
199                                                         "VOLUME", //requestType,
200                                                         null, //volumeGroupHeatStackId,
201                                                         null, //baseVfHeatStackId,
202                                                         req.getModelCustomizationUuid(),
203                                                         req.getVolumeGroupParams(), //inputs,
204                                                         req.getFailIfExists(), //failIfExists,
205                                                         req.getSuppressBackout(), //backout,
206                                                         req.getEnableBridge(),
207                                                         req.getMsoRequest(), // msoRequest,
208                                                         stackId,
209                                                         outputs,
210                                                         vnfRollback);
211                                 }
212
213                                 VolumeGroupRollback rb = new VolumeGroupRollback(
214                                                 req.getVolumeGroupId(),
215                                                 stackId.value,
216                                                 vnfRollback.value.getVnfCreated(),
217                                                 req.getTenantId(),
218                         req.getCloudOwner(),
219                                                 req.getCloudSiteId(),
220                                                 req.getMsoRequest(),
221                                                 req.getMessageId());
222
223                                 response = new CreateVolumeGroupResponse(
224                                                 req.getVolumeGroupId(),
225                                                 stackId.value,
226                                                 vnfRollback.value.getVnfCreated(),
227                                                 outputs.value,
228                                                 rb,
229                                                 req.getMessageId());
230                         } catch (VnfException e) {
231           logger.debug(EXCEPTION, e);
232                                 eresp = new VolumeGroupExceptionResponse(
233                                         e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
234                         }
235                         if (!req.isSynchronous()) {
236                                 // This is asynch, so POST response back to caller
237                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
238                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
239                         }
240         logger.debug("CreateVFModule VolumesTask exit: code= {} {} {}", getStatusCode(), RESP, getResponse());
241                 }
242         }
243
244         @DELETE
245         @Path("{aaiVolumeGroupId}")
246         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
247         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
248         @ApiOperation(value = "DeleteVNFVolumes",
249                 response = Response.class,
250                 notes = "Delete an existing vnfVolume")
251         @ApiResponses({
252                 @ApiResponse(code = 200, message = "vnfVolume has been successfully deleted"),
253                 @ApiResponse(code = 202, message = "delete vnfVolume request has been successfully accepted (async only)"),
254                 @ApiResponse(code = 500, message = "delete vnfVolume failed, examine entity object for details") })
255         public Response deleteVNFVolumes(
256                 @ApiParam(value = "aaiVolumeGroupId", required = true)
257                 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
258                 @ApiParam(value = "mode", required = true)
259                 @QueryParam("mode") String mode,
260                 @ApiParam(value = "DeleteVolumeGroupRequest", required = true)
261                 final DeleteVolumeGroupRequest req
262                 )
263         {
264       logger.debug("deleteVNFVolumes enter: {}", req.toJsonString());
265                 if (aaiVolumeGroupId == null || !aaiVolumeGroupId.equals(req.getVolumeGroupId())) {
266                         return Response
267                                 .status(HttpStatus.SC_BAD_REQUEST)
268                                 .type(MediaType.TEXT_PLAIN)
269                                 .entity(VOLUME_GROUPID_MISSING)
270                                 .build();
271                 }
272                 DeleteVNFVolumesTask task = new DeleteVNFVolumesTask(req, mode);
273                 if (req.isSynchronous()) {
274                         // This is a synchronous request
275                         task.run();
276                         return Response
277                                 .status(task.getStatusCode())
278                                 .entity(task.getGenericEntityResponse())
279                                 .build();
280                 } else {
281                         // This is an asynchronous request
282                         try {
283                                 Thread t1 = new Thread(task);
284                                 t1.start();
285                         } catch (Exception e) {
286                                 // problem handling create, send generic failure as sync resp to caller
287           logger.error("{} {} Exception - deleteVNFVolumes: ", MessageEnum.RA_DELETE_VNF_ERR,
288               ErrorCode.BusinessProcesssError.getValue(), e);
289                                 return Response.serverError().build();
290                         }
291                         // send sync response (ACK) to caller
292         logger.debug("deleteVNFVolumes exit");
293                         return Response.status(HttpStatus.SC_ACCEPTED).build();
294                 }
295         }
296
297         public class DeleteVNFVolumesTask implements Runnable {
298                 private final DeleteVolumeGroupRequest req;
299                 private DeleteVolumeGroupResponse response = null;
300                 private VolumeGroupExceptionResponse eresp = null;
301                 private boolean sendxml;
302                 private String mode;
303
304                 public DeleteVNFVolumesTask(DeleteVolumeGroupRequest req, String mode) {
305                         this.req = req;
306                         this.sendxml = true; // can be set with a field or header later
307                         this.mode = mode;
308                 }
309                 public int getStatusCode() {
310                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
311                 }
312                 public Object getGenericEntityResponse() {
313                         return (response != null)
314                                 ? new GenericEntity<DeleteVolumeGroupResponse>(response) {}
315                                 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
316                 }
317                 private String getResponse() {
318                         if (response != null) {
319                                 return sendxml ? response.toXmlString() : response.toJsonString();
320                         } else {
321                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
322                         }
323                 }
324                 @Override
325                 public void run() {
326         logger.debug("DeleteVNFVolumesTask start");
327                         String cloudSiteId = req.getCloudSiteId();
328                         try {
329                                 if (! cloudSiteId.equals(TESTING_KEYWORD)) {
330                                         // Support different Adapter Implementations
331                                         MsoVnfAdapter vnfAdapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudSiteId);
332                                         vnfAdapter.deleteVnf(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(), req.getVolumeGroupStackId(), req.getMsoRequest());
333                                 }
334                                 response = new DeleteVolumeGroupResponse(true, req.getMessageId());
335                         } catch (VnfException e) {
336           logger.debug(EXCEPTION, e);
337                                 eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
338                         }
339                         if (!req.isSynchronous()) {
340                                 // This is asynch, so POST response back to caller
341                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
342                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
343                         }
344         logger.debug("DeleteVNFVolumesTask exit: code= {} {} {}", getStatusCode(), RESP, getResponse());
345                 }
346         }
347
348         @DELETE
349         @Path("{aaiVolumeGroupId}/rollback")
350         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
351         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
352         @ApiOperation(value = "RollbackVNFVolumes",
353                 response = Response.class,
354                 notes = "Delete an existing vnfVolume")
355         @ApiResponses({
356                 @ApiResponse(code = 200, message = "vnfVolume has been successfully rolled back"),
357                 @ApiResponse(code = 202, message = "rollback vnfVolume request has been successfully accepted (async only)"),
358                 @ApiResponse(code = 500, message = "rollback vnfVolume failed, examine entity object for details") })
359         public Response rollbackVNFVolumes(
360                 @ApiParam(value = "aaiVolumeGroupId", required = true)
361                 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
362                 @ApiParam(value = "RollbackVolumeGroupRequest", required = true)
363                 final RollbackVolumeGroupRequest req
364                 )
365         {
366       logger.debug("rollbackVNFVolumes enter: {}", req.toJsonString());
367                 if (aaiVolumeGroupId == null || req.getVolumeGroupRollback() == null || !aaiVolumeGroupId.equals(req.getVolumeGroupRollback().getVolumeGroupId())) {
368                         return Response
369                                 .status(HttpStatus.SC_BAD_REQUEST)
370                                 .type(MediaType.TEXT_PLAIN)
371                                 .entity(VOLUME_GROUPID_MISSING)
372                                 .build();
373                 }
374                 RollbackVNFVolumesTask task = new RollbackVNFVolumesTask(req);
375                 if (req.isSynchronous()) {
376                         // This is a synchronous request
377                         task.run();
378                         return Response
379                                 .status(task.getStatusCode())
380                                 .entity(task.getGenericEntityResponse())
381                                 .build();
382                 } else {
383                         // This is an asynchronous request
384                         try {
385                                 Thread t1 = new Thread(task);
386                                 t1.start();
387                         } catch (Exception e) {
388                                 // problem handling create, send generic failure as sync resp to caller
389           logger.error("{} {} Exception - rollbackVNFVolumes: ", MessageEnum.RA_ROLLBACK_VNF_ERR,
390               ErrorCode.BusinessProcesssError.getValue(), e);
391                                 return Response.serverError().build();
392                         }
393                         // send sync response (ACK) to caller
394         logger.debug("rollbackVNFVolumes exit");
395                         return Response.status(HttpStatus.SC_ACCEPTED).build();
396                 }
397         }
398
399         public class RollbackVNFVolumesTask implements Runnable {
400                 private final RollbackVolumeGroupRequest req;
401                 private RollbackVolumeGroupResponse response = null;
402                 private VolumeGroupExceptionResponse eresp = null;
403                 private boolean sendxml;
404
405                 public RollbackVNFVolumesTask(RollbackVolumeGroupRequest req) {
406                         this.req = req;
407                         this.sendxml = true; // can be set with a field or header later
408                 }
409                 public int getStatusCode() {
410                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
411                 }
412                 public Object getGenericEntityResponse() {
413                         return (response != null)
414                                 ? new GenericEntity<RollbackVolumeGroupResponse>(response) {}
415                                 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
416                 }
417                 private String getResponse() {
418                         if (response != null) {
419                                 return sendxml ? response.toXmlString() : response.toJsonString();
420                         } else {
421                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
422                         }
423                 }
424                 @Override
425                 public void run() {
426         logger.debug("RollbackVNFVolumesTask start");
427                         try {
428                                 VolumeGroupRollback vgr = req.getVolumeGroupRollback();
429                                 VnfRollback vrb = new VnfRollback(
430                                                 vgr.getVolumeGroupStackId(), vgr.getTenantId(), vgr.getCloudOwnerId(), vgr.getCloudSiteId(), true, true,
431                                                 vgr.getMsoRequest(), null, null, null, null);
432
433                                 // Support different Adapter Implementations
434                                 MsoVnfAdapter vnfAdapter = vnfAdapterRestUtils.getVnfAdapterImpl(vrb.getMode(), vrb.getCloudSiteId());
435                                 vnfAdapter.rollbackVnf(vrb);
436                                 response = new RollbackVolumeGroupResponse(true, req.getMessageId());
437                         } catch (VnfException e) {
438           logger.debug(EXCEPTION, e);
439                                 eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
440                         }
441                         if (!req.isSynchronous()) {
442                                 // This is asynch, so POST response back to caller
443                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
444                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
445                         }
446         logger.debug("RollbackVNFVolumesTask exit: code= {} {} {}", getStatusCode(), RESP, getResponse());
447                 }
448
449         }
450
451         @PUT
452         @Path("{aaiVolumeGroupId}")
453         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
454         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
455         @ApiOperation(value = "UpdateVNFVolumes",
456                 response = Response.class,
457                 notes = "Update an existing vnfVolume")
458         @ApiResponses({
459                 @ApiResponse(code = 200, message = "vnfVolume has been successfully updated"),
460                 @ApiResponse(code = 202, message = "update vnfVolume request has been successfully accepted (async only)"),
461                 @ApiResponse(code = 500, message = "update vnfVolume failed, examine entity object for details") })
462         public Response updateVNFVolumes(
463                 @ApiParam(value = "aaiVolumeGroupId", required = true)
464                 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
465                 @ApiParam(value = "mode", required = true)
466                 @QueryParam("mode") String mode,
467                 @ApiParam(value = "UpdateVolumeGroupRequest", required = true)
468                 final UpdateVolumeGroupRequest req
469                 )
470         {
471       logger.debug("updateVNFVolumes enter: {}", req.toJsonString());
472                 if (aaiVolumeGroupId == null || !aaiVolumeGroupId.equals(req.getVolumeGroupId())) {
473                         return Response
474                                 .status(HttpStatus.SC_BAD_REQUEST)
475                                 .type(MediaType.TEXT_PLAIN)
476                                 .entity(VOLUME_GROUPID_MISSING)
477                                 .build();
478                 }
479                 UpdateVNFVolumesTask task = new UpdateVNFVolumesTask(req, mode);
480                 if (req.isSynchronous()) {
481                         // This is a synchronous request
482                         task.run();
483                         return Response
484                                 .status(task.getStatusCode())
485                                 .entity(task.getGenericEntityResponse())
486                                 .build();
487                 } else {
488                         // This is an asynchronous request
489                 try {
490                         Thread t1 = new Thread(task);
491                         t1.start();
492                 } catch (Exception e) {
493                         // problem handling create, send generic failure as sync resp to caller
494             logger.error("{} {} Exception - updateVNFVolumes: ", MessageEnum.RA_UPDATE_VNF_ERR,
495                 ErrorCode.BusinessProcesssError.getValue(), e);
496                         return Response.serverError().build();
497                 }
498                 // send sync response (ACK) to caller
499         logger.debug("updateVNFVolumes exit");
500                 return Response.status(HttpStatus.SC_ACCEPTED).build();
501                 }
502         }
503
504         public class UpdateVNFVolumesTask implements Runnable {
505                 private final UpdateVolumeGroupRequest req;
506                 private UpdateVolumeGroupResponse response = null;
507                 private VolumeGroupExceptionResponse eresp = null;
508                 private boolean sendxml;
509                 private String mode;
510
511                 public UpdateVNFVolumesTask(UpdateVolumeGroupRequest req, String mode) {
512                         this.req = req;
513                         this.sendxml = true; // can be set with a field or header later
514                         this.mode = mode;
515                 }
516                 public int getStatusCode() {
517                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
518                 }
519                 public Object getGenericEntityResponse() {
520                         return (response != null)
521                                 ? new GenericEntity<UpdateVolumeGroupResponse>(response) {}
522                                 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
523                 }
524                 private String getResponse() {
525                         if (response != null) {
526                                 return sendxml ? response.toXmlString() : response.toJsonString();
527                         } else {
528                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
529                         }
530                 }
531                 @Override
532                 public void run() {
533         logger.debug("UpdateVNFVolumesTask start");
534                         try {
535                                 Holder<Map<String, String>> outputs = new Holder<> ();
536                                 Holder<VnfRollback> vnfRollback = new Holder<> ();
537                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
538           logger.debug("in updateVfModuleVolume - completeVnfVfModuleType={}", completeVnfVfModuleType);
539
540                                 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
541                                         outputs.value = testMap();
542                                 } else {
543                                         // Support different Adapter Implementations
544                                         MsoVnfAdapter vnfAdapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, req.getCloudSiteId());
545                                         vnfAdapter.updateVfModule (req.getCloudSiteId(),
546                                                 req.getCloudOwner(),
547                                                         req.getTenantId(),
548                                                         //req.getVnfType(),
549                                                         completeVnfVfModuleType,
550                                                         req.getVnfVersion(),
551                                                         req.getVolumeGroupStackId(),
552                                                         "VOLUME",
553                                                         null,
554                                                         null,
555                                                         req.getVolumeGroupStackId(),
556                                                         req.getModelCustomizationUuid(),
557                                                         req.getVolumeGroupParams(),
558                                                         req.getMsoRequest(),
559                                                         outputs,
560                                                         vnfRollback);
561                                 }
562                                 response = new UpdateVolumeGroupResponse(
563                                                 req.getVolumeGroupId(), req.getVolumeGroupStackId(),
564                                                 outputs.value, req.getMessageId());
565                         } catch (VnfException e) {
566           logger.debug(EXCEPTION, e);
567                                 eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
568                         }
569                         if (!req.isSynchronous()) {
570                                 // This is asynch, so POST response back to caller
571                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
572                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
573                         }
574         logger.debug("UpdateVNFVolumesTask exit: code= {} {} {}", getStatusCode(), RESP, getResponse());
575                 }
576         }
577
578         @GET
579         @Path("{aaiVolumeGroupId}")
580         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
581         @ApiOperation(value = "QueryVNFVolumes",
582                 response = Response.class,
583                 notes = "Query an existing vnfVolume")
584         @ApiResponses({
585                 @ApiResponse(code = 200, message = "vnfVolume has been successfully queried"),
586                 @ApiResponse(code = 500, message = "query vnfVolume failed, examine entity object for details") })
587         public Response queryVNFVolumes(
588                 @ApiParam(value = "aaiVolumeGroupId", required = true)
589                 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
590                 @ApiParam(value = "cloudSiteId", required = true)
591                 @QueryParam("cloudSiteId") String cloudSiteId,
592                 @ApiParam(value = "cloudOwner", required = true)
593                 @QueryParam("cloudOwner") String cloudOwner,
594                 @ApiParam(value = "tenantId", required = true)
595                 @QueryParam("tenantId") String tenantId,
596                 @ApiParam(value = "volumeGroupStackId", required = true)
597                 @QueryParam("volumeGroupStackId") String volumeGroupStackId,
598                 @ApiParam(value = "skipAAI", required = true)
599                 @QueryParam("skipAAI") Boolean skipAAI,
600                 @ApiParam(value = "msoRequest.requestId", required = true)
601                 @QueryParam("msoRequest.requestId") String requestId,
602                 @ApiParam(value = "msoRequest.serviceInstanceId", required = true)
603                 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
604                 @ApiParam(value = "mode", required = true)
605                 @QueryParam("mode") String mode
606                 )
607         {
608         //This request responds synchronously only
609       logger.debug("queryVNFVolumes enter: {} {}", aaiVolumeGroupId, volumeGroupStackId);
610         MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
611
612         try {
613                 int respStatus = HttpStatus.SC_OK;
614                 QueryVolumeGroupResponse qryResp = new QueryVolumeGroupResponse(aaiVolumeGroupId, volumeGroupStackId, null, null);
615                 Holder<Boolean> vnfExists = new Holder<>();
616                 Holder<String> vfModuleId = new Holder<>();
617                 Holder<VnfStatus> status = new Holder<>();
618                 Holder<Map<String, String>> outputs = new Holder<>();
619                         if (cloudSiteId != null && cloudSiteId.equals(TESTING_KEYWORD)) {
620                                 if (tenantId != null && tenantId.equals(TESTING_KEYWORD)) {
621                                         throw new VnfException("testing.");
622                                 }
623                                 vnfExists.value = true;
624                                 vfModuleId.value = TESTING_KEYWORD;
625                                 status.value = VnfStatus.ACTIVE;
626                                 outputs.value = testMap();
627                         } else {
628                                 // Support different Adapter Implementations
629                                 MsoVnfAdapter vnfAdapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudSiteId);
630                                 vnfAdapter.queryVnf(cloudSiteId, cloudOwner, tenantId, volumeGroupStackId, msoRequest, vnfExists, vfModuleId, status, outputs);
631                         }
632                 if (!vnfExists.value) {
633             logger.debug("VNFVolumes not found");
634                         qryResp.setVolumeGroupStatus(status.value);
635                         respStatus = HttpStatus.SC_NOT_FOUND;
636                 } else {
637             logger.debug("VNFVolumes found {}, status={}", vfModuleId.value, status.value);
638                         qryResp.setVolumeGroupStatus(status.value);
639                         qryResp.setVolumeGroupOutputs(outputs.value);
640                 }
641           logger.debug("Query queryVNFVolumes exit");
642                 return Response
643                         .status(respStatus)
644                         .entity(new GenericEntity<QueryVolumeGroupResponse>(qryResp) {})
645                         .build();
646         } catch (VnfException e) {
647           logger.error("{} {} AaiVolumeGroupId: {} VnfException - queryVNFVolumes: ", MessageEnum.RA_QUERY_VNF_ERR,
648               ErrorCode.BusinessProcesssError.getValue(), aaiVolumeGroupId, e);
649                 VolumeGroupExceptionResponse excResp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
650           logger.debug("Query queryVNFVolumes exit");
651                 return Response
652                         .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
653                         .entity(new GenericEntity<VolumeGroupExceptionResponse>(excResp) {})
654                         .build();
655                 }
656         }
657     public static Map<String, String> testMap() {
658                 Map<String, String> m = new HashMap<>();
659                 m.put("mickey", "7");
660                 m.put("clyde", "10");
661                 m.put("wayne", "99");
662                 return m;
663     }
664 }