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