2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (C) 2018 IBM.
8 * Modifications Copyright (c) 2019 Samsung
9 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
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;
28 import javax.inject.Provider;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.QueryParam;
38 import javax.ws.rs.core.GenericEntity;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41 import javax.xml.ws.Holder;
42 import org.apache.http.HttpStatus;
43 import org.onap.so.adapters.vnf.exceptions.VnfException;
44 import org.onap.so.adapters.vnfrest.CreateVfModuleRequest;
45 import org.onap.so.adapters.vnfrest.CreateVfModuleResponse;
46 import org.onap.so.adapters.vnfrest.DeleteVfModuleRequest;
47 import org.onap.so.adapters.vnfrest.DeleteVfModuleResponse;
48 import org.onap.so.adapters.vnfrest.QueryVfModuleResponse;
49 import org.onap.so.adapters.vnfrest.RollbackVfModuleRequest;
50 import org.onap.so.adapters.vnfrest.RollbackVfModuleResponse;
51 import org.onap.so.adapters.vnfrest.UpdateVfModuleRequest;
52 import org.onap.so.adapters.vnfrest.UpdateVfModuleResponse;
53 import org.onap.so.adapters.vnfrest.VfModuleExceptionResponse;
54 import org.onap.so.adapters.vnfrest.VfModuleRollback;
55 import org.onap.so.entity.MsoRequest;
56 import org.onap.so.logger.ErrorCode;
57 import org.onap.so.logger.MessageEnum;
58 import org.onap.so.openstack.beans.VnfRollback;
59 import org.onap.so.openstack.beans.VnfStatus;
60 import org.onap.so.openstack.exceptions.MsoExceptionCategory;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63 import org.springframework.beans.factory.annotation.Autowired;
64 import org.springframework.stereotype.Component;
65 import io.swagger.annotations.Api;
66 import io.swagger.annotations.ApiOperation;
67 import io.swagger.annotations.ApiParam;
68 import io.swagger.annotations.ApiResponse;
69 import io.swagger.annotations.ApiResponses;
72 * This class services calls to the REST interface for VF Modules (http://host:port/vnfs/rest/v2/vnfs) Both XML and JSON
73 * can be produced/consumed. Set Accept: and Content-Type: headers appropriately. XML is the default. For testing, call
74 * with cloudSiteId = ___TESTING___ To test exceptions, also set tenantId = ___TESTING___
76 * V2 incorporates run-time selection of sub-orchestrator implementation (Heat or Cloudify) based on the target cloud.
79 @Api(value = "/v2/vnfs", description = "root of vnf adapters restful web service v2")
81 public class VnfAdapterRestV2 {
82 private static Logger logger = LoggerFactory.getLogger(VnfAdapterRestV2.class);
83 private static final String TESTING_KEYWORD = "___TESTING___";
84 private static final String RESP = ", resp=";
87 private VnfAdapterRestUtils vnfAdapterRestUtils;
90 private Provider<BpelRestClient> bpelRestClientProvider;
93 * URL:http://localhost:8080/vnfs/rest/v2/vnfs/<aaivnfid>/vf-modules/<aaimodid> REQUEST: {"deleteVfModuleRequest":
94 * {"cloudSiteId": "DAN", "tenantId": "214b428a1f554c02935e66330f6a5409", "vnfId": "somevnfid", "vfModuleId":
95 * "somemodid", "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73", "messageId": "ra.1", "notificationUrl":
96 * "http://localhost:8089/vnfmock", "skipAAI": true, "msoRequest": { "requestId": "ra1", "serviceInstanceId": "sa1"
100 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
101 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
102 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
103 @ApiOperation(value = "DeleteVfModule", response = Response.class,
104 notes = "Delete an existing vnfModule, DeleteVfModuleRequest JSON is required")
105 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully deleted"),
106 @ApiResponse(code = 202, message = "delete vnfModule request has been accepted (async only)"),
107 @ApiResponse(code = 500, message = "delete vnfModule failed, examine entity object for details")})
108 public Response deleteVfModule(
109 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
110 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
111 @ApiParam(value = "mode", required = true) @QueryParam("mode") String mode,
112 @ApiParam(value = "DeleteVfModuleRequest", required = true) final DeleteVfModuleRequest req) {
113 logger.debug("Delete VfModule enter: " + req.toJsonString());
114 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
115 logger.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
116 return Response.status(HttpStatus.SC_BAD_REQUEST).type(MediaType.TEXT_PLAIN)
117 .entity("vnfid in URL does not match content").build();
119 if (aaiVfModuleId == null || !aaiVfModuleId.equals(req.getVfModuleId())) {
120 logger.debug("Req rejected - aaiVfModuleId not provided or doesn't match URL");
121 return Response.status(HttpStatus.SC_BAD_REQUEST).type(MediaType.TEXT_PLAIN)
122 .entity("vfModuleId in URL does not match content").build();
125 DeleteVfModuleTask task = new DeleteVfModuleTask(req, mode);
126 if (req.isSynchronous()) {
127 // This is a synchronous request
129 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
131 // This is an asynchronous request
133 Thread t1 = new Thread(task);
135 } catch (Exception e) {
136 // problem handling delete, send generic failure as sync resp to caller
137 logger.error("{} {} {} {}", MessageEnum.RA_DELETE_VNF_ERR.toString(), "deleteVfModule",
138 ErrorCode.BusinessProcesssError.getValue(), "Exception in deleteVfModule", e);
139 return Response.serverError().build();
141 // send sync response (ACK) to caller
142 logger.debug("deleteVNFVolumes exit");
143 return Response.status(HttpStatus.SC_ACCEPTED).build();
147 public class DeleteVfModuleTask implements Runnable {
148 private final DeleteVfModuleRequest req;
149 private DeleteVfModuleResponse response = null;
150 private VfModuleExceptionResponse eresp = null;
151 private boolean sendxml;
154 public DeleteVfModuleTask(DeleteVfModuleRequest req, String mode) {
156 this.sendxml = true; // can be set with a field or header later
160 public int getStatusCode() {
161 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
164 public Object getGenericEntityResponse() {
165 return (response != null) ? new GenericEntity<DeleteVfModuleResponse>(response) {}
166 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
169 private String getResponse() {
170 if (response != null) {
171 return sendxml ? response.toXmlString() : response.toJsonString();
173 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
180 String cloudsite = req.getCloudSiteId();
181 Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
182 if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
183 // vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(),
184 // req.getMsoRequest());
185 // Support different Adapter Implementations
186 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsite);
187 adapter.deleteVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
188 req.getVfModuleStackId(), req.getMsoRequest(), outputs);
190 response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE,
191 req.getMessageId(), outputs.value);
192 } catch (VnfException e) {
193 logger.error("{} {} {}", MessageEnum.RA_DELETE_VNF_ERR.toString(),
194 ErrorCode.BusinessProcesssError.getValue(), "VnfException - " + "Delete VNF Module", e);
195 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE,
198 if (!req.isSynchronous()) {
199 BpelRestClient bpelClient = bpelRestClientProvider.get();
200 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
202 logger.debug("Delete vfModule exit: code=" + getStatusCode() + RESP + getResponse());
207 * URL:http://localhost:8080/vnfs/rest/v2/vnfs/<aaiVnfId>/vf-modules/<aaiVfModuleId>?cloudSiteId=DAN&tenantId=
208 * vfModule?&skipAAI=TRUE&msoRequest.requestId=ra1&msoRequest.serviceInstanceId=si1&vfModuleName=T2N2S1 RESP:
209 * {"queryVfModuleResponse": { "vfModuleId": "AvfmodId", "vfModuleOutputs": {"entry": { "key":
210 * "server_private_ip_1", "value": "10.100.1.25" }}, "vfModuleStackId":
211 * "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b", "vnfId": "AvnfID", "vnfStatus": "ACTIVE" }}
214 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
215 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
216 @ApiOperation(value = "QueryVfModule", response = Response.class, notes = "Query an existing vnfModule")
217 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully queried"),
218 @ApiResponse(code = 500, message = "query vnfModule failed, examine entity object for details")})
219 public Response queryVfModule(@ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
220 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
221 @ApiParam(value = "cloudSiteId", required = true) @QueryParam("cloudSiteId") String cloudSiteId,
222 @ApiParam(value = "cloudOwner", required = true) @QueryParam("cloudOwner") String cloudOwner,
223 @ApiParam(value = "tenantId", required = true) @QueryParam("tenantId") String tenantId,
224 @ApiParam(value = "vfModuleName", required = true) @QueryParam("vfModuleName") String vfModuleName, // RAA?
227 @ApiParam(value = "skipAAI", required = true) @QueryParam("skipAAI") Boolean skipAAI,
228 @ApiParam(value = "msoRequest.requestId",
229 required = true) @QueryParam("msoRequest.requestId") String requestId,
230 @ApiParam(value = "msoRequest.serviceInstanceId",
231 required = true) @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
232 @ApiParam(value = "mode", required = true) @QueryParam("mode") String mode) {
233 // This request responds synchronously only
234 logger.debug("Query vfModule enter:" + vfModuleName);
235 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
238 int respStatus = HttpStatus.SC_OK;
239 QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
240 Holder<Boolean> vnfExists = new Holder<Boolean>();
241 Holder<String> vfModuleId = new Holder<String>();
242 Holder<VnfStatus> status = new Holder<VnfStatus>();
243 Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
245 // Support different Adapter Implementations
246 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudSiteId);
247 adapter.queryVnf(cloudSiteId, cloudOwner, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId, status,
250 if (!vnfExists.value) {
251 logger.debug("vfModule not found");
252 respStatus = HttpStatus.SC_NOT_FOUND;
254 logger.debug("vfModule found" + vfModuleId.value + ", status=" + status.value);
255 qryResp.setVfModuleId(vfModuleId.value);
256 qryResp.setVnfStatus(status.value);
257 qryResp.setVfModuleOutputs(outputs.value);
259 logger.debug("Query vfModule exit");
260 return Response.status(respStatus).entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {}).build();
261 } catch (VnfException e) {
262 logger.error("{} {} {} {} {}", MessageEnum.RA_QUERY_VNF_ERR.toString(), vfModuleName, "queryVfModule",
263 ErrorCode.BusinessProcesssError.getValue(), "VnfException - queryVfModule", e);
264 VfModuleExceptionResponse excResp =
265 new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
266 return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
267 .entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {}).build();
272 * URL: http://localhost:8080/vnfs/rest/v2/vnfs/<aaivnfid>/vf-modules REQUEST: {"createVfModuleRequest":
273 * {"cloudSiteId": "DAN", "tenantId": "214b428a1f554c02935e66330f6a5409", "vnfId": "somevnfid", "vfModuleId":
274 * "somemodid", "vfModuleName": "RaaVnf1", "vnfType": "ApacheVnf", "vfModuleParams": {"entry": [ {"key":
275 * "network_id", "value": "59ed7b41-2983-413f-ba93-e7d437433916"}, {"key": "subnet_id", "value":
276 * "086c9298-5c57-49b7-bb2b-6fd5730c5d92"}, {"key": "server_name_0", "value": "RaaVnf1"} ]}, "failIfExists": true,
277 * "messageId": "ra.1", "notificationUrl": "http://localhost:8089/vnfmock", "skipAAI": true, "msoRequest": {
278 * "requestId": "ra1", "serviceInstanceId": "sa1" }} }
281 @Path("{aaiVnfId}/vf-modules")
282 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
283 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
284 @ApiOperation(value = "CreateVfModule", response = Response.class, notes = "Create a vnfModule")
285 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully created"),
286 @ApiResponse(code = 202, message = "create vnfModule request has been successfully accepted (async only)"),
287 @ApiResponse(code = 500, message = "create vnfModule failed, examine entity object for details")})
288 public Response createVfModule(
289 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
290 @ApiParam(value = "mode", required = true) @QueryParam("mode") String mode,
291 @ApiParam(value = "CreateVfModuleRequest", required = true) final CreateVfModuleRequest req) {
292 logger.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
293 if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
294 logger.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
295 return Response.status(HttpStatus.SC_BAD_REQUEST).type(MediaType.TEXT_PLAIN)
296 .entity("vnfid in URL does not match content").build();
299 CreateVfModuleTask task = new CreateVfModuleTask(req, mode);
300 if (req.isSynchronous()) {
301 // This is a synchronous request
303 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
305 // This is an asynchronous request
307 Thread t1 = new Thread(task);
309 } catch (Exception e) {
310 // problem handling create, send generic failure as sync resp to caller
311 logger.error("{} {} {} {}", MessageEnum.RA_CREATE_VNF_ERR.toString(), "createVfModule",
312 ErrorCode.BusinessProcesssError.getValue(), "Exception - createVfModule", e);
313 return Response.serverError().build();
315 // send sync response (ACK) to caller
316 logger.debug("createVfModule exit");
317 return Response.status(HttpStatus.SC_ACCEPTED).build();
321 public class CreateVfModuleTask implements Runnable {
322 private final CreateVfModuleRequest req;
323 private CreateVfModuleResponse response = null;
324 private VfModuleExceptionResponse eresp = null;
325 private boolean sendxml;
328 public CreateVfModuleTask(CreateVfModuleRequest req, String mode) {
330 this.sendxml = true; // can be set with a field or header later
334 public int getStatusCode() {
335 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
338 public Object getGenericEntityResponse() {
339 return (response != null) ? new GenericEntity<CreateVfModuleResponse>(response) {}
340 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
343 private String getResponse() {
344 if (response != null) {
345 return sendxml ? response.toXmlString() : response.toJsonString();
347 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
353 logger.debug("CreateVfModuleTask start");
355 // Synchronous Web Service Outputs
356 Holder<String> vfModuleStackId = new Holder<String>();
357 Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
358 Holder<VnfRollback> vnfRollback = new Holder<VnfRollback>();
359 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
360 logger.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
362 String cloudsiteId = req.getCloudSiteId();
363 String cloudOwner = req.getCloudOwner();
364 if (cloudsiteId != null && cloudsiteId.equals(TESTING_KEYWORD)) {
365 String tenant = req.getTenantId();
366 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
367 throw new VnfException("testing.");
369 vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudOwner, cloudsiteId, true, false,
370 new MsoRequest("reqid", "svcid"), req.getVolumeGroupId(), req.getVolumeGroupId(),
371 req.getRequestType(), req.getModelCustomizationUuid());
372 vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
373 outputs.value = VolumeAdapterRest.testMap();
375 // Support different Adapter Implementations
376 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsiteId);
377 adapter.createVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
378 completeVnfVfModuleType, req.getVnfVersion(), req.getVnfId(), req.getVfModuleName(),
379 req.getVfModuleId(), req.getRequestType(), req.getVolumeGroupStackId(),
380 req.getBaseVfModuleStackId(), req.getModelCustomizationUuid(), req.getVfModuleParams(),
381 req.getFailIfExists(), req.getBackout(), req.getEnableBridge(), req.getMsoRequest(),
382 vfModuleStackId, outputs, vnfRollback);
384 VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(),
385 vfModuleStackId.value, req.getMessageId());
386 response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(), vfModuleStackId.value,
387 Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
388 } catch (VnfException e) {
389 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE,
392 if (!req.isSynchronous()) {
393 BpelRestClient bpelClient = bpelRestClientProvider.get();
394 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
396 logger.debug("CreateVfModuleTask exit: code=" + getStatusCode() + RESP + getResponse());
401 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
402 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
403 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
404 @ApiOperation(value = "UpdateVfModule", response = Response.class, notes = "Update an existing vnfModule")
405 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully updated"),
406 @ApiResponse(code = 202, message = "update vnfModule request has been successfully accepted (async only)"),
407 @ApiResponse(code = 500, message = "update vnfModule failed, examine entity object for details")})
408 public Response updateVfModule(
409 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
410 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
411 @ApiParam(value = "mode", required = true) @QueryParam("mode") String mode,
412 @ApiParam(value = "UpdateVfModuleRequest", required = true) final UpdateVfModuleRequest req) {
413 logger.debug("Update VfModule enter: " + req.toJsonString());
414 UpdateVfModulesTask task = new UpdateVfModulesTask(req, mode);
415 if (req.isSynchronous()) {
416 // This is a synchronous request
418 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
420 // This is an asynchronous request
422 Thread t1 = new Thread(task);
424 } catch (Exception e) {
425 // problem handling create, send generic failure as sync resp to caller
426 logger.error("{} {} {} {}", MessageEnum.RA_UPDATE_VNF_ERR.toString(), "updateVfModule",
427 ErrorCode.BusinessProcesssError.getValue(), "Exception - updateVfModule", e);
428 return Response.serverError().build();
430 // send sync response (ACK) to caller
431 logger.debug("updateVfModules exit");
432 return Response.status(HttpStatus.SC_ACCEPTED).build();
436 public class UpdateVfModulesTask implements Runnable {
437 private final UpdateVfModuleRequest req;
438 private UpdateVfModuleResponse response = null;
439 private VfModuleExceptionResponse eresp = null;
440 private boolean sendxml;
443 public UpdateVfModulesTask(UpdateVfModuleRequest req, String mode) {
445 this.sendxml = true; // can be set with a field or header later
449 public int getStatusCode() {
450 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
453 public Object getGenericEntityResponse() {
454 return (response != null) ? new GenericEntity<UpdateVfModuleResponse>(response) {}
455 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
458 private String getResponse() {
459 if (response != null) {
460 return sendxml ? response.toXmlString() : response.toJsonString();
462 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
469 // MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
471 // Synchronous Web Service Outputs
472 Holder<String> vfModuleStackId = new Holder<String>();
473 Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
474 Holder<VnfRollback> vnfRollback = new Holder<VnfRollback>();
475 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
476 logger.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
478 String cloudsiteId = req.getCloudSiteId();
480 // Support different Adapter Implementations
481 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(mode, cloudsiteId);
482 adapter.updateVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
483 completeVnfVfModuleType, req.getVnfVersion(), req.getVfModuleName(), req.getRequestType(),
484 req.getVolumeGroupStackId(), req.getBaseVfModuleId(), req.getVfModuleStackId(),
485 req.getModelCustomizationUuid(), req.getVfModuleParams(), req.getMsoRequest(), outputs,
488 response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(), vfModuleStackId.value,
489 outputs.value, req.getMessageId());
490 } catch (VnfException e) {
491 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE,
494 if (!req.isSynchronous()) {
495 // This is asynch, so POST response back to caller
496 BpelRestClient bpelClient = bpelRestClientProvider.get();
497 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
499 logger.debug("Update VfModule exit: code=" + getStatusCode() + RESP + getResponse());
504 * URL:http://localhost:8080/vnfs/rest/v2/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback REQUEST:
505 * {"deleteVfModuleRequest": {"cloudSiteId": "DAN", "tenantId": "214b428a1f554c02935e66330f6a5409", "vnfId":
506 * "somevnfid", "vfModuleId": "somemodid", "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73", "messageId":
507 * "ra.1", "notificationUrl": "http://localhost:8089/vnfmock", "skipAAI": true, "msoRequest": { "requestId": "ra1",
508 * "serviceInstanceId": "sa1" }} }
511 @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
512 @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
513 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
514 @ApiOperation(value = "RollbackVfModule", response = Response.class, notes = "Rollback an existing vnfModule")
515 @ApiResponses({@ApiResponse(code = 200, message = "vnfModule has been successfully rolled back"),
516 @ApiResponse(code = 202,
517 message = "rollback vnfModule request has been successfully accepted (async only)"),
518 @ApiResponse(code = 500, message = "rollback vnfModule failed, examine entity object for details")})
519 public Response rollbackVfModule(
520 @ApiParam(value = "aaiVnfId", required = true) @PathParam("aaiVnfId") String aaiVnfId,
521 @ApiParam(value = "aaiVfModuleId", required = true) @PathParam("aaiVfModuleId") String aaiVfModuleId,
522 @ApiParam(value = "RollbackVfModuleRequest", required = true)
523 // @QueryParam("rollback") String rollback,
524 final RollbackVfModuleRequest req) {
525 logger.debug("Rollback VfModule enter: " + req.toJsonString());
526 RollbackVfModulesTask task = new RollbackVfModulesTask(req);
527 if (req.isSynchronous()) {
528 // This is a synchronous request
530 return Response.status(task.getStatusCode()).entity(task.getGenericEntityResponse()).build();
532 // This is an asynchronous request
534 Thread t1 = new Thread(task);
536 } catch (Exception e) {
537 // problem handling create, send generic failure as sync resp to caller
538 logger.error("{} {} {} {}", MessageEnum.RA_ROLLBACK_VNF_ERR.toString(), "rollbackVfModule",
539 ErrorCode.BusinessProcesssError.getValue(), "Exception - rollbackVfModule", e);
540 return Response.serverError().build();
542 // send sync response (ACK) to caller
543 logger.debug("rollbackVfModule exit");
544 return Response.status(HttpStatus.SC_ACCEPTED).build();
548 public class RollbackVfModulesTask implements Runnable {
549 private final RollbackVfModuleRequest req;
550 private RollbackVfModuleResponse response = null;
551 private VfModuleExceptionResponse eresp = null;
552 private boolean sendxml;
554 public RollbackVfModulesTask(RollbackVfModuleRequest req) {
556 this.sendxml = true; // can be set with a field or header later
559 public int getStatusCode() {
560 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
563 public Object getGenericEntityResponse() {
564 return (response != null) ? new GenericEntity<RollbackVfModuleResponse>(response) {}
565 : new GenericEntity<VfModuleExceptionResponse>(eresp) {};
568 private String getResponse() {
569 if (response != null) {
570 return sendxml ? response.toXmlString() : response.toJsonString();
572 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
579 VfModuleRollback vmr = req.getVfModuleRollback();
580 VnfRollback vrb = new VnfRollback(vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudOwner(),
581 vmr.getCloudSiteId(), true, vmr.isVfModuleCreated(), vmr.getMsoRequest(), null, null, null,
584 // Support multiple adapter implementations
585 MsoVnfAdapter adapter = vnfAdapterRestUtils.getVnfAdapterImpl(vmr.getMode(), vmr.getCloudSiteId());
586 adapter.rollbackVnf(vrb);
588 response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
589 } catch (VnfException e) {
590 logger.error("{} {} {}", MessageEnum.RA_ROLLBACK_VNF_ERR.toString(),
591 ErrorCode.BusinessProcesssError.getValue(), "Exception - rollbackVfModule", e);
592 eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false,
595 if (!req.isSynchronous()) {
596 // This is asynch, so POST response back to caller
597 BpelRestClient bpelClient = bpelRestClientProvider.get();
598 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
600 logger.debug("RollbackVfModulesTask exit: code=" + getStatusCode() + RESP + getResponse());