Change the header to SO
[so.git] / adapters / mso-vnf-adapter / src / main / java / org / openecomp / mso / adapters / vnf / VnfAdapterRest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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                                 Holder<Map<String, String>> outputs = new Holder <Map <String, String>> ();
177                                 if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
178                                         //vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
179                                         vnfAdapter.deleteVfModule (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest(), outputs);
180                                 }
181                                 response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE, req.getMessageId(), outputs.value);
182                         } catch (VnfException e) {
183                                 LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - Delete VNF Module", e);
184                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
185                         }
186                         if (!req.isSynchronous()) {
187                                 BpelRestClient bpelClient = new BpelRestClient();
188                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
189                         }
190                         LOGGER.debug ("Delete vfModule exit: code=" + getStatusCode() + ", resp="+ getResponse());
191                 }
192         }
193
194         /*
195          * 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
196          * RESP:
197          * {"queryVfModuleResponse": {
198                    "vfModuleId": "AvfmodId",
199                    "vfModuleOutputs": {"entry": {
200                           "key": "server_private_ip_1",
201                           "value": "10.100.1.25"
202                    }},
203                    "vfModuleStackId": "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b",
204                    "vnfId": "AvnfID",
205                    "vnfStatus": "ACTIVE"
206                 }}
207          */
208         @GET
209         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
210         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
211         public Response queryVfModule(
212                 @PathParam("aaiVnfId") String aaiVnfId,
213                 @PathParam("aaiVfModuleId") String aaiVfModuleId,
214                 @QueryParam("cloudSiteId") String cloudSiteId,
215                 @QueryParam("tenantId") String tenantId,
216                 @QueryParam("vfModuleName") String vfModuleName, //RAA? Id in doc
217                 @QueryParam("skipAAI") Boolean skipAAI,
218                 @QueryParam("msoRequest.requestId") String requestId,
219                 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId)
220         {
221                 //This request responds synchronously only
222                 LOGGER.debug ("Query vfModule enter:" + vfModuleName);
223                 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
224
225                 try {
226                         int respStatus = HttpStatus.SC_OK;
227                         QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
228                         Holder<Boolean> vnfExists = new Holder<Boolean>();
229                         Holder<String> vfModuleId = new Holder<String>();
230                         Holder<VnfStatus> status  = new Holder<VnfStatus>();
231                         Holder<Map<String, String>> outputs = new Holder <Map <String, String>> ();
232                         vnfAdapter.queryVnf (cloudSiteId, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId, status, outputs);
233                         if (!vnfExists.value) {
234                                 LOGGER.debug ("vfModule not found");
235                                 respStatus = HttpStatus.SC_NOT_FOUND;
236                         } else {
237                                 LOGGER.debug ("vfModule found" + vfModuleId.value + ", status=" + status.value);
238                                 qryResp.setVfModuleId(vfModuleId.value);
239                                 qryResp.setVnfStatus(status.value);
240                                 qryResp.setVfModuleOutputs(outputs.value);
241                         }
242                         LOGGER.debug ("Query vfModule exit");
243                         return Response
244                                 .status(respStatus)
245                                 .entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {})
246                                 .build();
247                 } catch (VnfException e) {
248                         LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR,  vfModuleName, "", "queryVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - queryVfModule", e);
249                         VfModuleExceptionResponse excResp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
250                         return Response
251                                 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
252                                 .entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {})
253                                 .build();
254                 }
255         }
256
257         /*URL: http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules
258          *REQUEST:
259          * {"createVfModuleRequest":
260                 {"cloudSiteId": "DAN",
261                 "tenantId": "214b428a1f554c02935e66330f6a5409",
262                 "vnfId": "somevnfid",
263                 "vfModuleId": "somemodid",
264                 "vfModuleName": "RaaVnf1",
265                 "vnfType": "ApacheVnf",
266                 "vfModuleParams": {"entry": [
267                         {"key": "network_id",
268                         "value": "59ed7b41-2983-413f-ba93-e7d437433916"},
269                         {"key": "subnet_id",
270                         "value": "086c9298-5c57-49b7-bb2b-6fd5730c5d92"},
271                         {"key": "server_name_0",
272                         "value": "RaaVnf1"}
273                         ]},
274                 "failIfExists": true,
275                 "messageId": "ra.1",
276                 "notificationUrl": "http://localhost:8089/vnfmock",
277                 "skipAAI": true,
278                 "msoRequest": {
279                 "requestId": "ra1",
280                 "serviceInstanceId": "sa1"
281                 }}
282                 }
283          */
284         @POST
285         @Path("{aaiVnfId}/vf-modules")
286         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
287         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
288         public Response createVfModule(
289                 @PathParam("aaiVnfId") String aaiVnfId,
290                 final CreateVfModuleRequest req)
291         {
292                 LOGGER.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
293                 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
294                         LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
295                         return Response
296                                 .status(HttpStatus.SC_BAD_REQUEST)
297                                 .type(MediaType.TEXT_PLAIN)
298                                 .entity("vnfid in URL does not match content")
299                                 .build();
300                 }
301                 CreateVfModuleTask task = new CreateVfModuleTask(req);
302                 if (req.isSynchronous()) {
303                         // This is a synchronous request
304                         task.run();
305                         return Response
306                                 .status(task.getStatusCode())
307                                 .entity(task.getGenericEntityResponse())
308                                 .build();
309                 } else {
310                         // This is an asynchronous request
311                         try {
312                                 Thread t1 = new Thread(task);
313                                 t1.start();
314                         } catch (Exception e) {
315                                 // problem handling create, send generic failure as sync resp to caller
316                                 LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, "", "createVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - createVfModule", e);
317                                 return Response.serverError().build();
318                         }
319                         // send sync response (ACK) to caller
320                         LOGGER.debug ("createVfModule exit");
321                         return Response.status(HttpStatus.SC_ACCEPTED).build();
322                 }
323         }
324
325         public class CreateVfModuleTask implements Runnable {
326                 private final CreateVfModuleRequest req;
327                 private CreateVfModuleResponse response = null;
328                 private VfModuleExceptionResponse eresp = null;
329                 private boolean sendxml;
330
331                 public CreateVfModuleTask(CreateVfModuleRequest req) {
332                         this.req = req;
333                         this.sendxml = true; // can be set with a field or header later
334                 }
335                 public int getStatusCode() {
336                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
337                 }
338                 public Object getGenericEntityResponse() {
339                         return (response != null)
340                                 ? new GenericEntity<CreateVfModuleResponse>(response) {}
341                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
342                 }
343                 private String getResponse() {
344                         if (response != null) {
345                                 return sendxml ? response.toXmlString() : response.toJsonString();
346                         } else {
347                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
348                         }
349                 }
350
351                 @Override
352                 public void run() {
353                         LOGGER.debug ("CreateVfModuleTask start");
354                         try {
355                                 // Synchronous Web Service Outputs
356                                 Holder <String> vfModuleStackId = new Holder <String> ();
357                                 Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
358                                 Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
359                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
360                                 LOGGER.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
361                                 String cloudsite = req.getCloudSiteId();
362                                 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
363                                         String tenant = req.getTenantId();
364                                         if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
365                                                 throw new VnfException("testing.");
366                                         }
367                                         vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudsite,
368                                                         true, false, new MsoRequest("reqid", "svcid"),
369                                                         req.getVolumeGroupId(), req.getVolumeGroupId(), req.getRequestType(), req.getModelCustomizationUuid());
370                                         vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
371                                         outputs.value = VolumeAdapterRest.testMap();
372                                 } else {
373 //                                      vnfAdapter.createVnf (createReq.getCloudSiteId(),
374 //                                              createReq.getTenantId(),
375 //                                              createReq.getVnfType(),
376 //                                              createReq.getVnfVersion(),
377 //                                              createReq.getVfModuleName(),
378 //                                              createReq.getRequestType(),
379 //                                              createReq.getVolumeGroupStackId(),
380 //                                              createReq.getVfModuleParams(),
381 //                                              createReq.getFailIfExists(),
382 //                                              createReq.getBackout(),
383 //                                              createReq.getMsoRequest(),
384 //                                              vfModuleStackId,
385 //                                              outputs,
386 //                                              vnfRollback);
387                                         vnfAdapter.createVfModule(req.getCloudSiteId(),
388                                                 req.getTenantId(),
389                                                 //req.getVnfType(),
390                                                 completeVnfVfModuleType,
391                                                 req.getVnfVersion(),
392                                                 req.getVfModuleName(),
393                                                 req.getRequestType(),
394                                                 req.getVolumeGroupStackId(),
395                                                 req.getBaseVfModuleStackId(),
396                                                 req.getModelCustomizationUuid(),
397                                                 req.getVfModuleParams(),
398                                                 req.getFailIfExists(),
399                                                 req.getBackout(),
400                                                 req.getMsoRequest(),
401                                                 vfModuleStackId,
402                                                 outputs,
403                                                 vnfRollback);
404                                 }
405                                 VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(), vfModuleStackId.value, req.getMessageId());
406                                 response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
407                                                 vfModuleStackId.value, Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
408                         } catch (VnfException e) {
409                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
410                         }
411                         if (!req.isSynchronous()) {
412                                 BpelRestClient bpelClient = new BpelRestClient();
413                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
414                         }
415                         LOGGER.debug ("CreateVfModuleTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
416                 }
417         }
418
419         @PUT
420         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
421         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
422         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
423         public Response updateVfModule(
424                         @PathParam("aaiVnfId") String aaiVnfId,
425                         @PathParam("aaiVfModuleId") String aaiVfModuleId,
426                         final UpdateVfModuleRequest req)
427         {
428                 LOGGER.debug("Update VfModule enter: " + req.toJsonString());
429                 UpdateVfModulesTask task = new UpdateVfModulesTask(req);
430                 if (req.isSynchronous()) {
431                         // This is a synchronous request
432                         task.run();
433                         return Response
434                                 .status(task.getStatusCode())
435                                 .entity(task.getGenericEntityResponse())
436                                 .build();
437                 } else {
438                         // This is an asynchronous request
439                 try {
440                         Thread t1 = new Thread(task);
441                         t1.start();
442                 } catch (Exception e) {
443                         // problem handling create, send generic failure as sync resp to caller
444                         LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, "", "updateVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - updateVfModule", e);
445                         return Response.serverError().build();
446                 }
447                 // send sync response (ACK) to caller
448                 LOGGER.debug ("updateVfModules exit");
449                 return Response.status(HttpStatus.SC_ACCEPTED).build();
450                 }
451         }
452
453         public class UpdateVfModulesTask implements Runnable {
454                 private final UpdateVfModuleRequest req;
455                 private UpdateVfModuleResponse response = null;
456                 private VfModuleExceptionResponse eresp = null;
457                 private boolean sendxml;
458
459                 public UpdateVfModulesTask(UpdateVfModuleRequest req) {
460                         this.req = req;
461                         this.sendxml = true; // can be set with a field or header later
462                 }
463                 public int getStatusCode() {
464                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
465                 }
466                 public Object getGenericEntityResponse() {
467                         return (response != null)
468                                 ? new GenericEntity<UpdateVfModuleResponse>(response) {}
469                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
470                 }
471                 private String getResponse() {
472                         if (response != null) {
473                                 return sendxml ? response.toXmlString() : response.toJsonString();
474                         } else {
475                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
476                         }
477                 }
478                 @Override
479                 public void run() {
480                         try {
481                                 //MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
482
483                                 // Synchronous Web Service Outputs
484                                 Holder <String> vfModuleStackId = new Holder <String> ();
485                                 Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
486                                 Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
487                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
488                                 LOGGER.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
489
490                                 vnfAdapter.updateVfModule (req.getCloudSiteId(),
491                                                 req.getTenantId(),
492                                                 //req.getVnfType(),
493                                                 completeVnfVfModuleType,
494                                                 req.getVnfVersion(),
495                                                 req.getVfModuleName(),
496                                                 req.getRequestType(),
497                                                 req.getVolumeGroupStackId(),
498                                                 req.getBaseVfModuleStackId(),
499                                                 req.getVfModuleStackId(),
500                                                 req.getModelCustomizationUuid(),
501                                                 req.getVfModuleParams(),
502                                                 req.getMsoRequest(),
503                                                 outputs,
504                                                 vnfRollback);
505
506                                 response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
507                                                 vfModuleStackId.value, outputs.value, req.getMessageId());
508                         } catch (VnfException e) {
509                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
510                         }
511                         if (!req.isSynchronous()) {
512                                 // This is asynch, so POST response back to caller
513                                 BpelRestClient bpelClient = new BpelRestClient ();
514                                 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
515                         }
516                         LOGGER.debug ("Update VfModule exit: code=" + getStatusCode() + ", resp="+ getResponse());
517                 }
518         }
519         /*
520          * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback
521          * REQUEST:
522          * {"deleteVfModuleRequest":
523                 {"cloudSiteId": "DAN",
524                 "tenantId": "214b428a1f554c02935e66330f6a5409",
525                 "vnfId": "somevnfid",
526                 "vfModuleId": "somemodid",
527                 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
528                 "messageId": "ra.1",
529                 "notificationUrl": "http://localhost:8089/vnfmock",
530                 "skipAAI": true,
531                 "msoRequest": {
532                 "requestId": "ra1",
533                 "serviceInstanceId": "sa1"
534                 }}
535                 }
536          */
537         @DELETE
538         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
539         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
540         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
541         public Response rollbackVfModule (
542                         @PathParam("aaiVnfId") String aaiVnfId,
543                         @PathParam("aaiVfModuleId") String aaiVfModuleId,
544                         //@QueryParam("rollback") String rollback,
545                         final RollbackVfModuleRequest req)
546         {
547                 LOGGER.debug("Rollback VfModule enter: " + req.toJsonString());
548                 RollbackVfModulesTask task = new RollbackVfModulesTask(req);
549                 if (req.isSynchronous()) {
550                         // This is a synchronous request
551                         task.run();
552                         return Response
553                                 .status(task.getStatusCode())
554                                 .entity(task.getGenericEntityResponse())
555                                 .build();
556                 } else {
557                         // This is an asynchronous request
558                 try {
559                         Thread t1 = new Thread(task);
560                         t1.start();
561                 } catch (Exception e) {
562                         // problem handling create, send generic failure as sync resp to caller
563                         LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
564                         return Response.serverError().build();
565                 }
566                 // send sync response (ACK) to caller
567                 LOGGER.debug ("rollbackVfModule exit");
568                 return Response.status(HttpStatus.SC_ACCEPTED).build();
569                 }
570         }
571
572         public class RollbackVfModulesTask implements Runnable {
573                 private final RollbackVfModuleRequest req;
574                 private RollbackVfModuleResponse response = null;
575                 private VfModuleExceptionResponse eresp = null;
576                 private boolean sendxml;
577
578                 public RollbackVfModulesTask(RollbackVfModuleRequest req) {
579                         this.req = req;
580                         this.sendxml = true; // can be set with a field or header later
581                 }
582                 public int getStatusCode() {
583                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
584                 }
585                 public Object getGenericEntityResponse() {
586                         return (response != null)
587                                 ? new GenericEntity<RollbackVfModuleResponse>(response) {}
588                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
589                 }
590                 private String getResponse() {
591                         if (response != null) {
592                                 return sendxml ? response.toXmlString() : response.toJsonString();
593                         } else {
594                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
595                         }
596                 }
597                 @Override
598                 public void run() {
599                         try {
600                                 VfModuleRollback vmr = req.getVfModuleRollback();
601                                 VnfRollback vrb = new VnfRollback(
602                                                 vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudSiteId(), true, true,
603                                                 vmr.getMsoRequest(), null, null, null, null);
604                                 vnfAdapter.rollbackVnf (vrb);
605                                 response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
606                         } catch (VnfException e) {
607                                 LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
608                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false, req.getMessageId());
609                         }
610                         if (!req.isSynchronous()) {
611                                 // This is asynch, so POST response back to caller
612                                 BpelRestClient bpelClient = new BpelRestClient ();
613                                 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
614                         }
615                         LOGGER.debug ("RollbackVfModulesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
616                 }
617         }
618 }