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