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