2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.adapters.vnf;
24 import java.util.HashMap;
27 import javax.ws.rs.Consumes;
28 import javax.ws.rs.DELETE;
29 import javax.ws.rs.GET;
30 import javax.ws.rs.POST;
31 import javax.ws.rs.PUT;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.QueryParam;
36 import javax.ws.rs.core.GenericEntity;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.Response;
39 import javax.xml.ws.Holder;
41 import org.apache.http.HttpStatus;
43 import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
44 import org.openecomp.mso.adapters.vnfrest.CreateVolumeGroupRequest;
45 import org.openecomp.mso.adapters.vnfrest.CreateVolumeGroupResponse;
46 import org.openecomp.mso.adapters.vnfrest.DeleteVolumeGroupRequest;
47 import org.openecomp.mso.adapters.vnfrest.DeleteVolumeGroupResponse;
48 import org.openecomp.mso.adapters.vnfrest.QueryVolumeGroupResponse;
49 import org.openecomp.mso.adapters.vnfrest.RollbackVolumeGroupRequest;
50 import org.openecomp.mso.adapters.vnfrest.RollbackVolumeGroupResponse;
51 import org.openecomp.mso.adapters.vnfrest.UpdateVolumeGroupRequest;
52 import org.openecomp.mso.adapters.vnfrest.UpdateVolumeGroupResponse;
53 import org.openecomp.mso.adapters.vnfrest.VolumeGroupExceptionResponse;
54 import org.openecomp.mso.adapters.vnfrest.VolumeGroupRollback;
55 import org.openecomp.mso.cloud.CloudConfigFactory;
56 import org.openecomp.mso.entity.MsoRequest;
57 import org.openecomp.mso.logger.MessageEnum;
58 import org.openecomp.mso.logger.MsoLogger;
59 import org.openecomp.mso.openstack.beans.VnfRollback;
60 import org.openecomp.mso.openstack.beans.VnfStatus;
61 import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
62 import org.openecomp.mso.properties.MsoPropertiesFactory;
65 * This class services calls to the REST interface for VNF Volumes (http://host:port/vnfs/rest/v1/volume-groups)
66 * Both XML and JSON can be produced/consumed. Set Accept: and Content-Type: headers appropriately. XML is the default.
67 * For testing, call with cloudSiteId = ___TESTING___
68 * To test exceptions, also set tenantId = ___TESTING___
70 @Path("/v1/volume-groups")
71 public class VolumeAdapterRest {
72 private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
73 private static final String TESTING_KEYWORD = "___TESTING___";
74 private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
75 private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
76 private final MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl(msoPropertiesFactory, cloudConfigFactory);
80 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
81 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
82 public Response createVNFVolumes(final CreateVolumeGroupRequest req) {
83 LOGGER.debug("createVNFVolumes enter: " + req.toJsonString());
84 CreateVNFVolumesTask task = new CreateVNFVolumesTask(req);
85 if (req.isSynchronous()) {
86 // This is a synchronous request
89 .status(task.getStatusCode())
90 .entity(task.getGenericEntityResponse())
93 // This is an asynchronous request
95 Thread t1 = new Thread(task);
97 } catch (Exception e) {
98 // problem handling create, send generic failure as sync resp to caller
99 LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, "", "createVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - createVNFVolumes", e);
100 return Response.serverError().build();
102 // send sync response (ACK) to caller
103 LOGGER.debug ("createVNFVolumes exit");
104 return Response.status(HttpStatus.SC_ACCEPTED).build();
108 public class CreateVNFVolumesTask implements Runnable {
109 private final CreateVolumeGroupRequest req;
110 private CreateVolumeGroupResponse response = null;
111 private VolumeGroupExceptionResponse eresp = null;
112 private boolean sendxml;
114 public CreateVNFVolumesTask(CreateVolumeGroupRequest req) {
116 this.sendxml = true; // can be set with a field or header later
118 public int getStatusCode() {
119 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
121 public Object getGenericEntityResponse() {
122 return (response != null)
123 ? new GenericEntity<CreateVolumeGroupResponse>(response) {}
124 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
126 private String getResponse() {
127 if (response != null) {
128 return sendxml ? response.toXmlString() : response.toJsonString();
130 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
135 LOGGER.debug ("CreateVFModule VolumesTask start");
137 // Synchronous Web Service Outputs
138 Holder<String> stackId = new Holder<String>();
139 Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
140 Holder<VnfRollback> vnfRollback = new Holder<VnfRollback>();
141 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
142 LOGGER.debug("in createVfModuleVolumes - completeVnfVfModuleType=" + completeVnfVfModuleType);
144 String cloudsite = req.getCloudSiteId();
145 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
146 String tenant = req.getTenantId();
147 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
148 throw new VnfException("testing.");
150 stackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
151 outputs.value = testMap();
153 // vnfAdapter.createVnf(
154 // req.getCloudSiteId(),
155 // req.getTenantId(),
157 // req.getVnfVersion(),
158 // req.getVolumeGroupName(),
159 // "VOLUME", // request type is VOLUME
160 // null, // not sure about this
161 // req.getVolumeGroupParams(),
162 // req.getFailIfExists(),
163 // req.getSuppressBackout(),
164 // req.getMsoRequest(),
168 vnfAdapter.createVfModule(
169 req.getCloudSiteId(), //cloudSiteId,
170 req.getTenantId(), //tenantId,
171 //req.getVnfType(), //vnfType,
172 completeVnfVfModuleType,
173 req.getVnfVersion(), //vnfVersion,
174 req.getVolumeGroupName(), //vnfName,
175 "VOLUME", //requestType,
176 null, //volumeGroupHeatStackId,
177 null, //baseVfHeatStackId,
178 req.getModelCustomizationUuid(),
179 req.getVolumeGroupParams(), //inputs,
180 req.getFailIfExists(), //failIfExists,
181 req.getSuppressBackout(), //backout,
182 req.getMsoRequest(), // msoRequest,
187 VolumeGroupRollback rb = new VolumeGroupRollback(
188 req.getVolumeGroupId(),
190 true, // TODO boolean volumeGroupCreated, when would it be false?
192 req.getCloudSiteId(),
195 response = new CreateVolumeGroupResponse(
196 req.getVolumeGroupId(),
198 true, // TODO boolean volumeGroupCreated, when would it be false?
202 } catch (VnfException e) {
203 eresp = new VolumeGroupExceptionResponse(
204 e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
206 if (!req.isSynchronous()) {
207 // This is asynch, so POST response back to caller
208 BpelRestClient bpelClient = new BpelRestClient();
209 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
211 LOGGER.debug ("CreateVFModule VolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
216 @Path("{aaiVolumeGroupId}")
217 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
218 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
219 public Response deleteVNFVolumes(
220 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
221 final DeleteVolumeGroupRequest req
224 LOGGER.debug("deleteVNFVolumes enter: " + req.toJsonString());
225 if (aaiVolumeGroupId == null || !aaiVolumeGroupId.equals(req.getVolumeGroupId())) {
227 .status(HttpStatus.SC_BAD_REQUEST)
228 .type(MediaType.TEXT_PLAIN)
229 .entity("VolumeGroupId in URL does not match content")
232 DeleteVNFVolumesTask task = new DeleteVNFVolumesTask(req);
233 if (req.isSynchronous()) {
234 // This is a synchronous request
237 .status(task.getStatusCode())
238 .entity(task.getGenericEntityResponse())
241 // This is an asynchronous request
243 Thread t1 = new Thread(task);
245 } catch (Exception e) {
246 // problem handling create, send generic failure as sync resp to caller
247 LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "deleteVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - deleteVNFVolumes", e);
248 return Response.serverError().build();
250 // send sync response (ACK) to caller
251 LOGGER.debug ("deleteVNFVolumes exit");
252 return Response.status(HttpStatus.SC_ACCEPTED).build();
256 public class DeleteVNFVolumesTask implements Runnable {
257 private final DeleteVolumeGroupRequest req;
258 private DeleteVolumeGroupResponse response = null;
259 private VolumeGroupExceptionResponse eresp = null;
260 private boolean sendxml;
262 public DeleteVNFVolumesTask(DeleteVolumeGroupRequest req) {
264 this.sendxml = true; // can be set with a field or header later
266 public int getStatusCode() {
267 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
269 public Object getGenericEntityResponse() {
270 return (response != null)
271 ? new GenericEntity<DeleteVolumeGroupResponse>(response) {}
272 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
274 private String getResponse() {
275 if (response != null) {
276 return sendxml ? response.toXmlString() : response.toJsonString();
278 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
283 LOGGER.debug("DeleteVNFVolumesTask start");
285 if (!req.getCloudSiteId().equals(TESTING_KEYWORD)) {
286 vnfAdapter.deleteVnf(req.getCloudSiteId(), req.getTenantId(), req.getVolumeGroupStackId(), req.getMsoRequest());
288 response = new DeleteVolumeGroupResponse(true, req.getMessageId());
289 } catch (VnfException e) {
290 eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
292 if (!req.isSynchronous()) {
293 // This is asynch, so POST response back to caller
294 BpelRestClient bpelClient = new BpelRestClient();
295 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
297 LOGGER.debug("DeleteVNFVolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
302 @Path("{aaiVolumeGroupId}/rollback")
303 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
304 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
305 public Response rollbackVNFVolumes(
306 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
307 final RollbackVolumeGroupRequest req
310 LOGGER.debug("rollbackVNFVolumes enter: " + req.toJsonString());
311 if (aaiVolumeGroupId == null || req.getVolumeGroupRollback() == null || !aaiVolumeGroupId.equals(req.getVolumeGroupRollback().getVolumeGroupId())) {
313 .status(HttpStatus.SC_BAD_REQUEST)
314 .type(MediaType.TEXT_PLAIN)
315 .entity("VolumeGroupId in URL does not match content")
318 RollbackVNFVolumesTask task = new RollbackVNFVolumesTask(req);
319 if (req.isSynchronous()) {
320 // This is a synchronous request
323 .status(task.getStatusCode())
324 .entity(task.getGenericEntityResponse())
327 // This is an asynchronous request
329 Thread t1 = new Thread(task);
331 } catch (Exception e) {
332 // problem handling create, send generic failure as sync resp to caller
333 LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVNFVolumes", e);
334 return Response.serverError().build();
336 // send sync response (ACK) to caller
337 LOGGER.debug("rollbackVNFVolumes exit");
338 return Response.status(HttpStatus.SC_ACCEPTED).build();
342 public class RollbackVNFVolumesTask implements Runnable {
343 private final RollbackVolumeGroupRequest req;
344 private RollbackVolumeGroupResponse response = null;
345 private VolumeGroupExceptionResponse eresp = null;
346 private boolean sendxml;
348 public RollbackVNFVolumesTask(RollbackVolumeGroupRequest req) {
350 this.sendxml = true; // can be set with a field or header later
352 public int getStatusCode() {
353 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
355 public Object getGenericEntityResponse() {
356 return (response != null)
357 ? new GenericEntity<RollbackVolumeGroupResponse>(response) {}
358 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
360 private String getResponse() {
361 if (response != null) {
362 return sendxml ? response.toXmlString() : response.toJsonString();
364 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
369 LOGGER.debug("DeleteVNFVolumesTask start");
371 VolumeGroupRollback vgr = req.getVolumeGroupRollback();
372 VnfRollback vrb = new VnfRollback(
373 vgr.getVolumeGroupStackId(), vgr.getTenantId(), vgr.getCloudSiteId(), true, true,
374 vgr.getMsoRequest(), null, null, null, null);
375 vnfAdapter.rollbackVnf(vrb);
376 response = new RollbackVolumeGroupResponse(true, req.getMessageId());
377 } catch (VnfException e) {
378 eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
380 if (!req.isSynchronous()) {
381 // This is asynch, so POST response back to caller
382 BpelRestClient bpelClient = new BpelRestClient();
383 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
385 LOGGER.debug("DeleteVNFVolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
391 @Path("{aaiVolumeGroupId}")
392 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
393 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
394 public Response updateVNFVolumes(
395 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
396 final UpdateVolumeGroupRequest req
399 LOGGER.debug("updateVNFVolumes enter: " + req.toJsonString());
400 if (aaiVolumeGroupId == null || !aaiVolumeGroupId.equals(req.getVolumeGroupId())) {
402 .status(HttpStatus.SC_BAD_REQUEST)
403 .type(MediaType.TEXT_PLAIN)
404 .entity("VolumeGroupId in URL does not match content")
407 UpdateVNFVolumesTask task = new UpdateVNFVolumesTask(req);
408 if (req.isSynchronous()) {
409 // This is a synchronous request
412 .status(task.getStatusCode())
413 .entity(task.getGenericEntityResponse())
416 // This is an asynchronous request
418 Thread t1 = new Thread(task);
420 } catch (Exception e) {
421 // problem handling create, send generic failure as sync resp to caller
422 LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, "", "updateVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - updateVNFVolumes", e);
423 return Response.serverError().build();
425 // send sync response (ACK) to caller
426 LOGGER.debug ("updateVNFVolumes exit");
427 return Response.status(HttpStatus.SC_ACCEPTED).build();
431 public class UpdateVNFVolumesTask implements Runnable {
432 private final UpdateVolumeGroupRequest req;
433 private UpdateVolumeGroupResponse response = null;
434 private VolumeGroupExceptionResponse eresp = null;
435 private boolean sendxml;
437 public UpdateVNFVolumesTask(UpdateVolumeGroupRequest req) {
439 this.sendxml = true; // can be set with a field or header later
441 public int getStatusCode() {
442 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
444 public Object getGenericEntityResponse() {
445 return (response != null)
446 ? new GenericEntity<UpdateVolumeGroupResponse>(response) {}
447 : new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
449 private String getResponse() {
450 if (response != null) {
451 return sendxml ? response.toXmlString() : response.toJsonString();
453 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
458 LOGGER.debug("UpdateVNFVolumesTask start");
460 @SuppressWarnings("unused")
461 Holder<String> stackId = new Holder<String> ();
462 Holder<Map<String, String>> outputs = new Holder<Map <String, String>> ();
463 Holder<VnfRollback> vnfRollback = new Holder<VnfRollback> ();
464 String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
465 LOGGER.debug("in updateVfModuleVolume - completeVnfVfModuleType=" + completeVnfVfModuleType);
467 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
468 outputs.value = testMap();
470 //vnfAdapter.updateVnf(
471 // req.getCloudSiteId(),
472 // req.getTenantId(),
474 // req.getVnfVersion(),
475 // req.getVfModuleType(),
476 // "VOLUME", // request type is VOLUME
477 // req.getVolumeGroupStackId(),
478 // req.getVolumeGroupParams(),
479 // req.getMsoRequest(),
482 vnfAdapter.updateVfModule (req.getCloudSiteId(),
485 completeVnfVfModuleType,
487 req.getVolumeGroupStackId(),
491 req.getVolumeGroupStackId(),
492 req.getModelCustomizationUuid(),
493 req.getVolumeGroupParams(),
498 response = new UpdateVolumeGroupResponse(
499 req.getVolumeGroupId(), req.getVolumeGroupStackId(),
500 outputs.value, req.getMessageId());
501 } catch (VnfException e) {
502 eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
504 if (!req.isSynchronous()) {
505 // This is asynch, so POST response back to caller
506 BpelRestClient bpelClient = new BpelRestClient();
507 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
509 LOGGER.debug("UpdateVNFVolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
514 @Path("{aaiVolumeGroupId}")
515 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
516 public Response queryVNFVolumes(
517 @PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
518 @QueryParam("cloudSiteId") String cloudSiteId,
519 @QueryParam("tenantId") String tenantId,
520 @QueryParam("volumeGroupStackId") String volumeGroupStackId,
521 @QueryParam("skipAAI") Boolean skipAAI,
522 @QueryParam("msoRequest.requestId") String requestId,
523 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId
526 //This request responds synchronously only
527 LOGGER.debug ("queryVNFVolumes enter:" + aaiVolumeGroupId + " " + volumeGroupStackId);
528 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
531 int respStatus = HttpStatus.SC_OK;
532 QueryVolumeGroupResponse qryResp = new QueryVolumeGroupResponse(aaiVolumeGroupId, volumeGroupStackId, null, null);
533 Holder<Boolean> vnfExists = new Holder<Boolean>();
534 Holder<String> vfModuleId = new Holder<String>();
535 Holder<VnfStatus> status = new Holder<VnfStatus>();
536 Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
537 if (cloudSiteId != null && cloudSiteId.equals(TESTING_KEYWORD)) {
538 if (tenantId != null && tenantId.equals(TESTING_KEYWORD)) {
539 throw new VnfException("testing.");
541 vnfExists.value = true;
542 vfModuleId.value = TESTING_KEYWORD;
543 status.value = VnfStatus.ACTIVE;
544 outputs.value = testMap();
546 vnfAdapter.queryVnf(cloudSiteId, tenantId, volumeGroupStackId, msoRequest, vnfExists, vfModuleId, status, outputs);
548 if (!vnfExists.value) {
549 LOGGER.debug ("VNFVolumes not found");
550 qryResp.setVolumeGroupStatus(status.value);
551 respStatus = HttpStatus.SC_NOT_FOUND;
553 LOGGER.debug ("VNFVolumes found " + vfModuleId.value + ", status=" + status.value);
554 qryResp.setVolumeGroupStatus(status.value);
555 qryResp.setVolumeGroupOutputs(outputs.value);
557 LOGGER.debug("Query queryVNFVolumes exit");
560 .entity(new GenericEntity<QueryVolumeGroupResponse>(qryResp) {})
562 } catch (VnfException e) {
563 LOGGER.error(MessageEnum.RA_QUERY_VNF_ERR, aaiVolumeGroupId, "", "queryVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - queryVNFVolumes", e);
564 VolumeGroupExceptionResponse excResp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
565 LOGGER.debug("Query queryVNFVolumes exit");
567 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
568 .entity(new GenericEntity<VolumeGroupExceptionResponse>(excResp) {})
572 public static Map<String, String> testMap() {
573 Map<String, String> m = new HashMap<String, String>();
574 m.put("mickey", "7");
575 m.put("clyde", "10");
576 m.put("wayne", "99");