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