diff options
Diffstat (limited to 'adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java')
-rw-r--r-- | adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java | 595 |
1 files changed, 595 insertions, 0 deletions
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java new file mode 100644 index 0000000000..c813534212 --- /dev/null +++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java @@ -0,0 +1,595 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.adapters.network; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.ws.Holder; + +import org.apache.http.HttpStatus; + +import org.openecomp.mso.adapters.network.exceptions.NetworkException; +import org.openecomp.mso.adapters.nwrest.ContrailNetwork; +import org.openecomp.mso.adapters.nwrest.CreateNetworkError; +import org.openecomp.mso.adapters.nwrest.CreateNetworkRequest; +import org.openecomp.mso.adapters.nwrest.CreateNetworkResponse; +import org.openecomp.mso.adapters.nwrest.DeleteNetworkError; +import org.openecomp.mso.adapters.nwrest.DeleteNetworkRequest; +import org.openecomp.mso.adapters.nwrest.DeleteNetworkResponse; +import org.openecomp.mso.adapters.nwrest.ProviderVlanNetwork; +import org.openecomp.mso.adapters.nwrest.QueryNetworkError; +import org.openecomp.mso.adapters.nwrest.QueryNetworkResponse; +import org.openecomp.mso.adapters.nwrest.RollbackNetworkError; +import org.openecomp.mso.adapters.nwrest.RollbackNetworkRequest; +import org.openecomp.mso.adapters.nwrest.RollbackNetworkResponse; +import org.openecomp.mso.adapters.nwrest.UpdateNetworkError; +import org.openecomp.mso.adapters.nwrest.UpdateNetworkRequest; +import org.openecomp.mso.adapters.nwrest.UpdateNetworkResponse; +import org.openecomp.mso.cloud.CloudConfigFactory; +import org.openecomp.mso.entity.MsoRequest; +import org.openecomp.mso.logger.MessageEnum; +import org.openecomp.mso.logger.MsoLogger; +import org.openecomp.mso.openstack.beans.NetworkRollback; +import org.openecomp.mso.openstack.beans.NetworkStatus; +import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory; +import org.openecomp.mso.properties.MsoPropertiesFactory; + +@Path("/v1/networks") +public class NetworkAdapterRest { + private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); + private static final String TESTING_KEYWORD = "___TESTING___"; + private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); + private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory(); + private final MsoNetworkAdapterImpl adapter = new MsoNetworkAdapterImpl(msoPropertiesFactory, cloudConfigFactory); + + @POST + @Path("") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response createNetwork(CreateNetworkRequest req) { + LOGGER.debug("createNetwork enter: " + req.toJsonString()); + CreateNetworkTask task = new CreateNetworkTask(req); + if (req.isSynchronous()) { + // This is a synchronous request + task.run(); + return Response + .status(task.getStatusCode()) + .entity(task.getGenericEntityResponse()) + .build(); + } else { + // This is an asynchronous request + try { + Thread t1 = new Thread(task); + t1.start(); + } catch (Exception e) { + // problem handling create, send generic failure as sync resp to caller + LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while create network", e); + return Response.serverError().build(); + } + // send sync response (ACK) to caller + LOGGER.debug ("createNetwork exit"); + return Response.status(HttpStatus.SC_ACCEPTED).build(); + } + } + + public class CreateNetworkTask implements Runnable { + private final CreateNetworkRequest req; + private CreateNetworkResponse response = null; + private CreateNetworkError eresp = null; + private boolean sendxml; + + public CreateNetworkTask(CreateNetworkRequest req) { + this.req = req; + this.sendxml = true; // can be set with a field or header later + } + public int getStatusCode() { + return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST; + } + public Object getGenericEntityResponse() { + return (response != null) + ? new GenericEntity<CreateNetworkResponse>(response) {} + : new GenericEntity<CreateNetworkError>(eresp) {}; + } + private String getResponse() { + if (response != null) { + return sendxml ? response.toXmlString() : response.toJsonString(); + } else { + return sendxml ? eresp.toXmlString() : eresp.toJsonString(); + } + } + @Override + public void run() { + LOGGER.debug ("CreateNetworkTask start"); + try { + // Synchronous Web Service Outputs + Holder<String> networkId = new Holder<String>(); + Holder<String> neutronNetworkId = new Holder<String>(); + Holder<String> networkFqdn = new Holder<String>(); + Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>(); + Holder<NetworkRollback> rollback = new Holder<NetworkRollback>(); + + String cloudsite = req.getCloudSiteId(); + if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) { + String tenant = req.getTenantId(); + if (tenant != null && tenant.equals(TESTING_KEYWORD)) { + throw new NetworkException("testing."); + } + networkId.value = "479D3D8B-6360-47BC-AB75-21CC91981484"; + neutronNetworkId.value = "55e55884-28fa-11e6-8971-0017f20fe1b8"; + networkFqdn.value = "086f70b6-28fb-11e6-8260-0017f20fe1b8"; + subnetIdMap.value = testMap(); + rollback.value = new NetworkRollback(); + } else if (req.isContrailRequest()) { + ContrailNetwork ctn = req.getContrailNetwork(); + if (ctn == null) { + ctn = new ContrailNetwork(); + req.setContrailNetwork(ctn); + } + adapter.createNetworkContrail( + req.getCloudSiteId(), + req.getTenantId(), + req.getNetworkType(), + req.getNetworkName(), + req.getContrailNetwork().getRouteTargets(), + req.getContrailNetwork().getShared(), + req.getContrailNetwork().getExternal(), + req.getFailIfExists(), + req.getBackout(), + req.getSubnets(), + req.getContrailNetwork().getPolicyFqdns(), + req.getContrailNetwork().getRouteTableFqdns(), + req.getMsoRequest(), + networkId, + neutronNetworkId, + networkFqdn, + subnetIdMap, + rollback); + } else { + ProviderVlanNetwork pvn = req.getProviderVlanNetwork(); + if (pvn == null) { + pvn = new ProviderVlanNetwork(); + req.setProviderVlanNetwork(pvn); + } + adapter.createNetwork( + req.getCloudSiteId(), + req.getTenantId(), + req.getNetworkType(), + req.getNetworkName(), + req.getProviderVlanNetwork().getPhysicalNetworkName(), + req.getProviderVlanNetwork().getVlans(), + req.getFailIfExists(), + req.getBackout(), + req.getSubnets(), + req.getMsoRequest(), + networkId, + neutronNetworkId, + subnetIdMap, + rollback); + } + response = new CreateNetworkResponse( + req.getNetworkId(), + neutronNetworkId.value, + rollback.value.getNetworkStackId(), + networkFqdn.value, + rollback.value.getNetworkCreated(), + subnetIdMap.value, + rollback.value, + req.getMessageId()); + } catch (NetworkException e) { + eresp = new CreateNetworkError( + e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); + } + if (!req.isSynchronous()) { + // This is asynch, so POST response back to caller + BpelRestClient bpelClient = new BpelRestClient(); + bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); + } + LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + } + } + + @DELETE + @Path("{aaiNetworkId}") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response deleteNetwork( + @PathParam("aaiNetworkId") String aaiNetworkId, + DeleteNetworkRequest req) + { + LOGGER.debug("deleteNetwork enter: " + req.toJsonString()); + if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) { + return Response + .status(HttpStatus.SC_BAD_REQUEST) + .type(MediaType.TEXT_PLAIN) + .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")") + .build(); + } + DeleteNetworkTask task = new DeleteNetworkTask(req); + if (req.isSynchronous()) { + // This is a synchronous request + task.run(); + return Response + .status(task.getStatusCode()) + .entity(task.getGenericEntityResponse()) + .build(); + } else { + // This is an asynchronous request + try { + Thread t1 = new Thread(task); + t1.start(); + } catch (Exception e) { + // problem handling create, send generic failure as sync resp to caller + LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while delete network", e); + return Response.serverError().build(); + } + // send sync response (ACK) to caller + LOGGER.debug ("deleteNetwork exit"); + return Response.status(HttpStatus.SC_ACCEPTED).build(); + } + } + + public class DeleteNetworkTask implements Runnable { + private final DeleteNetworkRequest req; + private DeleteNetworkResponse response = null; + private DeleteNetworkError eresp = null; + private boolean sendxml; + + public DeleteNetworkTask(DeleteNetworkRequest req) { + this.req = req; + this.sendxml = true; // can be set with a field or header later + } + public int getStatusCode() { + return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST; + } + public Object getGenericEntityResponse() { + return (response != null) + ? new GenericEntity<DeleteNetworkResponse>(response) {} + : new GenericEntity<DeleteNetworkError>(eresp) {}; + } + private String getResponse() { + if (response != null) { + return sendxml ? response.toXmlString() : response.toJsonString(); + } else { + return sendxml ? eresp.toXmlString() : eresp.toJsonString(); + } + } + @Override + public void run() { + LOGGER.debug("DeleteNetworkTask start"); + try { + Holder<Boolean> networkDeleted = new Holder<Boolean>(); + if (req.getCloudSiteId().equals(TESTING_KEYWORD)) { + networkDeleted.value = true; + } else { + adapter.deleteNetwork( + req.getCloudSiteId(), + req.getTenantId(), + req.getNetworkType(), + req.getNetworkStackId(), + req.getMsoRequest(), + networkDeleted); + } + response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId()); + } catch (NetworkException e) { + eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); + } + if (!req.isSynchronous()) { + // This is asynch, so POST response back to caller + BpelRestClient bpelClient = new BpelRestClient(); + bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); + } + LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + } + } + + @GET + @Path("{aaiNetworkId}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response queryNetwork( + @QueryParam("cloudSiteId") String cloudSiteId, + @QueryParam("tenantId") String tenantId, + @QueryParam("networkStackId") String networkStackId, + @QueryParam("skipAAI") String skipAAI, + @QueryParam("msoRequest.requestId") String requestId, + @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId, + @PathParam("aaiNetworkId") String aaiNetworkId) + { + //This request responds synchronously only + LOGGER.debug ("Query network enter:" + aaiNetworkId); + MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId); + + try { + int respStatus = HttpStatus.SC_OK; + QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null); + Holder<Boolean> networkExists = new Holder<Boolean>(); + Holder<String> networkId = new Holder<String>(); + Holder<String> neutronNetworkId = new Holder<String>(); + Holder<NetworkStatus> status = new Holder<NetworkStatus>(); + Holder<List<String>> routeTargets = new Holder<List<String>>(); + Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>(); + + adapter.queryNetworkContrail(cloudSiteId, tenantId, aaiNetworkId, msoRequest, + networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap); + + if (!networkExists.value) { + LOGGER.debug ("network not found"); + respStatus = HttpStatus.SC_NOT_FOUND; + } else { + LOGGER.debug ("network found" + networkId.value + ", status=" + status.value); + resp.setNetworkExists(networkExists.value); + resp.setNetworkId(networkId.value); + resp.setNeutronNetworkId(neutronNetworkId.value); + resp.setNetworkStatus(status.value); + resp.setRouteTargets(routeTargets.value); + resp.setSubnetIdMap(subnetIdMap.value); + } + LOGGER.debug ("Query network exit"); + return Response + .status(respStatus) + .entity(new GenericEntity<QueryNetworkResponse>(resp) {}) + .build(); + } catch (NetworkException e) { + LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, aaiNetworkId, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception when query VNF", e); + QueryNetworkError err = new QueryNetworkError(); + err.setMessage(e.getMessage()); + err.setCategory(MsoExceptionCategory.INTERNAL); + return Response + .status(HttpStatus.SC_INTERNAL_SERVER_ERROR) + .entity(new GenericEntity<QueryNetworkError>(err) {}) + .build(); + } + } + + @DELETE + @Path("{aaiNetworkId}/rollback") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response rollbackNetwork( + RollbackNetworkRequest req) + { + LOGGER.debug("rollbackNetwork enter: " + req.toJsonString()); + RollbackNetworkTask task = new RollbackNetworkTask(req); + if (req.isSynchronous()) { + // This is a synchronous request + task.run(); + return Response + .status(task.getStatusCode()) + .entity(task.getGenericEntityResponse()) + .build(); + } else { + // This is an asynchronous request + try { + Thread t1 = new Thread(task); + t1.start(); + } catch (Exception e) { + // problem handling create, send generic failure as sync resp to caller + LOGGER.error (MessageEnum.RA_ROLLBACK_NULL, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in rollbackNetwork", e); + return Response.serverError().build(); + } + // send sync response (ACK) to caller + LOGGER.debug("rollbackNetwork exit"); + return Response.status(HttpStatus.SC_ACCEPTED).build(); + } + } + + public class RollbackNetworkTask implements Runnable { + private final RollbackNetworkRequest req; + private RollbackNetworkResponse response = null; + private RollbackNetworkError eresp = null; + private boolean sendxml; + + public RollbackNetworkTask(RollbackNetworkRequest req) { + this.req = req; + this.sendxml = true; // can be set with a field or header later + } + public int getStatusCode() { + return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST; + } + public Object getGenericEntityResponse() { + return (response != null) + ? new GenericEntity<RollbackNetworkResponse>(response) {} + : new GenericEntity<RollbackNetworkError>(eresp) {}; + } + private String getResponse() { + if (response != null) { + return sendxml ? response.toXmlString() : response.toJsonString(); + } else { + return sendxml ? eresp.toXmlString() : eresp.toJsonString(); + } + } + @Override + public void run() { + LOGGER.debug("RollbackNetworkTask start"); + try { + NetworkRollback nwr = req.getNetworkRollback(); + adapter.rollbackNetwork(nwr); + response = new RollbackNetworkResponse(true, req.getMessageId()); + } catch (NetworkException e) { + eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); + } + if (!req.isSynchronous()) { + // This is asynch, so POST response back to caller + BpelRestClient bpelClient = new BpelRestClient(); + bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); + } + LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + } + } + + @PUT + @Path("{aaiNetworkId}") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response updateNetwork( + @PathParam("aaiNetworkId") String aaiNetworkId, + UpdateNetworkRequest req) + { + LOGGER.debug("updateNetwork enter: " + req.toJsonString()); + if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) { + return Response + .status(HttpStatus.SC_BAD_REQUEST) + .type(MediaType.TEXT_PLAIN) + .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")") + .build(); + } + UpdateNetworkTask task = new UpdateNetworkTask(req); + if (req.isSynchronous()) { + // This is a synchronous request + task.run(); + return Response + .status(task.getStatusCode()) + .entity(task.getGenericEntityResponse()) + .build(); + } else { + // This is an asynchronous request + try { + Thread t1 = new Thread(task); + t1.start(); + } catch (Exception e) { + // problem handling create, send generic failure as sync resp to caller + LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateNetwork", e); + return Response.serverError().build(); + } + // send sync response (ACK) to caller + LOGGER.debug ("updateNetwork exit"); + return Response.status(HttpStatus.SC_ACCEPTED).build(); + } + } + + public class UpdateNetworkTask implements Runnable { + private final UpdateNetworkRequest req; + private UpdateNetworkResponse response = null; + private UpdateNetworkError eresp = null; + private boolean sendxml; + + public UpdateNetworkTask(UpdateNetworkRequest req) { + this.req = req; + this.sendxml = true; // can be set with a field or header later + } + public int getStatusCode() { + return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST; + } + public Object getGenericEntityResponse() { + return (response != null) + ? new GenericEntity<UpdateNetworkResponse>(response) {} + : new GenericEntity<UpdateNetworkError>(eresp) {}; + } + private String getResponse() { + if (response != null) { + return sendxml ? response.toXmlString() : response.toJsonString(); + } else { + return sendxml ? eresp.toXmlString() : eresp.toJsonString(); + } + } + @Override + public void run() { + LOGGER.debug("UpdateNetworkTask start"); + try { + Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>(); + Holder<NetworkRollback> rollback = new Holder<NetworkRollback> (); + + if (req.getCloudSiteId().equals(TESTING_KEYWORD)) { + subnetIdMap.value = testMap(); + NetworkRollback rb = new NetworkRollback (); + rb.setCloudId(req.getCloudSiteId()); + rb.setTenantId(req.getTenantId()); + rb.setMsoRequest(req.getMsoRequest()); + rollback.value = rb; + } else if (req.isContrailRequest()) { + ContrailNetwork ctn = req.getContrailNetwork(); + if (ctn == null) { + ctn = new ContrailNetwork(); + req.setContrailNetwork(ctn); + } + adapter.updateNetworkContrail( + req.getCloudSiteId(), + req.getTenantId(), + req.getNetworkType(), + req.getNetworkStackId(), + req.getNetworkName(), + req.getContrailNetwork().getRouteTargets(), + req.getContrailNetwork().getShared(), + req.getContrailNetwork().getExternal(), + req.getSubnets(), + req.getContrailNetwork().getPolicyFqdns(), + req.getContrailNetwork().getRouteTableFqdns(), + req.getMsoRequest(), + subnetIdMap, + rollback); + } else { + ProviderVlanNetwork pvn = req.getProviderVlanNetwork(); + if (pvn == null) { + pvn = new ProviderVlanNetwork(); + req.setProviderVlanNetwork(pvn); + } + adapter.updateNetwork( + req.getCloudSiteId(), + req.getTenantId(), + req.getNetworkType(), + req.getNetworkStackId(), + req.getNetworkName(), + req.getProviderVlanNetwork().getPhysicalNetworkName(), + req.getProviderVlanNetwork().getVlans(), + req.getSubnets(), + req.getMsoRequest(), + subnetIdMap, + rollback); + } + response = new UpdateNetworkResponse( + req.getNetworkId(), + null, // NeutronNetworkId is not available from an update + subnetIdMap.value, + req.getMessageId()); + } catch (NetworkException e) { + eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); + } + if (!req.isSynchronous()) { + // This is asynch, so POST response back to caller + BpelRestClient bpelClient = new BpelRestClient(); + bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); + } + LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + } + } + + public static Map<String, String> testMap() { + Map<String, String> m = new HashMap<String, String>(); + m.put("mickey", "7"); + m.put("clyde", "10"); + m.put("wayne", "99"); + return m; + } +} |