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