2 * ============LICENSE_START=======================================================
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
15 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
25 package org.onap.so.adapters.vnf;
29 import javax.inject.Provider;
30 import javax.ws.rs.Consumes;
31 import javax.ws.rs.DELETE;
32 import javax.ws.rs.GET;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.PUT;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.PathParam;
37 import javax.ws.rs.Produces;
38 import javax.ws.rs.QueryParam;
39 import javax.ws.rs.core.GenericEntity;
40 import javax.ws.rs.core.MediaType;
41 import javax.ws.rs.core.Response;
42 import javax.xml.ws.Holder;
43 import org.apache.http.HttpStatus;
44 import org.onap.logging.ref.slf4j.ONAPLogConstants;
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;
66 import org.springframework.beans.factory.annotation.Autowired;
67 import org.springframework.stereotype.Component;
68 import org.springframework.transaction.annotation.Transactional;
69 import io.swagger.annotations.Api;
70 import io.swagger.annotations.ApiOperation;
71 import io.swagger.annotations.ApiParam;
72 import io.swagger.annotations.ApiResponse;
73 import io.swagger.annotations.ApiResponses;
76 * This class services calls to the REST interface for VF Modules (http://host:port/vnfs/rest/v1/vnfs) Both XML and JSON
77 * can be produced/consumed. Set Accept: and Content-Type: headers appropriately. XML is the default. For testing, call
78 * with cloudSiteId = ___TESTING___ To test exceptions, also set tenantId = ___TESTING___
81 @Api(value = "/v1/vnfs", description = "root of vnf adapters restful web service")
84 public class VnfAdapterRest {
85 private static Logger logger = LoggerFactory.getLogger(VnfAdapterRest.class);
86 private static final String TESTING_KEYWORD = "___TESTING___";
87 private static final String RESP = ", resp=";
90 private MsoVnfAdapterImpl vnfAdapter;
93 private Provider<BpelRestClient> bpelRestClientProvider;
96 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
97 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
98 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
99 @ApiOperation(value = "DeleteVfModule", response = Response.class,
100 notes = "Delete an existing vnfModule, DeleteVfModuleRequest JSON is required")
101 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully deleted"),
102 @ApiResponse(code = 202, message = "delete vnfModule request has been accepted (async only)"),
103 @ApiResponse(code = 500, message = "delete vnfModule failed, examine entity object for details")})
104 public Response deleteVfModule(
105 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
106 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
107 @ApiParam(value = "DeleteVfModuleRequest", required = true) final DeleteVfModuleRequest req) {
108 logger.debug("Delete VfModule enter: " + req.toJsonString());
109 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
110 logger.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
111 return Response.status(HttpStatus.SC_BAD_REQUEST).type(MediaType.TEXT_PLAIN)
112 .entity("vnfid in URL does not match content").build();
114 if (aaiVfModuleId == null || !aaiVfModuleId.equals(req.getVfModuleId())) {
115 logger.debug("Req rejected - aaiVfModuleId not provided or doesn't match URL");
116 return Response.status(HttpStatus.SC_BAD_REQUEST).type(MediaType.TEXT_PLAIN)
117 .entity("vfModuleId in URL does not match content").build();
119 DeleteVfModuleTask task = new DeleteVfModuleTask(req);
120 if (req.isSynchronous()) {
121 // This is a synchronous request
123 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
125 // This is an asynchronous request
127 Thread t1 = new Thread(task);
129 } catch (Exception e) {
130 // problem handling delete, send generic failure as sync resp to caller
131 logger.error("", MessageEnum.RA_DELETE_VNF_ERR.toString(), "deleteVfModule",
132 ErrorCode.BusinessProcesssError.getValue(), "Exception in deleteVfModule", e);
133 return Response.serverError().build();
135 // send sync response (ACK) to caller
136 logger.debug("deleteVNFVolumes exit");
137 return Response.status(HttpStatus.SC_ACCEPTED).build();
141 public class DeleteVfModuleTask implements Runnable {
142 private final DeleteVfModuleRequest req;
143 private DeleteVfModuleResponse response = null;
144 private VfModuleExceptionResponse eresp = null;
145 private boolean sendxml;
147 public DeleteVfModuleTask(DeleteVfModuleRequest req) {
149 this.sendxml = true; // can be set with a field or header later
152 public int getStatusCode() {
153 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
156 public Object getGenericEntityResponse() {
157 return (response != null) ? new GenericEntity<DeleteVfModuleResponse>(response) {}
158 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
161 private String getResponse() {
162 if (response != null) {
163 return sendxml ? response.toXmlString() : response.toJsonString();
165 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
173 MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId());
174 } catch (Exception e) {
175 logger.error("Error adding RequestId to MDC", e);
177 String cloudsite = req.getCloudSiteId();
178 Holder<Map<String, String>> outputs = new Holder<>();
179 if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
180 vnfAdapter.deleteVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
181 req.getVfModuleStackId(), req.getMsoRequest(), outputs);
183 response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE,
184 req.getMessageId(), outputs.value);
185 } catch (VnfException e) {
186 logger.error("{} {} {}", MessageEnum.RA_DELETE_VNF_ERR.toString(),
187 ErrorCode.BusinessProcesssError.getValue(), "VnfException - Delete VNF Module", e);
188 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE,
191 if (!req.isSynchronous()) {
192 BpelRestClient bpelClient = bpelRestClientProvider.get();
193 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
195 logger.debug("Delete vfModule exit: code=" + getStatusCode() + RESP + getResponse());
201 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
202 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
203 @ApiOperation(value = "QueryVfModule", response = Response.class, notes = "Query an existing vnfModule")
204 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully queried"),
205 @ApiResponse(code = 500, message = "query vnfModule failed, examine entity object for details")})
206 public Response queryVfModule(@ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
207 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
208 @ApiParam(value = "cloudSiteId", required = true) @QueryParam("cloudSiteId") String cloudSiteId,
209 @ApiParam(value = "cloudOwner", required = true) @QueryParam("cloudOwner") String cloudOwner,
210 @ApiParam(value = "tenantId", required = true) @QueryParam("tenantId") String tenantId,
211 @ApiParam(value = "vfModuleName", required = true) @QueryParam("vfModuleName") String vfModuleName, // RAA?
214 @ApiParam(value = "skipAAI", required = true) @QueryParam("skipAAI") Boolean skipAAI,
215 @ApiParam(value = "msoRequest.requestId",
216 required = true) @QueryParam("msoRequest.requestId") String requestId,
217 @ApiParam(value = "msoRequest.serviceInstanceId",
218 required = true) @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId) {
219 // This request responds synchronously only
220 logger.debug("Query vfModule enter:" + vfModuleName);
221 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
224 int respStatus = HttpStatus.SC_OK;
225 QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
226 Holder<Boolean> vnfExists = new Holder<>();
227 Holder<String> vfModuleId = new Holder<>();
228 Holder<VnfStatus> status = new Holder<>();
229 Holder<Map<String, String>> outputs = new Holder<>();
230 vnfAdapter.queryVnf(cloudSiteId, cloudOwner, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId,
232 if (!vnfExists.value) {
233 logger.debug("vfModule not found");
234 respStatus = HttpStatus.SC_NOT_FOUND;
236 logger.debug("vfModule found" + vfModuleId.value + ", status=" + status.value);
237 qryResp.setVfModuleId(vfModuleId.value);
238 qryResp.setVnfStatus(status.value);
239 qryResp.setVfModuleOutputs(outputs.value);
241 logger.debug("Query vfModule exit");
242 return Response.status(respStatus).entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {}).build();
243 } catch (VnfException e) {
244 logger.error("{} {} {} {} {}", MessageEnum.RA_QUERY_VNF_ERR.toString(), vfModuleName, "queryVfModule",
245 ErrorCode.BusinessProcesssError.getValue(), "VnfException - queryVfModule", e);
246 VfModuleExceptionResponse excResp =
247 new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
248 return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
249 .entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {}).build();
254 * URL: http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules REQUEST: {"createVfModuleRequest":
255 * {"cloudSiteId": "DAN", "tenantId": "214b428a1f554c02935e66330f6a5409", "vnfId": "somevnfid", "vfModuleId":
256 * "somemodid", "vfModuleName": "RaaVnf1", "vnfType": "ApacheVnf", "vfModuleParams": {"entry": [ {"key":
257 * "network_id", "value": "59ed7b41-2983-413f-ba93-e7d437433916"}, {"key": "subnet_id", "value":
258 * "086c9298-5c57-49b7-bb2b-6fd5730c5d92"}, {"key": "server_name_0", "value": "RaaVnf1"} ]}, "failIfExists": true,
259 * "messageId": "ra.1", "notificationUrl": "http://localhost:8089/vnfmock", "skipAAI": true, "msoRequest": {
260 * "requestId": "ra1", "serviceInstanceId": "sa1" }} }
263 @Path("{aaiVnfId}/vf-modules")
264 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
265 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
266 @ApiOperation(value = "CreateVfModule", response = Response.class, notes = "Create a vnfModule")
267 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully created"),
268 @ApiResponse(code = 202, message = "create vnfModule request has been successfully accepted (async only)"),
269 @ApiResponse(code = 500, message = "create vnfModule failed, examine entity object for details")})
270 public Response createVfModule(
271 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
272 @ApiParam(value = "CreateVfModuleRequest", required = true) final CreateVfModuleRequest req) {
273 logger.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
274 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
275 logger.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
276 return Response.status(HttpStatus.SC_BAD_REQUEST).type(MediaType.TEXT_PLAIN)
277 .entity("vnfid in URL does not match content").build();
279 CreateVfModuleTask task = new CreateVfModuleTask(req);
280 if (req.isSynchronous()) {
281 // This is a synchronous request
283 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
285 // This is an asynchronous request
287 Thread t1 = new Thread(task);
289 } catch (Exception e) {
290 // problem handling create, send generic failure as sync resp to caller
291 logger.error("{} {} {} {}", MessageEnum.RA_CREATE_VNF_ERR, "createVfModule",
292 ErrorCode.BusinessProcesssError, "Exception - createVfModule", e);
293 return Response.serverError().build();
295 // send sync response (ACK) to caller
296 logger.debug("createVfModule exit");
297 return Response.status(HttpStatus.SC_ACCEPTED).build();
301 public class CreateVfModuleTask implements Runnable {
302 private final CreateVfModuleRequest req;
303 private CreateVfModuleResponse response = null;
304 private VfModuleExceptionResponse eresp = null;
305 private boolean sendxml;
307 public CreateVfModuleTask(CreateVfModuleRequest req) {
309 this.sendxml = true; // can be set with a field or header later
312 public int getStatusCode() {
313 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
316 public Object getGenericEntityResponse() {
317 return (response != null) ? new GenericEntity<CreateVfModuleResponse>(response) {}
318 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
321 private String getResponse() {
322 if (response != null) {
323 return sendxml ? response.toXmlString() : response.toJsonString();
325 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
331 logger.debug("CreateVfModuleTask start");
334 MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId());
335 } catch (Exception e) {
336 logger.error("Error adding RequestId to MDC", e);
338 // Synchronous Web Service Outputs
339 Holder<String> vfModuleStackId = new Holder<>();
340 Holder<Map<String, String>> outputs = new Holder<>();
341 Holder<VnfRollback> vnfRollback = new Holder<>();
342 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
343 logger.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
344 String cloudsite = req.getCloudSiteId();
345 String cloudOwner = req.getCloudOwner();
346 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
347 String tenant = req.getTenantId();
348 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
349 throw new VnfException("testing.");
351 vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudOwner, cloudsite, true, false,
352 new MsoRequest("reqid", "svcid"), req.getVolumeGroupId(), req.getVolumeGroupId(),
353 req.getRequestType(), req.getModelCustomizationUuid());
354 vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
355 outputs.value = VolumeAdapterRest.testMap();
357 vnfAdapter.createVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
358 completeVnfVfModuleType, req.getVnfVersion(), req.getVnfId(), req.getVfModuleName(),
359 req.getVfModuleId(), req.getRequestType(), req.getVolumeGroupStackId(),
360 req.getBaseVfModuleStackId(), req.getModelCustomizationUuid(), req.getVfModuleParams(),
361 req.getFailIfExists(), req.getBackout(), req.getEnableBridge(), req.getMsoRequest(),
362 vfModuleStackId, outputs, vnfRollback);
364 VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(),
365 vfModuleStackId.value, req.getMessageId());
366 response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(), vfModuleStackId.value,
367 Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
368 } catch (VnfException e) {
369 logger.debug("Exception :", e);
370 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE,
373 if (!req.isSynchronous()) {
374 BpelRestClient bpelClient = bpelRestClientProvider.get();
375 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
377 logger.debug("CreateVfModuleTask exit: code=" + getStatusCode());
382 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
383 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
384 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
385 @ApiOperation(value = "UpdateVfModule", response = Response.class, notes = "Update an existing vnfModule")
386 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully updated"),
387 @ApiResponse(code = 202, message = "update vnfModule request has been successfully accepted (async only)"),
388 @ApiResponse(code = 500, message = "update vnfModule failed, examine entity object for details")})
389 public Response updateVfModule(
390 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
391 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
392 @ApiParam(value = "UpdateVfModuleRequest", required = true) final UpdateVfModuleRequest req) {
393 logger.debug("Update VfModule enter: " + req.toJsonString());
394 UpdateVfModulesTask task = new UpdateVfModulesTask(req);
395 if (req.isSynchronous()) {
396 // This is a synchronous request
398 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
400 // This is an asynchronous request
402 Thread t1 = new Thread(task);
404 } catch (Exception e) {
405 // problem handling create, send generic failure as sync resp to caller
406 logger.error("{} {} {} {}", MessageEnum.RA_UPDATE_VNF_ERR.toString(), "updateVfModule",
407 ErrorCode.BusinessProcesssError.getValue(), "Exception - updateVfModule", e);
408 return Response.serverError().build();
410 // send sync response (ACK) to caller
411 logger.debug("updateVfModules exit");
412 return Response.status(HttpStatus.SC_ACCEPTED).build();
416 public class UpdateVfModulesTask implements Runnable {
417 private final UpdateVfModuleRequest req;
418 private UpdateVfModuleResponse response = null;
419 private VfModuleExceptionResponse eresp = null;
420 private boolean sendxml;
422 public UpdateVfModulesTask(UpdateVfModuleRequest req) {
424 this.sendxml = true; // can be set with a field or header later
427 public int getStatusCode() {
428 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
431 public Object getGenericEntityResponse() {
432 return (response != null) ? new GenericEntity<UpdateVfModuleResponse>(response) {}
433 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
436 private String getResponse() {
437 if (response != null) {
438 return sendxml ? response.toXmlString() : response.toJsonString();
440 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
448 MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId());
449 } catch (Exception e) {
450 logger.error("Error adding RequestId to MDC", e);
452 Holder<String> vfModuleStackId = new Holder<>();
453 Holder<Map<String, String>> outputs = new Holder<>();
454 Holder<VnfRollback> vnfRollback = new Holder<>();
455 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
456 logger.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
458 vnfAdapter.updateVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
460 completeVnfVfModuleType, req.getVnfVersion(), req.getVfModuleName(), req.getRequestType(),
461 req.getVolumeGroupStackId(), req.getBaseVfModuleStackId(), req.getVfModuleStackId(),
462 req.getModelCustomizationUuid(), req.getVfModuleParams(), req.getMsoRequest(), outputs,
465 response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(), vfModuleStackId.value,
466 outputs.value, req.getMessageId());
467 } catch (VnfException e) {
468 logger.debug("Exception :", e);
469 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE,
472 if (!req.isSynchronous()) {
473 // This is asynch, so POST response back to caller
474 BpelRestClient bpelClient = bpelRestClientProvider.get();
475 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
477 logger.debug("Update VfModule exit: code=" + getStatusCode() + RESP + getResponse());
483 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
484 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
485 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
486 @ApiOperation(value = "RollbackVfModule", response = Response.class, notes = "Rollback an existing vnfModule")
487 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully rolled back"),
488 @ApiResponse(code = 202,
489 message = "rollback vnfModule request has been successfully accepted (async only)"),
490 @ApiResponse(code = 500, message = "rollback vnfModule failed, examine entity object for details")})
491 public Response rollbackVfModule(
492 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
493 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
494 @ApiParam(value = "RollbackVfModuleRequest", required = true)
495 // @QueryParam("rollback") String rollback,
496 final RollbackVfModuleRequest req) {
497 logger.debug("Rollback VfModule enter: " + req.toJsonString());
498 RollbackVfModulesTask task = new RollbackVfModulesTask(req);
499 if (req.isSynchronous()) {
500 // This is a synchronous request
502 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
504 // This is an asynchronous request
506 Thread t1 = new Thread(task);
508 } catch (Exception e) {
509 // problem handling create, send generic failure as sync resp to caller
510 logger.error("{} {} {} {}", MessageEnum.RA_ROLLBACK_VNF_ERR.toString(), "rollbackVfModule",
511 ErrorCode.BusinessProcesssError.getValue(), "Exception - rollbackVfModule", e);
512 return Response.serverError().build();
514 // send sync response (ACK) to caller
515 logger.debug("rollbackVfModule exit");
516 return Response.status(HttpStatus.SC_ACCEPTED).build();
520 public class RollbackVfModulesTask implements Runnable {
521 private final RollbackVfModuleRequest req;
522 private RollbackVfModuleResponse response = null;
523 private VfModuleExceptionResponse eresp = null;
524 private boolean sendxml;
526 public RollbackVfModulesTask(RollbackVfModuleRequest req) {
528 this.sendxml = true; // can be set with a field or header later
531 public int getStatusCode() {
532 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
535 public Object getGenericEntityResponse() {
536 return (response != null) ? new GenericEntity<RollbackVfModuleResponse>(response) {}
537 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
540 private String getResponse() {
541 if (response != null) {
542 return sendxml ? response.toXmlString() : response.toJsonString();
544 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
552 MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getVfModuleRollback().getMsoRequest().getRequestId());
553 } catch (Exception e) {
554 logger.error("Error adding RequestId to MDC", e);
556 VfModuleRollback vmr = req.getVfModuleRollback();
557 VnfRollback vrb = new VnfRollback(vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudOwner(),
558 vmr.getCloudSiteId(), true, true, vmr.getMsoRequest(), null, null, null, null);
559 vnfAdapter.rollbackVnf(vrb);
560 response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
561 } catch (VnfException e) {
562 logger.error("{} {} {}", MessageEnum.RA_ROLLBACK_VNF_ERR, ErrorCode.BusinessProcesssError,
563 "Exception" + " - " + "rollbackVfModule", e);
564 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false,
567 if (!req.isSynchronous()) {
568 // This is asynch, so POST response back to caller
569 BpelRestClient bpelClient = bpelRestClientProvider.get();
570 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
572 logger.debug("RollbackVfModulesTask exit: code=" + getStatusCode() + RESP + getResponse());