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 * ================================================================================
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
24 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;
44 import org.apache.http.HttpStatus;
45 import org.onap.so.adapters.vnf.exceptions.VnfException;
46 import org.onap.so.adapters.vnfrest.CreateVfModuleRequest;
47 import org.onap.so.adapters.vnfrest.CreateVfModuleResponse;
48 import org.onap.so.adapters.vnfrest.DeleteVfModuleRequest;
49 import org.onap.so.adapters.vnfrest.DeleteVfModuleResponse;
50 import org.onap.so.adapters.vnfrest.QueryVfModuleResponse;
51 import org.onap.so.adapters.vnfrest.RollbackVfModuleRequest;
52 import org.onap.so.adapters.vnfrest.RollbackVfModuleResponse;
53 import org.onap.so.adapters.vnfrest.UpdateVfModuleRequest;
54 import org.onap.so.adapters.vnfrest.UpdateVfModuleResponse;
55 import org.onap.so.adapters.vnfrest.VfModuleExceptionResponse;
56 import org.onap.so.adapters.vnfrest.VfModuleRollback;
57 import org.onap.so.entity.MsoRequest;
58 import org.onap.so.logger.MessageEnum;
59 import org.onap.so.logger.MsoLogger;
60 import org.onap.so.openstack.beans.VnfRollback;
61 import org.onap.so.openstack.beans.VnfStatus;
62 import org.onap.so.openstack.exceptions.MsoExceptionCategory;
63 import org.springframework.beans.factory.annotation.Autowired;
64 import org.springframework.beans.factory.annotation.Qualifier;
65 import org.springframework.stereotype.Component;
66 import org.springframework.transaction.annotation.Transactional;
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;
75 * This class services calls to the REST interface for VF Modules (http://host:port/vnfs/rest/v1/vnfs)
76 * Both XML and JSON can be produced/consumed. Set Accept: and Content-Type: headers appropriately. XML is the default.
77 * For testing, call with cloudSiteId = ___TESTING___
78 * To test exceptions, also set tenantId = ___TESTING___
81 @Api(value = "/v1/vnfs", description = "root of vnf adapters restful web service")
84 public class VnfAdapterRest {
85 private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA, VnfAdapterRest.class);
86 private static final String TESTING_KEYWORD = "___TESTING___";
87 private static final String RESP=", resp=";
90 private MsoVnfAdapterImpl vnfAdapter;
91 //TODO Logging, SkipAAI, CREATED flags, Integrate with BPEL, Auth,
95 private Provider<BpelRestClient> bpelRestClientProvider;
99 * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>
101 * {"deleteVfModuleRequest":
102 {"cloudSiteId": "DAN",
103 "tenantId": "214b428a1f554c02935e66330f6a5409",
104 "vnfId": "somevnfid",
105 "vfModuleId": "somemodid",
106 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
108 "notificationUrl": "http://localhost:8089/vnfmock",
112 "serviceInstanceId": "sa1"
117 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
118 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
119 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
120 @ApiOperation(value = "DeleteVfModule",
121 response = Response.class,
122 notes = "Delete an existing vnfModule, DeleteVfModuleRequest JSON is required")
124 @ApiResponse(code = 200, message = "vnfModule has been successfully deleted"),
125 @ApiResponse(code = 202, message = "delete vnfModule request has been accepted (async only)"),
126 @ApiResponse(code = 500, message = "delete vnfModule failed, examine entity object for details") })
127 public Response deleteVfModule (
128 @ApiParam(value = "aaiVnfId", required = true)
129 @PathParam("aaiVnfId") String aaiVnfId,
130 @ApiParam(value = "aaiVfModuleId", required = true)
131 @PathParam("aaiVfModuleId") String aaiVfModuleId,
132 @ApiParam(value = "DeleteVfModuleRequest", required = true)
133 final DeleteVfModuleRequest req)
135 LOGGER.debug("Delete VfModule enter: " + req.toJsonString());
136 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
137 LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
139 .status(HttpStatus.SC_BAD_REQUEST)
140 .type(MediaType.TEXT_PLAIN)
141 .entity("vnfid in URL does not match content")
144 if (aaiVfModuleId == null || !aaiVfModuleId.equals(req.getVfModuleId())) {
145 LOGGER.debug("Req rejected - aaiVfModuleId not provided or doesn't match URL");
147 .status(HttpStatus.SC_BAD_REQUEST)
148 .type(MediaType.TEXT_PLAIN)
149 .entity("vfModuleId in URL does not match content")
152 DeleteVfModuleTask task = new DeleteVfModuleTask(req);
153 if (req.isSynchronous()) {
154 // This is a synchronous request
157 .status(task.getStatusCode())
158 .entity(task.getGenericEntityResponse())
161 // This is an asynchronous request
163 Thread t1 = new Thread(task);
165 } catch (Exception e) {
166 // problem handling delete, send generic failure as sync resp to caller
167 LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "deleteVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in deleteVfModule", e);
168 return Response.serverError().build();
170 // send sync response (ACK) to caller
171 LOGGER.debug ("deleteVNFVolumes exit");
172 return Response.status(HttpStatus.SC_ACCEPTED).build();
176 public class DeleteVfModuleTask implements Runnable {
177 private final DeleteVfModuleRequest req;
178 private DeleteVfModuleResponse response = null;
179 private VfModuleExceptionResponse eresp = null;
180 private boolean sendxml;
182 public DeleteVfModuleTask(DeleteVfModuleRequest req) {
184 this.sendxml = true; // can be set with a field or header later
186 public int getStatusCode() {
187 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
189 public Object getGenericEntityResponse() {
190 return (response != null)
191 ? new GenericEntity<DeleteVfModuleResponse>(response) {}
192 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
194 private String getResponse() {
195 if (response != null) {
196 return sendxml ? response.toXmlString() : response.toJsonString();
198 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
205 String cloudsite = req.getCloudSiteId();
206 Holder<Map<String, String>> outputs = new Holder <> ();
207 if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
208 //vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
209 vnfAdapter.deleteVfModule (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest(), outputs);
211 response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE, req.getMessageId(), outputs.value);
212 } catch (VnfException e) {
213 LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - Delete VNF Module", e);
214 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
216 if (!req.isSynchronous()) {
217 BpelRestClient bpelClient = bpelRestClientProvider.get();
218 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
220 LOGGER.debug ("Delete vfModule exit: code=" + getStatusCode() + RESP+ getResponse());
225 * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaiVnfId>/vf-modules/<aaiVfModuleId>?cloudSiteId=DAN&tenantId=vfModule?&skipAAI=TRUE&msoRequest.requestId=ra1&msoRequest.serviceInstanceId=si1&vfModuleName=T2N2S1
227 * {"queryVfModuleResponse": {
228 "vfModuleId": "AvfmodId",
229 "vfModuleOutputs": {"entry": {
230 "key": "server_private_ip_1",
231 "value": "10.100.1.25"
233 "vfModuleStackId": "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b",
235 "vnfStatus": "ACTIVE"
239 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
240 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
241 @ApiOperation(value = "QueryVfModule",
242 response = Response.class,
243 notes = "Query an existing vnfModule")
245 @ApiResponse(code = 200, message = "vnfModule has been successfully queried"),
246 @ApiResponse(code = 500, message = "query vnfModule failed, examine entity object for details") })
247 public Response queryVfModule(
248 @ApiParam(value = "aaiVnfId", required = true)
249 @PathParam("aaiVnfId") String aaiVnfId,
250 @ApiParam(value = "aaiVfModuleId", required = true)
251 @PathParam("aaiVfModuleId") String aaiVfModuleId,
252 @ApiParam(value = "cloudSiteId", required = true)
253 @QueryParam("cloudSiteId") String cloudSiteId,
254 @ApiParam(value = "tenantId", required = true)
255 @QueryParam("tenantId") String tenantId,
256 @ApiParam(value = "vfModuleName", required = true)
257 @QueryParam("vfModuleName") String vfModuleName, //RAA? Id in doc
258 @ApiParam(value = "skipAAI", required = true)
259 @QueryParam("skipAAI") Boolean skipAAI,
260 @ApiParam(value = "msoRequest.requestId", required = true)
261 @QueryParam("msoRequest.requestId") String requestId,
262 @ApiParam(value = "msoRequest.serviceInstanceId", required = true)
263 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId)
265 //This request responds synchronously only
266 LOGGER.debug ("Query vfModule enter:" + vfModuleName);
267 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
270 int respStatus = HttpStatus.SC_OK;
271 QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
272 Holder<Boolean> vnfExists = new Holder<>();
273 Holder<String> vfModuleId = new Holder<>();
274 Holder<VnfStatus> status = new Holder<>();
275 Holder<Map<String, String>> outputs = new Holder <> ();
276 vnfAdapter.queryVnf (cloudSiteId, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId, status, outputs);
277 if (!vnfExists.value) {
278 LOGGER.debug ("vfModule not found");
279 respStatus = HttpStatus.SC_NOT_FOUND;
281 LOGGER.debug ("vfModule found" + vfModuleId.value + ", status=" + status.value);
282 qryResp.setVfModuleId(vfModuleId.value);
283 qryResp.setVnfStatus(status.value);
284 qryResp.setVfModuleOutputs(outputs.value);
286 LOGGER.debug ("Query vfModule exit");
289 .entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {})
291 } catch (VnfException e) {
292 LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, "", "queryVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - queryVfModule", e);
293 VfModuleExceptionResponse excResp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
295 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
296 .entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {})
301 /*URL: http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules
303 * {"createVfModuleRequest":
304 {"cloudSiteId": "DAN",
305 "tenantId": "214b428a1f554c02935e66330f6a5409",
306 "vnfId": "somevnfid",
307 "vfModuleId": "somemodid",
308 "vfModuleName": "RaaVnf1",
309 "vnfType": "ApacheVnf",
310 "vfModuleParams": {"entry": [
311 {"key": "network_id",
312 "value": "59ed7b41-2983-413f-ba93-e7d437433916"},
314 "value": "086c9298-5c57-49b7-bb2b-6fd5730c5d92"},
315 {"key": "server_name_0",
318 "failIfExists": true,
320 "notificationUrl": "http://localhost:8089/vnfmock",
324 "serviceInstanceId": "sa1"
329 @Path("{aaiVnfId}/vf-modules")
330 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
331 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
332 @ApiOperation(value = "CreateVfModule",
333 response = Response.class,
334 notes = "Create a vnfModule")
336 @ApiResponse(code = 200, message = "vnfModule has been successfully created"),
337 @ApiResponse(code = 202, message = "create vnfModule request has been successfully accepted (async only)"),
338 @ApiResponse(code = 500, message = "create vnfModule failed, examine entity object for details") })
339 public Response createVfModule(
340 @ApiParam(value = "aaiVnfId", required = true)
341 @PathParam("aaiVnfId") String aaiVnfId,
342 @ApiParam(value = "CreateVfModuleRequest", required = true)
343 final CreateVfModuleRequest req)
345 LOGGER.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
346 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
347 LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
349 .status(HttpStatus.SC_BAD_REQUEST)
350 .type(MediaType.TEXT_PLAIN)
351 .entity("vnfid in URL does not match content")
354 CreateVfModuleTask task = new CreateVfModuleTask(req);
355 if (req.isSynchronous()) {
356 // This is a synchronous request
359 .status(task.getStatusCode())
360 .entity(task.getGenericEntityResponse())
363 // This is an asynchronous request
365 Thread t1 = new Thread(task);
367 } catch (Exception e) {
368 // problem handling create, send generic failure as sync resp to caller
369 LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, "", "createVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - createVfModule", e);
370 return Response.serverError().build();
372 // send sync response (ACK) to caller
373 LOGGER.debug ("createVfModule exit");
374 return Response.status(HttpStatus.SC_ACCEPTED).build();
378 public class CreateVfModuleTask implements Runnable {
379 private final CreateVfModuleRequest req;
380 private CreateVfModuleResponse response = null;
381 private VfModuleExceptionResponse eresp = null;
382 private boolean sendxml;
384 public CreateVfModuleTask(CreateVfModuleRequest req) {
386 this.sendxml = true; // can be set with a field or header later
388 public int getStatusCode() {
389 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
391 public Object getGenericEntityResponse() {
392 return (response != null)
393 ? new GenericEntity<CreateVfModuleResponse>(response) {}
394 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
396 private String getResponse() {
397 if (response != null) {
398 return sendxml ? response.toXmlString() : response.toJsonString();
400 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
406 LOGGER.debug ("CreateVfModuleTask start");
408 // Synchronous Web Service Outputs
409 Holder <String> vfModuleStackId = new Holder <> ();
410 Holder <Map <String, String>> outputs = new Holder <> ();
411 Holder <VnfRollback> vnfRollback = new Holder <> ();
412 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
413 LOGGER.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
414 String cloudsite = req.getCloudSiteId();
415 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
416 String tenant = req.getTenantId();
417 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
418 throw new VnfException("testing.");
420 vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudsite,
421 true, false, new MsoRequest("reqid", "svcid"),
422 req.getVolumeGroupId(), req.getVolumeGroupId(), req.getRequestType(), req.getModelCustomizationUuid());
423 vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
424 outputs.value = VolumeAdapterRest.testMap();
426 // vnfAdapter.createVnf (createReq.getCloudSiteId(),
427 // createReq.getTenantId(),
428 // createReq.getVnfType(),
429 // createReq.getVnfVersion(),
430 // createReq.getVfModuleName(),
431 // createReq.getRequestType(),
432 // createReq.getVolumeGroupStackId(),
433 // createReq.getVfModuleParams(),
434 // createReq.getFailIfExists(),
435 // createReq.getBackout(),
436 // createReq.getMsoRequest(),
440 vnfAdapter.createVfModule(req.getCloudSiteId(),
443 completeVnfVfModuleType,
445 req.getVfModuleName(),
446 req.getRequestType(),
447 req.getVolumeGroupStackId(),
448 req.getBaseVfModuleStackId(),
449 req.getModelCustomizationUuid(),
450 req.getVfModuleParams(),
451 req.getFailIfExists(),
453 req.getEnableBridge(),
459 VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(), vfModuleStackId.value, req.getMessageId());
460 response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
461 vfModuleStackId.value, Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
462 } catch (VnfException e) {
463 LOGGER.debug("Exception :",e);
464 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
466 if (!req.isSynchronous()) {
467 BpelRestClient bpelClient = bpelRestClientProvider.get();
468 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
470 LOGGER.debug ("CreateVfModuleTask exit: code=" + getStatusCode() + RESP+ getResponse());
475 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
476 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
477 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
478 @ApiOperation(value = "UpdateVfModule",
479 response = Response.class,
480 notes = "Update an existing vnfModule")
482 @ApiResponse(code = 200, message = "vnfModule has been successfully updated"),
483 @ApiResponse(code = 202, message = "update vnfModule request has been successfully accepted (async only)"),
484 @ApiResponse(code = 500, message = "update vnfModule failed, examine entity object for details") })
485 public Response updateVfModule(
486 @ApiParam(value = "aaiVnfId", required = true)
487 @PathParam("aaiVnfId") String aaiVnfId,
488 @ApiParam(value = "aaiVfModuleId", required = true)
489 @PathParam("aaiVfModuleId") String aaiVfModuleId,
490 @ApiParam(value = "UpdateVfModuleRequest", required = true)
491 final UpdateVfModuleRequest req)
493 LOGGER.debug("Update VfModule enter: " + req.toJsonString());
494 UpdateVfModulesTask task = new UpdateVfModulesTask(req);
495 if (req.isSynchronous()) {
496 // This is a synchronous request
499 .status(task.getStatusCode())
500 .entity(task.getGenericEntityResponse())
503 // This is an asynchronous request
505 Thread t1 = new Thread(task);
507 } catch (Exception e) {
508 // problem handling create, send generic failure as sync resp to caller
509 LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, "", "updateVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - updateVfModule", e);
510 return Response.serverError().build();
512 // send sync response (ACK) to caller
513 LOGGER.debug ("updateVfModules exit");
514 return Response.status(HttpStatus.SC_ACCEPTED).build();
518 public class UpdateVfModulesTask implements Runnable {
519 private final UpdateVfModuleRequest req;
520 private UpdateVfModuleResponse response = null;
521 private VfModuleExceptionResponse eresp = null;
522 private boolean sendxml;
524 public UpdateVfModulesTask(UpdateVfModuleRequest req) {
526 this.sendxml = true; // can be set with a field or header later
528 public int getStatusCode() {
529 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
531 public Object getGenericEntityResponse() {
532 return (response != null)
533 ? new GenericEntity<UpdateVfModuleResponse>(response) {}
534 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
536 private String getResponse() {
537 if (response != null) {
538 return sendxml ? response.toXmlString() : response.toJsonString();
540 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
546 //MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
548 // Synchronous Web Service Outputs
549 Holder <String> vfModuleStackId = new Holder <> ();
550 Holder <Map <String, String>> outputs = new Holder <> ();
551 Holder <VnfRollback> vnfRollback = new Holder <> ();
552 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
553 LOGGER.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
555 vnfAdapter.updateVfModule (req.getCloudSiteId(),
558 completeVnfVfModuleType,
560 req.getVfModuleName(),
561 req.getRequestType(),
562 req.getVolumeGroupStackId(),
563 req.getBaseVfModuleStackId(),
564 req.getVfModuleStackId(),
565 req.getModelCustomizationUuid(),
566 req.getVfModuleParams(),
571 response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
572 vfModuleStackId.value, outputs.value, req.getMessageId());
573 } catch (VnfException e) {
574 LOGGER.debug("Exception :",e);
575 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
577 if (!req.isSynchronous()) {
578 // This is asynch, so POST response back to caller
579 BpelRestClient bpelClient = bpelRestClientProvider.get();
580 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
582 LOGGER.debug ("Update VfModule exit: code=" + getStatusCode() + RESP+ getResponse());
586 * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback
588 * {"deleteVfModuleRequest":
589 {"cloudSiteId": "DAN",
590 "tenantId": "214b428a1f554c02935e66330f6a5409",
591 "vnfId": "somevnfid",
592 "vfModuleId": "somemodid",
593 "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
595 "notificationUrl": "http://localhost:8089/vnfmock",
599 "serviceInstanceId": "sa1"
604 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
605 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
606 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
607 @ApiOperation(value = "RollbackVfModule",
608 response = Response.class,
609 notes = "Rollback an existing vnfModule")
611 @ApiResponse(code = 200, message = "vnfModule has been successfully rolled back"),
612 @ApiResponse(code = 202, message = "rollback vnfModule request has been successfully accepted (async only)"),
613 @ApiResponse(code = 500, message = "rollback vnfModule failed, examine entity object for details") })
614 public Response rollbackVfModule (
615 @ApiParam(value = "aaiVnfId", required = true)
616 @PathParam("aaiVnfId") String aaiVnfId,
617 @ApiParam(value = "aaiVfModuleId", required = true)
618 @PathParam("aaiVfModuleId") String aaiVfModuleId,
619 @ApiParam(value = "RollbackVfModuleRequest", required = true)
620 //@QueryParam("rollback") String rollback,
621 final RollbackVfModuleRequest req)
623 LOGGER.debug("Rollback VfModule enter: " + req.toJsonString());
624 RollbackVfModulesTask task = new RollbackVfModulesTask(req);
625 if (req.isSynchronous()) {
626 // This is a synchronous request
629 .status(task.getStatusCode())
630 .entity(task.getGenericEntityResponse())
633 // This is an asynchronous request
635 Thread t1 = new Thread(task);
637 } catch (Exception e) {
638 // problem handling create, send generic failure as sync resp to caller
639 LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
640 return Response.serverError().build();
642 // send sync response (ACK) to caller
643 LOGGER.debug ("rollbackVfModule exit");
644 return Response.status(HttpStatus.SC_ACCEPTED).build();
648 public class RollbackVfModulesTask implements Runnable {
649 private final RollbackVfModuleRequest req;
650 private RollbackVfModuleResponse response = null;
651 private VfModuleExceptionResponse eresp = null;
652 private boolean sendxml;
654 public RollbackVfModulesTask(RollbackVfModuleRequest req) {
656 this.sendxml = true; // can be set with a field or header later
658 public int getStatusCode() {
659 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
661 public Object getGenericEntityResponse() {
662 return (response != null)
663 ? new GenericEntity<RollbackVfModuleResponse>(response) {}
664 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
666 private String getResponse() {
667 if (response != null) {
668 return sendxml ? response.toXmlString() : response.toJsonString();
670 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
676 VfModuleRollback vmr = req.getVfModuleRollback();
677 VnfRollback vrb = new VnfRollback(
678 vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudSiteId(), true, true,
679 vmr.getMsoRequest(), null, null, null, null);
680 vnfAdapter.rollbackVnf (vrb);
681 response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
682 } catch (VnfException e) {
683 LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
684 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false, req.getMessageId());
686 if (!req.isSynchronous()) {
687 // This is asynch, so POST response back to caller
688 BpelRestClient bpelClient = bpelRestClientProvider.get();
689 bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
691 LOGGER.debug ("RollbackVfModulesTask exit: code=" + getStatusCode() + RESP+ getResponse());