Removed MsoLogger class
[so.git] / adapters / mso-openstack-adapters / src / main / java / org / onap / so / adapters / vnf / VnfAdapterRestV2.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (C) 2018 IBM.
8  * Modifications Copyright (c) 2019 Samsung
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.ErrorCode;
59 import org.onap.so.logger.MessageEnum;
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.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65 import org.springframework.beans.factory.annotation.Autowired;
66 import org.springframework.stereotype.Component;
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/v2/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  * V2 incorporates run-time selection of sub-orchestrator implementation (Heat or Cloudify)
81  * based on the target cloud.
82  */
83 @Path("/v2/vnfs")
84 @Api(value = "/v2/vnfs", description = "root of vnf adapters restful web service v2")
85 @Component
86 public class VnfAdapterRestV2 {
87         private static Logger logger = LoggerFactory.getLogger(VnfAdapterRestV2.class);
88         private static final String TESTING_KEYWORD = "___TESTING___";
89         private static final String RESP=", resp=";
90
91         @Autowired
92         private VnfAdapterRestUtils vnfAdapterRestUtils;
93
94         @Autowired
95         private Provider<BpelRestClient> bpelRestClientProvider;
96
97    /*
98         * URL:http://localhost:8080/vnfs/rest/v2/vnfs/<aaivnfid>/vf-modules/<aaimodid>
99         * REQUEST:
100         * {"deleteVfModuleRequest":
101                 {"cloudSiteId": "DAN",
102                 "tenantId": "214b428a1f554c02935e66330f6a5409",
103                 "vnfId": "somevnfid",
104                 "vfModuleId": "somemodid",
105                 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
106                 "messageId": "ra.1",
107                 "notificationUrl": "http://localhost:8089/vnfmock",
108                 "skipAAI": true,
109                 "msoRequest": {
110                 "requestId": "ra1",
111                 "serviceInstanceId": "sa1"
112                 }}
113                 }
114         */
115         @DELETE
116         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
117         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
118         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
119         @ApiOperation(value = "DeleteVfModule",
120         response = Response.class,
121         notes = "Delete an existing vnfModule, DeleteVfModuleRequest JSON is required")
122         @ApiResponses({
123                 @ApiResponse(code = 200, message = "vnfModule has been successfully deleted"),
124                 @ApiResponse(code = 202, message = "delete vnfModule request has been accepted (async only)"),
125                 @ApiResponse(code = 500, message = "delete vnfModule failed, examine entity object for details") })
126         public Response deleteVfModule (
127                 @ApiParam(value = "aaiVnfId", required = true)
128                 @PathParam("aaiVnfId") String aaiVnfId,
129                 @ApiParam(value = "aaiVfModuleId", required = true)
130                 @PathParam("aaiVfModuleId") String aaiVfModuleId,
131                 @ApiParam(value = "mode", required = true)
132                 @QueryParam("mode") String mode,
133                 @ApiParam(value = "DeleteVfModuleRequest", required = true)
134                 final DeleteVfModuleRequest req)
135         {
136                 logger.debug("Delete VfModule enter: " + req.toJsonString());
137                 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
138                         logger.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
139                         return Response
140                                 .status(HttpStatus.SC_BAD_REQUEST)
141                                 .type(MediaType.TEXT_PLAIN)
142                                 .entity("vnfid in URL does not match content")
143                                 .build();
144                 }
145                 if (aaiVfModuleId == null || !aaiVfModuleId.equals(req.getVfModuleId())) {
146                                 logger.debug("Req rejected - aaiVfModuleId not provided or doesn't match URL");
147                         return Response
148                                 .status(HttpStatus.SC_BAD_REQUEST)
149                                 .type(MediaType.TEXT_PLAIN)
150                                 .entity("vfModuleId in URL does not match content")
151                                 .build();
152                 }
153
154                 DeleteVfModuleTask task = new DeleteVfModuleTask(req, mode);
155                 if (req.isSynchronous()) {
156                         // This is a synchronous request
157                         task.run();
158                         return Response
159                                 .status(task.getStatusCode())
160                                 .entity(task.getGenericEntityResponse())
161                                 .build();
162                 } else {
163                         // This is an asynchronous request
164                         try {
165                                 Thread t1 = new Thread(task);
166                                 t1.start();
167                         } catch (Exception e) {
168                                 // problem handling delete, send generic failure as sync resp to caller
169                                 logger.error("{} {} {} {}", MessageEnum.RA_DELETE_VNF_ERR.toString(), "deleteVfModule",
170                                         ErrorCode.BusinessProcesssError.getValue(), "Exception in deleteVfModule", e);
171                                 return Response.serverError().build();
172                         }
173                         // send sync response (ACK) to caller
174                         logger.debug("deleteVNFVolumes exit");
175                         return Response.status(HttpStatus.SC_ACCEPTED).build();
176                 }
177         }
178
179         public class DeleteVfModuleTask implements Runnable {
180                 private final DeleteVfModuleRequest req;
181                 private DeleteVfModuleResponse response = null;
182                 private VfModuleExceptionResponse eresp = null;
183                 private boolean sendxml;
184                 private String mode;
185
186                 public DeleteVfModuleTask(DeleteVfModuleRequest req, String mode) {
187                         this.req = req;
188                         this.sendxml = true; // can be set with a field or header later
189                         this.mode = mode;
190                 }
191                 public int getStatusCode() {
192                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
193                 }
194                 public Object getGenericEntityResponse() {
195                         return (response != null)
196                                 ? new GenericEntity<DeleteVfModuleResponse>(response) {}
197                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
198                 }
199                 private String getResponse() {
200                         if (response != null) {
201                                 return sendxml ? response.toXmlString() : response.toJsonString();
202                         } else {
203                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
204                         }
205                 }
206
207                 @Override
208                 public void run() {
209                         try {
210                                 String cloudsite = req.getCloudSiteId();
211                                 Holder<Map<String, String>> outputs = new Holder <Map <String, String>> ();
212                                 if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
213                                         //vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
214                                         // Support different Adapter Implementations
215                                         MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsite);
216                                         adapter.deleteVfModule (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest(), outputs);
217                                 }
218                                 response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE, req.getMessageId(), outputs.value);
219                         } catch (VnfException e) {
220                                 logger.error("{} {} {}", MessageEnum.RA_DELETE_VNF_ERR.toString(),
221                                         ErrorCode.BusinessProcesssError.getValue(), "VnfException - " + "Delete VNF Module", e);
222                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
223                         }
224                         if (!req.isSynchronous()) {
225                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
226                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
227                         }
228                         logger.debug("Delete vfModule exit: code=" + getStatusCode() + RESP + getResponse());
229                 }
230         }
231
232         /*
233          * URL:http://localhost:8080/vnfs/rest/v2/vnfs/<aaiVnfId>/vf-modules/<aaiVfModuleId>?cloudSiteId=DAN&tenantId=vfModule?&skipAAI=TRUE&msoRequest.requestId=ra1&msoRequest.serviceInstanceId=si1&vfModuleName=T2N2S1
234          * RESP:
235          * {"queryVfModuleResponse": {
236                    "vfModuleId": "AvfmodId",
237                    "vfModuleOutputs": {"entry": {
238                           "key": "server_private_ip_1",
239                           "value": "10.100.1.25"
240                    }},
241                    "vfModuleStackId": "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b",
242                    "vnfId": "AvnfID",
243                    "vnfStatus": "ACTIVE"
244                 }}
245          */
246         @GET
247         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
248         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
249         @ApiOperation(value = "QueryVfModule",
250                 response = Response.class,
251                 notes = "Query an existing vnfModule")
252         @ApiResponses({
253                 @ApiResponse(code = 200, message = "vnfModule has been successfully queried"),
254                 @ApiResponse(code = 500, message = "query vnfModule failed, examine entity object for details") })
255         public Response queryVfModule(
256                 @ApiParam(value = "aaiVnfId", required = true)
257                 @PathParam("aaiVnfId") String aaiVnfId,
258                 @ApiParam(value = "aaiVfModuleId", required = true)
259                 @PathParam("aaiVfModuleId") String aaiVfModuleId,
260                 @ApiParam(value = "cloudSiteId", required = true)
261                 @QueryParam("cloudSiteId") String cloudSiteId,
262                 @ApiParam(value = "tenantId", required = true)
263                 @QueryParam("tenantId") String tenantId,
264                 @ApiParam(value = "vfModuleName", required = true)
265                 @QueryParam("vfModuleName") String vfModuleName, //RAA? Id in doc
266                 @ApiParam(value = "skipAAI", required = true)
267                 @QueryParam("skipAAI") Boolean skipAAI,
268                 @ApiParam(value = "msoRequest.requestId", required = true)
269                 @QueryParam("msoRequest.requestId") String requestId,
270                 @ApiParam(value = "msoRequest.serviceInstanceId", required = true)
271                 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
272                 @ApiParam(value = "mode", required = true)
273                 @QueryParam("mode") String mode)
274         {
275                 //This request responds synchronously only
276                 logger.debug("Query vfModule enter:" + vfModuleName);
277                 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
278
279                 try {
280                         int respStatus = HttpStatus.SC_OK;
281                         QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
282                         Holder<Boolean> vnfExists = new Holder<Boolean>();
283                         Holder<String> vfModuleId = new Holder<String>();
284                         Holder<VnfStatus> status  = new Holder<VnfStatus>();
285                         Holder<Map<String, String>> outputs = new Holder <Map <String, String>> ();
286
287                         // Support different Adapter Implementations
288                         MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudSiteId);
289                         adapter.queryVnf (cloudSiteId, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId, status, outputs);
290
291                         if (!vnfExists.value) {
292                                 logger.debug("vfModule not found");
293                                 respStatus = HttpStatus.SC_NOT_FOUND;
294                         } else {
295                                 logger.debug("vfModule found" + vfModuleId.value + ", status=" + status.value);
296                                 qryResp.setVfModuleId(vfModuleId.value);
297                                 qryResp.setVnfStatus(status.value);
298                                 qryResp.setVfModuleOutputs(outputs.value);
299                         }
300                         logger.debug ("Query vfModule exit");
301                         return Response
302                                 .status(respStatus)
303                                 .entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {})
304                                 .build();
305                 } catch (VnfException e) {
306                         logger.error("{} {} {} {} {}", MessageEnum.RA_QUERY_VNF_ERR.toString(), vfModuleName, "queryVfModule",
307                                 ErrorCode.BusinessProcesssError.getValue(), "VnfException - queryVfModule", e);
308                         VfModuleExceptionResponse excResp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
309                         return Response
310                                 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
311                                 .entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {})
312                                 .build();
313                 }
314         }
315
316         /*URL: http://localhost:8080/vnfs/rest/v2/vnfs/<aaivnfid>/vf-modules
317          *REQUEST:
318          * {"createVfModuleRequest":
319                 {"cloudSiteId": "DAN",
320                 "tenantId": "214b428a1f554c02935e66330f6a5409",
321                 "vnfId": "somevnfid",
322                 "vfModuleId": "somemodid",
323                 "vfModuleName": "RaaVnf1",
324                 "vnfType": "ApacheVnf",
325                 "vfModuleParams": {"entry": [
326                         {"key": "network_id",
327                         "value": "59ed7b41-2983-413f-ba93-e7d437433916"},
328                         {"key": "subnet_id",
329                         "value": "086c9298-5c57-49b7-bb2b-6fd5730c5d92"},
330                         {"key": "server_name_0",
331                         "value": "RaaVnf1"}
332                         ]},
333                 "failIfExists": true,
334                 "messageId": "ra.1",
335                 "notificationUrl": "http://localhost:8089/vnfmock",
336                 "skipAAI": true,
337                 "msoRequest": {
338                 "requestId": "ra1",
339                 "serviceInstanceId": "sa1"
340                 }}
341                 }
342          */
343         @POST
344         @Path("{aaiVnfId}/vf-modules")
345         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
346         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
347         @ApiOperation(value = "CreateVfModule",
348                 response = Response.class,
349                 notes = "Create a vnfModule")
350         @ApiResponses({
351                 @ApiResponse(code = 200, message = "vnfModule has been successfully created"),
352                 @ApiResponse(code = 202, message = "create vnfModule request has been successfully accepted (async only)"),
353                 @ApiResponse(code = 500, message = "create vnfModule failed, examine entity object for details") })
354         public Response createVfModule(
355                 @ApiParam(value = "aaiVnfId", required = true)
356                 @PathParam("aaiVnfId") String aaiVnfId,
357                 @ApiParam(value = "mode", required = true)
358                 @QueryParam("mode") String mode,
359                 @ApiParam(value = "CreateVfModuleRequest", required = true)
360                 final CreateVfModuleRequest req)
361         {
362                 logger.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
363                 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
364                         logger.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
365                         return Response
366                                 .status(HttpStatus.SC_BAD_REQUEST)
367                                 .type(MediaType.TEXT_PLAIN)
368                                 .entity("vnfid in URL does not match content")
369                                 .build();
370                 }
371
372                 CreateVfModuleTask task = new CreateVfModuleTask(req, mode);
373                 if (req.isSynchronous()) {
374                         // This is a synchronous request
375                         task.run();
376                         return Response
377                                 .status(task.getStatusCode())
378                                 .entity(task.getGenericEntityResponse())
379                                 .build();
380                 } else {
381                         // This is an asynchronous request
382                         try {
383                                 Thread t1 = new Thread(task);
384                                 t1.start();
385                         } catch (Exception e) {
386                                 // problem handling create, send generic failure as sync resp to caller
387                                 logger.error("{} {} {} {}", MessageEnum.RA_CREATE_VNF_ERR.toString(), "createVfModule",
388                                         ErrorCode.BusinessProcesssError.getValue(), "Exception - createVfModule", e);
389                                 return Response.serverError().build();
390                         }
391                         // send sync response (ACK) to caller
392                         logger.debug("createVfModule exit");
393                         return Response.status(HttpStatus.SC_ACCEPTED).build();
394                 }
395         }
396
397         public class CreateVfModuleTask implements Runnable {
398                 private final CreateVfModuleRequest req;
399                 private CreateVfModuleResponse response = null;
400                 private VfModuleExceptionResponse eresp = null;
401                 private boolean sendxml;
402                 private String mode;
403
404                 public CreateVfModuleTask(CreateVfModuleRequest req, String mode) {
405                         this.req = req;
406                         this.sendxml = true; // can be set with a field or header later
407                         this.mode = mode;
408                 }
409                 public int getStatusCode() {
410                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
411                 }
412                 public Object getGenericEntityResponse() {
413                         return (response != null)
414                                 ? new GenericEntity<CreateVfModuleResponse>(response) {}
415                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
416                 }
417                 private String getResponse() {
418                         if (response != null) {
419                                 return sendxml ? response.toXmlString() : response.toJsonString();
420                         } else {
421                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
422                         }
423                 }
424
425                 @Override
426                 public void run() {
427                         logger.debug("CreateVfModuleTask start");
428                         try {
429                                 // Synchronous Web Service Outputs
430                                 Holder <String> vfModuleStackId = new Holder <String> ();
431                                 Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
432                                 Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
433                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
434                                 logger.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
435
436                                 String cloudsiteId = req.getCloudSiteId();
437                                 if (cloudsiteId != null && cloudsiteId.equals(TESTING_KEYWORD)) {
438                                         String tenant = req.getTenantId();
439                                         if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
440                                                 throw new VnfException("testing.");
441                                         }
442                                         vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudsiteId,
443                                                         true, false, new MsoRequest("reqid", "svcid"),
444                                                         req.getVolumeGroupId(), req.getVolumeGroupId(), req.getRequestType(), req.getModelCustomizationUuid());
445                                         vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
446                                         outputs.value = VolumeAdapterRest.testMap();
447                                 } else {
448                                         // Support different Adapter Implementations
449                                         MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsiteId);
450                                         adapter.createVfModule(req.getCloudSiteId(),
451                                                 req.getTenantId(),
452                                                 completeVnfVfModuleType,
453                                                 req.getVnfVersion(),
454                                                 req.getVnfId(),
455                                                 req.getVfModuleName(),
456                                                 req.getVfModuleId(),
457                                                 req.getRequestType(),
458                                                 req.getVolumeGroupStackId(),
459                                                 req.getBaseVfModuleStackId(),
460                                                 req.getModelCustomizationUuid(),
461                                                 req.getVfModuleParams(),
462                                                 req.getFailIfExists(),
463                                                 req.getBackout(),
464                                                 req.getEnableBridge(),
465                                                 req.getMsoRequest(),
466                                                 vfModuleStackId,
467                                                 outputs,
468                                                 vnfRollback);
469                                 }
470                                 VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(), vfModuleStackId.value, req.getMessageId());
471                                 response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
472                                                 vfModuleStackId.value, Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
473                         } catch (VnfException e) {
474                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
475                         }
476                         if (!req.isSynchronous()) {
477                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
478                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
479                         }
480                         logger.debug("CreateVfModuleTask exit: code=" + getStatusCode() + RESP + getResponse());
481                 }
482         }
483
484         @PUT
485         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
486         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
487         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
488         @ApiOperation(value = "UpdateVfModule",
489                 response = Response.class,
490                 notes = "Update an existing vnfModule")
491         @ApiResponses({
492                 @ApiResponse(code = 200, message = "vnfModule has been successfully updated"),
493                 @ApiResponse(code = 202, message = "update vnfModule request has been successfully accepted (async only)"),
494                 @ApiResponse(code = 500, message = "update vnfModule failed, examine entity object for details") })
495         public Response updateVfModule(
496                         @ApiParam(value = "aaiVnfId", required = true)
497                         @PathParam("aaiVnfId") String aaiVnfId,
498                         @ApiParam(value = "aaiVfModuleId", required = true)
499                         @PathParam("aaiVfModuleId") String aaiVfModuleId,
500                         @ApiParam(value = "mode", required = true)
501                         @QueryParam("mode") String mode,
502                         @ApiParam(value = "UpdateVfModuleRequest", required = true)
503                         final UpdateVfModuleRequest req)
504         {
505                 logger.debug("Update VfModule enter: " + req.toJsonString());
506                 UpdateVfModulesTask task = new UpdateVfModulesTask(req, mode);
507                 if (req.isSynchronous()) {
508                         // This is a synchronous request
509                         task.run();
510                         return Response
511                                 .status(task.getStatusCode())
512                                 .entity(task.getGenericEntityResponse())
513                                 .build();
514                 } else {
515                         // This is an asynchronous request
516                 try {
517                         Thread t1 = new Thread(task);
518                         t1.start();
519                 } catch (Exception e) {
520                         // problem handling create, send generic failure as sync resp to caller
521                                         logger.error("{} {} {} {}", MessageEnum.RA_UPDATE_VNF_ERR.toString(), "updateVfModule",
522                                                 ErrorCode.BusinessProcesssError.getValue(), "Exception - updateVfModule", e);
523                                         return Response.serverError().build();
524                 }
525                 // send sync response (ACK) to caller
526                 logger.debug("updateVfModules exit");
527                 return Response.status(HttpStatus.SC_ACCEPTED).build();
528                 }
529         }
530
531         public class UpdateVfModulesTask implements Runnable {
532                 private final UpdateVfModuleRequest req;
533                 private UpdateVfModuleResponse response = null;
534                 private VfModuleExceptionResponse eresp = null;
535                 private boolean sendxml;
536                 private String mode;
537
538                 public UpdateVfModulesTask(UpdateVfModuleRequest req, String mode) {
539                         this.req = req;
540                         this.sendxml = true; // can be set with a field or header later
541                         this.mode = mode;
542                 }
543                 public int getStatusCode() {
544                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
545                 }
546                 public Object getGenericEntityResponse() {
547                         return (response != null)
548                                 ? new GenericEntity<UpdateVfModuleResponse>(response) {}
549                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
550                 }
551                 private String getResponse() {
552                         if (response != null) {
553                                 return sendxml ? response.toXmlString() : response.toJsonString();
554                         } else {
555                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
556                         }
557                 }
558                 @Override
559                 public void run() {
560                         try {
561                                 //MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
562
563                                 // Synchronous Web Service Outputs
564                                 Holder <String> vfModuleStackId = new Holder <String> ();
565                                 Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
566                                 Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
567                                 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
568                                 logger.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
569
570                                 String cloudsiteId = req.getCloudSiteId();
571
572                                 // Support different Adapter Implementations
573                                 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsiteId);
574                                 adapter.updateVfModule (req.getCloudSiteId(),
575                                                 req.getTenantId(),
576                                                 completeVnfVfModuleType,
577                                                 req.getVnfVersion(),
578                                                 req.getVfModuleName(),
579                                                 req.getRequestType(),
580                                                 req.getVolumeGroupStackId(),
581                                                 req.getBaseVfModuleId(),
582                                                 req.getVfModuleStackId(),
583                                                 req.getModelCustomizationUuid(),
584                                                 req.getVfModuleParams(),
585                                                 req.getMsoRequest(),
586                                                 outputs,
587                                                 vnfRollback);
588
589                                 response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
590                                                 vfModuleStackId.value, outputs.value, req.getMessageId());
591                         } catch (VnfException e) {
592                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
593                         }
594                         if (!req.isSynchronous()) {
595                                 // This is asynch, so POST response back to caller
596                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
597                                 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
598                         }
599                         logger.debug("Update VfModule exit: code=" + getStatusCode() + RESP + getResponse());
600                 }
601         }
602         /*
603          * URL:http://localhost:8080/vnfs/rest/v2/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback
604          * REQUEST:
605          * {"deleteVfModuleRequest":
606                 {"cloudSiteId": "DAN",
607                 "tenantId": "214b428a1f554c02935e66330f6a5409",
608                 "vnfId": "somevnfid",
609                 "vfModuleId": "somemodid",
610                 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
611                 "messageId": "ra.1",
612                 "notificationUrl": "http://localhost:8089/vnfmock",
613                 "skipAAI": true,
614                 "msoRequest": {
615                 "requestId": "ra1",
616                 "serviceInstanceId": "sa1"
617                 }}
618                 }
619          */
620         @DELETE
621         @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
622         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
623         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
624         @ApiOperation(value = "RollbackVfModule",
625                 response = Response.class,
626                 notes = "Rollback an existing vnfModule")
627         @ApiResponses({
628                 @ApiResponse(code = 200, message = "vnfModule has been successfully rolled back"),
629                 @ApiResponse(code = 202, message = "rollback vnfModule request has been successfully accepted (async only)"),
630                 @ApiResponse(code = 500, message = "rollback vnfModule failed, examine entity object for details") })
631         public Response rollbackVfModule (
632                         @ApiParam(value = "aaiVnfId", required = true)
633                         @PathParam("aaiVnfId") String aaiVnfId,
634                         @ApiParam(value = "aaiVfModuleId", required = true)
635                         @PathParam("aaiVfModuleId") String aaiVfModuleId,
636                         @ApiParam(value = "RollbackVfModuleRequest", required = true)
637                         //@QueryParam("rollback") String rollback,
638                         final RollbackVfModuleRequest req)
639         {
640                 logger.debug("Rollback VfModule enter: " + req.toJsonString());
641                 RollbackVfModulesTask task = new RollbackVfModulesTask(req);
642                 if (req.isSynchronous()) {
643                         // This is a synchronous request
644                         task.run();
645                         return Response
646                                 .status(task.getStatusCode())
647                                 .entity(task.getGenericEntityResponse())
648                                 .build();
649                 } else {
650                         // This is an asynchronous request
651                 try {
652                         Thread t1 = new Thread(task);
653                         t1.start();
654                 } catch (Exception e) {
655                         // problem handling create, send generic failure as sync resp to caller
656                                         logger.error("{} {} {} {}", MessageEnum.RA_ROLLBACK_VNF_ERR.toString(), "rollbackVfModule",
657                                                 ErrorCode.BusinessProcesssError.getValue(), "Exception - rollbackVfModule", e);
658                                         return Response.serverError().build();
659                 }
660                 // send sync response (ACK) to caller
661                 logger.debug("rollbackVfModule exit");
662                 return Response.status(HttpStatus.SC_ACCEPTED).build();
663                 }
664         }
665
666         public class RollbackVfModulesTask implements Runnable {
667                 private final RollbackVfModuleRequest req;
668                 private RollbackVfModuleResponse response = null;
669                 private VfModuleExceptionResponse eresp = null;
670                 private boolean sendxml;
671
672                 public RollbackVfModulesTask(RollbackVfModuleRequest req) {
673                         this.req = req;
674                         this.sendxml = true; // can be set with a field or header later
675                 }
676                 public int getStatusCode() {
677                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
678                 }
679                 public Object getGenericEntityResponse() {
680                         return (response != null)
681                                 ? new GenericEntity<RollbackVfModuleResponse>(response) {}
682                                 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
683                 }
684                 private String getResponse() {
685                         if (response != null) {
686                                 return sendxml ? response.toXmlString() : response.toJsonString();
687                         } else {
688                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
689                         }
690                 }
691                 @Override
692                 public void run() {
693                         try {
694                                 VfModuleRollback vmr = req.getVfModuleRollback();
695                                 VnfRollback vrb = new VnfRollback(
696                                                 vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudSiteId(), true, vmr.isVfModuleCreated(),
697                                                 vmr.getMsoRequest(), null, null, null, null);
698
699                                 // Support multiple adapter implementations
700                                 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl (vmr.getMode(), vmr.getCloudSiteId());
701                                 adapter.rollbackVnf (vrb);
702
703                                 response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
704                         } catch (VnfException e) {
705                                 logger.error("{} {} {}", MessageEnum.RA_ROLLBACK_VNF_ERR.toString(),
706                                         ErrorCode.BusinessProcesssError.getValue(), "Exception - rollbackVfModule", e);
707                                 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false, req.getMessageId());
708                         }
709                         if (!req.isSynchronous()) {
710                                 // This is asynch, so POST response back to caller
711                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
712                                 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
713                         }
714                         logger.debug("RollbackVfModulesTask exit: code=" + getStatusCode() + RESP + getResponse());
715                 }
716         }
717 }