6906f816a7cf28474ad70ccc5caab6861d348225
[so.git] / adapters / mso-vnf-adapter / src / main / java / org / openecomp / mso / adapters / vnf / VnfAdapterRest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.mso.adapters.vnf;
22
23
24 import java.util.Map;
25
26 import javax.ws.rs.Consumes;
27 import javax.ws.rs.DELETE;
28 import javax.ws.rs.GET;
29 import javax.ws.rs.HEAD;
30 import javax.ws.rs.POST;
31 import javax.ws.rs.PUT;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.QueryParam;
36 import javax.ws.rs.core.Response;
37 import javax.ws.rs.core.GenericEntity;
38 import javax.ws.rs.core.MediaType;
39 import javax.xml.ws.Holder;
40
41 import org.apache.http.HttpStatus;
42
43 import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
44 import org.openecomp.mso.cloud.CloudConfigFactory;
45 import org.openecomp.mso.entity.MsoRequest;
46 import org.openecomp.mso.logger.MessageEnum;
47 import org.openecomp.mso.logger.MsoLogger;
48 import org.openecomp.mso.openstack.beans.VnfStatus;
49 import org.openecomp.mso.openstack.beans.VnfRollback;
50 import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
51 import org.openecomp.mso.properties.MsoPropertiesFactory;
52 import org.openecomp.mso.adapters.vnfrest.*;
53
54 /**
55  * This class services calls to the REST interface for VF Modules (http://host:port/vnfs/rest/v1/vnfs)
56  * Both XML and JSON can be produced/consumed.  Set Accept: and Content-Type: headers appropriately.  XML is the default.
57  * For testing, call with cloudSiteId = ___TESTING___
58  * To test exceptions, also set tenantId = ___TESTING___
59  */
60 @Path("/v1/vnfs")
61 public class VnfAdapterRest {
62         private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
63         private static final String TESTING_KEYWORD = "___TESTING___";
64         private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
65         private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
66         private final MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
67         //TODO Logging, SkipAAI, CREATED flags, Integrate with BPEL, Auth,
68
69         @HEAD
70         @GET
71         @Path("/healthcheck")
72         @Produces(MediaType.TEXT_HTML)
73         public Response healthcheck () {
74                 String CHECK_HTML = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Health Check</title></head><body>Application ready</body></html>";
75                 return Response.ok().entity(CHECK_HTML).build();
76         }
77
78    /*
79         * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>
80         * REQUEST:
81         * {"deleteVfModuleRequest":
82                 {"cloudSiteId": "DAN",
83                 "tenantId": "214b428a1f554c02935e66330f6a5409",
84                 "vnfId": "somevnfid",
85                 "vfModuleId": "somemodid",
86                 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
87                 "messageId": "ra.1",
88                 "notificationUrl": "http://localhost:8089/vnfmock",
89                 "skipAAI": true,
90                 "msoRequest": {
91                 "requestId": "ra1",
92                 "serviceInstanceId": "sa1"
93                 }}
94                 }
95         */
96         @DELETE
97         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
98         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
99         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
100         public Response deleteVfModule (
101                 @PathParam("aaiVnfId") String aaiVnfId,
102                 @PathParam("aaiVfModuleId") String aaiVfModuleId,
103                 final DeleteVfModuleRequest req)
104         {
105                 LOGGER.debug("Delete VfModule enter: " + req.toJsonString());
106                 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
107                         LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
108                         return Response
109                                 .status(HttpStatus.SC_BAD_REQUEST)
110                                 .type(MediaType.TEXT_PLAIN)
111                                 .entity("vnfid in URL does not match content")
112                                 .build();
113                 }
114                 if (aaiVfModuleId == null || !aaiVfModuleId.equals(req.getVfModuleId())) {
115                         LOGGER.debug("Req rejected - aaiVfModuleId not provided or doesn't match URL");
116                         return Response
117                                 .status(HttpStatus.SC_BAD_REQUEST)
118                                 .type(MediaType.TEXT_PLAIN)
119                                 .entity("vfModuleId in URL does not match content")
120                                 .build();
121                 }
122                 DeleteVfModuleTask task = new DeleteVfModuleTask(req);
123                 if (req.isSynchronous()) {
124                         // This is a synchronous request
125                         task.run();
126                         return Response
127                                 .status(task.getStatusCode())
128                                 .entity(task.getGenericEntityResponse())
129                                 .build();
130                 } else {
131                         // This is an asynchronous request
132                         try {
133                                 Thread t1 = new Thread(task);
134                                 t1.start();
135                         } catch (Exception e) {
136                                 // problem handling delete, send generic failure as sync resp to caller
137                                 LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "deleteVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in deleteVfModule", e);
138                                 return Response.serverError().build();
139                         }
140                         // send sync response (ACK) to caller
141                         LOGGER.debug ("deleteVNFVolumes exit");
142                         return Response.status(HttpStatus.SC_ACCEPTED).build();
143                 }
144         }
145
146         public class DeleteVfModuleTask implements Runnable {
147                 private final DeleteVfModuleRequest req;
148                 private DeleteVfModuleResponse response = null;
149                 private VfModuleExceptionResponse eresp = null;
150                 private boolean sendxml;
151
152                 public DeleteVfModuleTask(DeleteVfModuleRequest req) {
153                         this.req = req;
154                         this.sendxml = true; // can be set with a field or header later
155                 }
156                 public int getStatusCode() {
157                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
158                 }
159                 public Object getGenericEntityResponse() {
160                         return (response != null)
161                                 ? new GenericEntity<DeleteVfModuleResponse>(response) {}
162                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
163                 }
164                 private String getResponse() {
165                         if (response != null) {
166                                 return sendxml ? response.toXmlString() : response.toJsonString();
167                         } else {
168                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
169                         }
170                 }
171
172                 @Override
173                 public void run() {
174                         try {
175                                 String cloudsite = req.getCloudSiteId();
176                                 if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
177                                         //vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
178                                         vnfAdapter.deleteVfModule (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
179                                 }
180                                 response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE, req.getMessageId());
181                         } catch (VnfException e) {
182                                 LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - Delete VNF Module", e);
183                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
184                         }
185                         if (!req.isSynchronous()) {
186                                 BpelRestClient bpelClient = new BpelRestClient();
187                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
188                         }
189                         LOGGER.debug ("Delete vfModule exit: code=" + getStatusCode() + ", resp="+ getResponse());
190                 }
191         }
192
193         /*
194          * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaiVnfId>/vf-modules/<aaiVfModuleId>?cloudSiteId=DAN&tenantId=vfModule?&skipAAI=TRUE&msoRequest.requestId=ra1&msoRequest.serviceInstanceId=si1&vfModuleName=T2N2S1
195          * RESP:
196          * {"queryVfModuleResponse": {
197                    "vfModuleId": "AvfmodId",
198                    "vfModuleOutputs": {"entry": {
199                           "key": "server_private_ip_1",
200                           "value": "10.100.1.25"
201                    }},
202                    "vfModuleStackId": "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b",
203                    "vnfId": "AvnfID",
204                    "vnfStatus": "ACTIVE"
205                 }}
206          */
207         @GET
208         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
209         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
210         public Response queryVfModule(
211                 @PathParam("aaiVnfId") String aaiVnfId,
212                 @PathParam("aaiVfModuleId") String aaiVfModuleId,
213                 @QueryParam("cloudSiteId") String cloudSiteId,
214                 @QueryParam("tenantId") String tenantId,
215                 @QueryParam("vfModuleName") String vfModuleName, //RAA? Id in doc
216                 @QueryParam("skipAAI") Boolean skipAAI,
217                 @QueryParam("msoRequest.requestId") String requestId,
218                 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId)
219         {
220                 //This request responds synchronously only
221                 LOGGER.debug ("Query vfModule enter:" + vfModuleName);
222                 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
223
224                 try {
225                         int respStatus = HttpStatus.SC_OK;
226                         QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
227                         Holder<Boolean> vnfExists = new Holder<Boolean>();
228                         Holder<String> vfModuleId = new Holder<String>();
229                         Holder<VnfStatus> status  = new Holder<VnfStatus>();
230                         Holder<Map<String, String>> outputs = new Holder <Map <String, String>> ();
231                         vnfAdapter.queryVnf (cloudSiteId, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId, status, outputs);
232                         if (!vnfExists.value) {
233                                 LOGGER.debug ("vfModule not found");
234                                 respStatus = HttpStatus.SC_NOT_FOUND;
235                         } else {
236                                 LOGGER.debug ("vfModule found" + vfModuleId.value + ", status=" + status.value);
237                                 qryResp.setVfModuleId(vfModuleId.value);
238                                 qryResp.setVnfStatus(status.value);
239                                 qryResp.setVfModuleOutputs(outputs.value);
240                         }
241                         LOGGER.debug ("Query vfModule exit");
242                         return Response
243                                 .status(respStatus)
244                                 .entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {})
245                                 .build();
246                 } catch (VnfException e) {
247                         LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR,  vfModuleName, "", "queryVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - queryVfModule", e);
248                         VfModuleExceptionResponse excResp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
249                         return Response
250                                 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
251                                 .entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {})
252                                 .build();
253                 }
254         }
255
256         /*URL: http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules
257          *REQUEST:
258          * {"createVfModuleRequest":
259                 {"cloudSiteId": "DAN",
260                 "tenantId": "214b428a1f554c02935e66330f6a5409",
261                 "vnfId": "somevnfid",
262                 "vfModuleId": "somemodid",
263                 "vfModuleName": "RaaVnf1",
264                 "vnfType": "ApacheVnf",
265                 "vfModuleParams": {"entry": [
266                         {"key": "network_id",
267                         "value": "59ed7b41-2983-413f-ba93-e7d437433916"},
268                         {"key": "subnet_id",
269                         "value": "086c9298-5c57-49b7-bb2b-6fd5730c5d92"},
270                         {"key": "server_name_0",
271                         "value": "RaaVnf1"}
272                         ]},
273                 "failIfExists": true,
274                 "messageId": "ra.1",
275                 "notificationUrl": "http://localhost:8089/vnfmock",
276                 "skipAAI": true,
277                 "msoRequest": {
278                 "requestId": "ra1",
279                 "serviceInstanceId": "sa1"
280                 }}
281                 }
282          */
283         @POST
284         @Path("{aaiVnfId}/vf-modules")
285         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
286         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
287         public Response createVfModule(
288                 @PathParam("aaiVnfId") String aaiVnfId,
289                 final CreateVfModuleRequest req)
290         {
291                 LOGGER.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
292                 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
293                         LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
294                         return Response
295                                 .status(HttpStatus.SC_BAD_REQUEST)
296                                 .type(MediaType.TEXT_PLAIN)
297                                 .entity("vnfid in URL does not match content")
298                                 .build();
299                 }
300                 CreateVfModuleTask task = new CreateVfModuleTask(req);
301                 if (req.isSynchronous()) {
302                         // This is a synchronous request
303                         task.run();
304                         return Response
305                                 .status(task.getStatusCode())
306                                 .entity(task.getGenericEntityResponse())
307                                 .build();
308                 } else {
309                         // This is an asynchronous request
310                         try {
311                                 Thread t1 = new Thread(task);
312                                 t1.start();
313                         } catch (Exception e) {
314                                 // problem handling create, send generic failure as sync resp to caller
315                                 LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, "", "createVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - createVfModule", e);
316                                 return Response.serverError().build();
317                         }
318                         // send sync response (ACK) to caller
319                         LOGGER.debug ("createVfModule exit");
320                         return Response.status(HttpStatus.SC_ACCEPTED).build();
321                 }
322         }
323
324         public class CreateVfModuleTask implements Runnable {
325                 private final CreateVfModuleRequest req;
326                 private CreateVfModuleResponse response = null;
327                 private VfModuleExceptionResponse eresp = null;
328                 private boolean sendxml;
329
330                 public CreateVfModuleTask(CreateVfModuleRequest req) {
331                         this.req = req;
332                         this.sendxml = true; // can be set with a field or header later
333                 }
334                 public int getStatusCode() {
335                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
336                 }
337                 public Object getGenericEntityResponse() {
338                         return (response != null)
339                                 ? new GenericEntity<CreateVfModuleResponse>(response) {}
340                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
341                 }
342                 private String getResponse() {
343                         if (response != null) {
344                                 return sendxml ? response.toXmlString() : response.toJsonString();
345                         } else {
346                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
347                         }
348                 }
349
350                 @Override
351                 public void run() {
352                         LOGGER.debug ("CreateVfModuleTask start");
353                         try {
354                                 // Synchronous Web Service Outputs
355                                 Holder <String> vfModuleStackId = new Holder <String> ();
356                                 Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
357                                 Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
358                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
359                                 LOGGER.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
360                                 String cloudsite = req.getCloudSiteId();
361                                 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
362                                         String tenant = req.getTenantId();
363                                         if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
364                                                 throw new VnfException("testing.");
365                                         }
366                                         vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudsite,
367                                                         true, false, new MsoRequest("reqid", "svcid"),
368                                                         req.getVolumeGroupId(), req.getVolumeGroupId(), req.getRequestType());
369                                         vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
370                                         outputs.value = VolumeAdapterRest.testMap();
371                                 } else {
372 //                                      vnfAdapter.createVnf (createReq.getCloudSiteId(),
373 //                                              createReq.getTenantId(),
374 //                                              createReq.getVnfType(),
375 //                                              createReq.getVnfVersion(),
376 //                                              createReq.getVfModuleName(),
377 //                                              createReq.getRequestType(),
378 //                                              createReq.getVolumeGroupStackId(),
379 //                                              createReq.getVfModuleParams(),
380 //                                              createReq.getFailIfExists(),
381 //                                              createReq.getBackout(),
382 //                                              createReq.getMsoRequest(),
383 //                                              vfModuleStackId,
384 //                                              outputs,
385 //                                              vnfRollback);
386                                         vnfAdapter.createVfModule(req.getCloudSiteId(),
387                                                 req.getTenantId(),
388                                                 //req.getVnfType(),
389                                                 completeVnfVfModuleType,
390                                                 req.getVnfVersion(),
391                                                 req.getVfModuleName(),
392                                                 req.getRequestType(),
393                                                 req.getVolumeGroupStackId(),
394                                                 req.getBaseVfModuleStackId(),
395                                                 req.getVfModuleParams(),
396                                                 req.getFailIfExists(),
397                                                 req.getBackout(),
398                                                 req.getMsoRequest(),
399                                                 vfModuleStackId,
400                                                 outputs,
401                                                 vnfRollback);
402                                 }
403                                 VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(), vfModuleStackId.value, req.getMessageId());
404                                 response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
405                                                 vfModuleStackId.value, Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
406                         } catch (VnfException e) {
407                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
408                         }
409                         if (!req.isSynchronous()) {
410                                 BpelRestClient bpelClient = new BpelRestClient();
411                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
412                         }
413                         LOGGER.debug ("CreateVfModuleTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
414                 }
415         }
416
417         @PUT
418         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
419         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
420         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
421         public Response updateVfModule(
422                         @PathParam("aaiVnfId") String aaiVnfId,
423                         @PathParam("aaiVfModuleId") String aaiVfModuleId,
424                         final UpdateVfModuleRequest req)
425         {
426                 LOGGER.debug("Update VfModule enter: " + req.toJsonString());
427                 UpdateVfModulesTask task = new UpdateVfModulesTask(req);
428                 if (req.isSynchronous()) {
429                         // This is a synchronous request
430                         task.run();
431                         return Response
432                                 .status(task.getStatusCode())
433                                 .entity(task.getGenericEntityResponse())
434                                 .build();
435                 } else {
436                         // This is an asynchronous request
437                 try {
438                         Thread t1 = new Thread(task);
439                         t1.start();
440                 } catch (Exception e) {
441                         // problem handling create, send generic failure as sync resp to caller
442                         LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, "", "updateVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - updateVfModule", e);
443                         return Response.serverError().build();
444                 }
445                 // send sync response (ACK) to caller
446                 LOGGER.debug ("updateVfModules exit");
447                 return Response.status(HttpStatus.SC_ACCEPTED).build();
448                 }
449         }
450
451         public class UpdateVfModulesTask implements Runnable {
452                 private final UpdateVfModuleRequest req;
453                 private UpdateVfModuleResponse response = null;
454                 private VfModuleExceptionResponse eresp = null;
455                 private boolean sendxml;
456
457                 public UpdateVfModulesTask(UpdateVfModuleRequest req) {
458                         this.req = req;
459                         this.sendxml = true; // can be set with a field or header later
460                 }
461                 public int getStatusCode() {
462                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
463                 }
464                 public Object getGenericEntityResponse() {
465                         return (response != null)
466                                 ? new GenericEntity<UpdateVfModuleResponse>(response) {}
467                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
468                 }
469                 private String getResponse() {
470                         if (response != null) {
471                                 return sendxml ? response.toXmlString() : response.toJsonString();
472                         } else {
473                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
474                         }
475                 }
476                 @Override
477                 public void run() {
478                         try {
479                                 //MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
480
481                                 // Synchronous Web Service Outputs
482                                 Holder <String> vfModuleStackId = new Holder <String> ();
483                                 Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
484                                 Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
485                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
486                                 LOGGER.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
487
488                                 /*
489                                 vnfAdapter.updateVnf (updateReq.getCloudSiteId(),
490                                                 updateReq.getTenantId(),
491                                                 updateReq.getVnfType(),
492                                                 updateReq.getVnfVersion(),
493                                                 updateReq.getVfModuleName(),
494                                                 updateReq.getRequestType(),
495                                                 updateReq.getVolumeGroupStackId(),
496                                                 updateReq.getVfModuleParams(),
497                                                 updateReq.getMsoRequest(),
498                                                 outputs,
499                                                 vnfRollback); 
500                                                 */
501                                 vnfAdapter.updateVfModule (req.getCloudSiteId(),
502                                                 req.getTenantId(),
503                                                 //req.getVnfType(),
504                                                 completeVnfVfModuleType,
505                                                 req.getVnfVersion(),
506                                                 req.getVfModuleName(),
507                                                 req.getRequestType(),
508                                                 req.getVolumeGroupStackId(),
509                                                 req.getBaseVfModuleId(),
510                                                 req.getVfModuleStackId(),
511                                                 req.getVfModuleParams(),
512                                                 req.getMsoRequest(),
513                                                 outputs,
514                                                 vnfRollback); 
515
516                                 response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
517                                                 vfModuleStackId.value, outputs.value, req.getMessageId());
518                         } catch (VnfException e) {
519                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
520                         }
521                         if (!req.isSynchronous()) {
522                                 // This is asynch, so POST response back to caller
523                                 BpelRestClient bpelClient = new BpelRestClient ();
524                                 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
525                         }
526                         LOGGER.debug ("Update VfModule exit: code=" + getStatusCode() + ", resp="+ getResponse());
527                 }
528         }
529         /*
530          * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback
531          * REQUEST:
532          * {"deleteVfModuleRequest":
533                 {"cloudSiteId": "DAN",
534                 "tenantId": "214b428a1f554c02935e66330f6a5409",
535                 "vnfId": "somevnfid",
536                 "vfModuleId": "somemodid",
537                 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
538                 "messageId": "ra.1",
539                 "notificationUrl": "http://localhost:8089/vnfmock",
540                 "skipAAI": true,
541                 "msoRequest": {
542                 "requestId": "ra1",
543                 "serviceInstanceId": "sa1"
544                 }}
545                 }
546          */
547         @DELETE
548         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
549         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
550         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
551         public Response rollbackVfModule (
552                         @PathParam("aaiVnfId") String aaiVnfId,
553                         @PathParam("aaiVfModuleId") String aaiVfModuleId,
554                         //@QueryParam("rollback") String rollback,
555                         final RollbackVfModuleRequest req)
556         {
557                 LOGGER.debug("Rollback VfModule enter: " + req.toJsonString());
558                 RollbackVfModulesTask task = new RollbackVfModulesTask(req);
559                 if (req.isSynchronous()) {
560                         // This is a synchronous request
561                         task.run();
562                         return Response
563                                 .status(task.getStatusCode())
564                                 .entity(task.getGenericEntityResponse())
565                                 .build();
566                 } else {
567                         // This is an asynchronous request
568                 try {
569                         Thread t1 = new Thread(task);
570                         t1.start();
571                 } catch (Exception e) {
572                         // problem handling create, send generic failure as sync resp to caller
573                         LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
574                         return Response.serverError().build();
575                 }
576                 // send sync response (ACK) to caller
577                 LOGGER.debug ("rollbackVfModule exit");
578                 return Response.status(HttpStatus.SC_ACCEPTED).build();
579                 }
580         }
581
582         public class RollbackVfModulesTask implements Runnable {
583                 private final RollbackVfModuleRequest req;
584                 private RollbackVfModuleResponse response = null;
585                 private VfModuleExceptionResponse eresp = null;
586                 private boolean sendxml;
587
588                 public RollbackVfModulesTask(RollbackVfModuleRequest req) {
589                         this.req = req;
590                         this.sendxml = true; // can be set with a field or header later
591                 }
592                 public int getStatusCode() {
593                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
594                 }
595                 public Object getGenericEntityResponse() {
596                         return (response != null)
597                                 ? new GenericEntity<RollbackVfModuleResponse>(response) {}
598                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
599                 }
600                 private String getResponse() {
601                         if (response != null) {
602                                 return sendxml ? response.toXmlString() : response.toJsonString();
603                         } else {
604                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
605                         }
606                 }
607                 @Override
608                 public void run() {
609                         try {
610                                 VfModuleRollback vmr = req.getVfModuleRollback();
611                                 VnfRollback vrb = new VnfRollback(
612                                                 vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudSiteId(), true, true,
613                                                 vmr.getMsoRequest(), null, null, null);
614                                 vnfAdapter.rollbackVnf (vrb);
615                                 response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
616                         } catch (VnfException e) {
617                                 LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
618                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false, req.getMessageId());
619                         }
620                         if (!req.isSynchronous()) {
621                                 // This is asynch, so POST response back to caller
622                                 BpelRestClient bpelClient = new BpelRestClient ();
623                                 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
624                         }
625                         LOGGER.debug ("RollbackVfModulesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
626                 }
627         }
628 }