From 3835d91556ed661b9b9711950aafbffa1d6a92e0 Mon Sep 17 00:00:00 2001 From: Madhu Venugopal Date: Fri, 2 Aug 2013 06:59:47 -0700 Subject: [PATCH] NorthBound APIs for the Bridge Domain configuration Service. This is the first cut NB-APIs and the enunciate documentation will be generated once the Jenkins Verify is complete @ https://jenkins.opendaylight.org/controller/job/controller-verify/ws/opendaylight/northbound/networkconfiguration/bridgedomain/target/site/wsdocs/index.html At a high level, the current version supports the following APIs : 1. Connect : PUT http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/mgmt1/172.28.30.51/6634 Response Data : xml : json: {"@type": "STUB","@id": "mgmt1"} 2. Connect : PUT http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/STUB/mgmt1/172.28.30.51/6634 Response Data : xml : json: {"@type": "STUB","@id": "mgmt1"} 3. Create Bridge : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1 4. Add Port : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1 5. Add Port, Vlan : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port2/200 Change-Id: Ic55f6bd20859b78a0e004a39388ee358eae5e61a Signed-off-by: Madhu Venugopal --- .../distribution/opendaylight/pom.xml | 1 + .../bridgedomain/enunciate.xml | 12 + .../networkconfiguration/bridgedomain/pom.xml | 108 ++++++ .../northbound/BridgeDomainNorthbound.java | 336 ++++++++++++++++++ .../BridgeDomainNorthboundApplication.java | 30 ++ .../src/main/resources/WEB-INF/web.xml | 51 +++ 6 files changed, 538 insertions(+) create mode 100644 opendaylight/northbound/networkconfiguration/bridgedomain/enunciate.xml create mode 100644 opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml create mode 100644 opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthbound.java create mode 100644 opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthboundApplication.java create mode 100644 opendaylight/northbound/networkconfiguration/bridgedomain/src/main/resources/WEB-INF/web.xml diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 807dea52e3..97f6878591 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -94,6 +94,7 @@ ../../northbound/hosttracker ../../northbound/subnets ../../northbound/switchmanager + ../../northbound/networkconfiguration/bridgedomain ../../northbound/integrationtest diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/enunciate.xml b/opendaylight/northbound/networkconfiguration/bridgedomain/enunciate.xml new file mode 100644 index 0000000000..f5a7ef1233 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/enunciate.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml b/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml new file mode 100644 index 0000000000..cba14fdc78 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + org.opendaylight.controller + commons.opendaylight + 1.4.0-SNAPSHOT + ../../../commons/opendaylight + + + networkconfig.bridgedomain.northbound + 0.0.1-SNAPSHOT + bundle + + + + org.codehaus.enunciate + maven-enunciate-plugin + ${enunciate.version} + + + org.opendaylight.controller + sal + 0.5.0-SNAPSHOT + + + + + org.apache.felix + maven-bundle-plugin + 2.3.6 + true + + + + + + org.opendaylight.controller.sal.core, + org.opendaylight.controller.sal.utils, + org.opendaylight.controller.sal.networkconfig.bridgedomain, + org.opendaylight.controller.containermanager, + org.opendaylight.controller.usermanager, + com.sun.jersey.spi.container.servlet, + org.opendaylight.controller.northbound.commons, + org.opendaylight.controller.northbound.commons.exception, + org.opendaylight.controller.northbound.commons.utils, + org.opendaylight.controller.sal.authorization, + org.opendaylight.controller.connectionmanager, + org.opendaylight.controller.sal.connection, + org.slf4j, + javax.ws.rs, + javax.ws.rs.core, + javax.xml.bind.annotation, + javax.xml.bind, + !org.codehaus.enunciate.jaxrs + + + + /controller/nb/v2/networkconfig/bridgedomain + + ${project.basedir}/src/main/resources/META-INF + + + + + + + org.opendaylight.controller + sal + 0.5.0-SNAPSHOT + + + org.opendaylight.controller + sal.connection + 0.1.0-SNAPSHOT + + + org.opendaylight.controller + sal.networkconfiguration + 0.0.1-SNAPSHOT + + + org.opendaylight.controller + connectionmanager + 0.1.0-SNAPSHOT + + + org.opendaylight.controller + containermanager + 0.4.0-SNAPSHOT + + + org.codehaus.enunciate + enunciate-core-annotations + ${enunciate.version} + + + org.opendaylight.controller + commons.northbound + 0.4.0-SNAPSHOT + + + org.opendaylight.controller.thirdparty + com.sun.jersey.jersey-servlet + 1.17-SNAPSHOT + + + diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthbound.java b/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthbound.java new file mode 100644 index 0000000000..36819f6222 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthbound.java @@ -0,0 +1,336 @@ + +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.networkconfig.bridgedomain.northbound; + +import java.util.HashMap; +import java.util.Map; + +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; + +import org.codehaus.enunciate.jaxrs.ResponseCode; +import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.codehaus.enunciate.jaxrs.TypeHint; +import org.opendaylight.controller.connectionmanager.IConnectionManager; +import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; +import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; +import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants; +import org.opendaylight.controller.sal.networkconfig.bridgedomain.IBridgeDomainConfigService; +import org.opendaylight.controller.sal.connection.ConnectionConstants; +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.utils.NetUtils; +import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.sal.utils.StatusCode; + +/** + * BridgeDomain Configuration Northbound APIs + * + *

+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * HTTPS Authentication is disabled by default. Administrator can enable it in tomcat-server.xml after adding + * a proper keystore / SSL certificate from a trusted authority.
+ * More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration + */ +@Path("/") +public class BridgeDomainNorthbound { + private String username; + + @Context + public void setSecurityContext(SecurityContext context) { + username = context.getUserPrincipal().getName(); + } + protected String getUserName() { + return username; + } + + private IBridgeDomainConfigService getConfigurationService() { + return (IBridgeDomainConfigService) ServiceHelper + .getGlobalInstance(IBridgeDomainConfigService.class, this); + } + + private IConnectionManager getConnectionManager() { + return (IConnectionManager) ServiceHelper + .getGlobalInstance(IConnectionManager.class, this); + } + + /** + * If a Network Configuration Service needs a special Management Connection and if the + * Node Type is unknown, use this REST api to connect to the management session. + *
+     * Example :
+     * Request : PUT http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/mgmt1/1.1.1.1/6634
+     * Response : Node :
+     *                  xml : <node type="STUB" id="mgmt1"/>
+     *                  json: {"@type": "STUB","@id": "mgmt1"}
+     *
+ * @param nodeName User-Defined name of the node to connect with. This can be any alpha numeric value + * @param ipAddress IP Address of the Node to connect with. + * @param port Layer4 Port of the management session to connect with. + * @return Node If the connection is successful, HTTP 404 otherwise. + */ + + @Path("/connect/{nodeName}/{ipAddress}/{port}/") + @PUT + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @TypeHint(Node.class) + @StatusCodes( { + @ResponseCode(code = 201, condition = "Node connected successfully"), + @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"), + @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."), + @ResponseCode(code = 503, condition = "Connection Manager Service not available")} ) + public Node connect( + @PathParam(value = "nodeName") String nodeName, + @PathParam(value = "ipAddress") String ipAddress, + @PathParam(value = "port") String port) { + + IConnectionManager connectionManager = getConnectionManager(); + if (connectionManager == null) { + throw new ServiceUnavailableException("IConnectionManager not available."); + } + + if (!NetUtils.isIPv4AddressValid(ipAddress)) { + throw new NotAcceptableException("Invalid ip address "+ipAddress); + } + + try { + Integer.parseInt(port); + } catch (Exception e) { + throw new NotAcceptableException("Invalid Layer4 Port "+port); + } + + Map params = new HashMap(); + params.put(ConnectionConstants.ADDRESS, ipAddress); + params.put(ConnectionConstants.PORT, port); + + Node node = null; + try { + node = connectionManager.connect(nodeName, params); + if (node == null) { + throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port); + } + return node; + } catch (Exception e) { + throw new ResourceNotFoundException(e.getMessage()); + } + } + + /** + * If a Network Configuration Service needs a special Management Connection, and if the + * node Type is known, the user can choose to use this REST api to connect to the management session. + *
+     * Example :
+     * Request : PUT http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/STUB/mgmt1/1.1.1.1/6634
+     * Response : Node :
+     *                  xml : <node type="STUB" id="mgmt1"/>
+     *                  json: {"@type": "STUB","@id": "mgmt1"}
+     *
+ * @param nodeName User-Defined name of the node to connect with. This can be any alpha numeric value + * @param ipAddress IP Address of the Node to connect with. + * @param port Layer4 Port of the management session to connect with. + * @return Node If the connection is successful, HTTP 404 otherwise. + */ + + @Path("/connect/{nodeType}/{nodeId}/{ipAddress}/{port}/") + @PUT + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @TypeHint(Node.class) + @StatusCodes( { + @ResponseCode(code = 201, condition = "Node connected successfully"), + @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"), + @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."), + @ResponseCode(code = 503, condition = "Connection Manager Service not available")} ) + public Node connect( + @PathParam(value = "nodeType") String nodeType, + @PathParam(value = "nodeId") String nodeId, + @PathParam(value = "ipAddress") String ipAddress, + @PathParam(value = "port") String port) { + + IConnectionManager connectionManager = getConnectionManager(); + if (connectionManager == null) { + throw new ServiceUnavailableException("IConnectionManager not available."); + } + + if (!NetUtils.isIPv4AddressValid(ipAddress)) { + throw new NotAcceptableException("Invalid ip address "+ipAddress); + } + + try { + Integer.parseInt(port); + } catch (Exception e) { + throw new NotAcceptableException("Invalid Layer4 Port "+port); + } + + Map params = new HashMap(); + params.put(ConnectionConstants.ADDRESS, ipAddress); + params.put(ConnectionConstants.PORT, port); + + Node node = null; + try { + node = connectionManager.connect(nodeType, nodeId, params); + if (node == null) { + throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port); + } + return node; + } catch (Exception e) { + throw new ResourceNotFoundException(e.getMessage()); + } + } + + /** + * Create a Bridge. + *
+     * Example :
+     * Request : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
+     *
+ * @param nodeType Node Type of the node with the management session. + * @param nodeId Node Identifier of the node with the management session. + * @param bridgeName Name / Identifier for a bridge to be created. + */ + + @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}") + @POST + @StatusCodes( { @ResponseCode(code = 201, condition = "Bridge created successfully"), + @ResponseCode(code = 404, condition = "Could not create Bridge"), + @ResponseCode(code = 412, condition = "Failed to create Bridge due to an exception"), + @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} ) + + public Response createBridge( + @PathParam(value = "nodeType") String nodeType, + @PathParam(value = "nodeId") String nodeId, + @PathParam(value = "bridgeName") String name) { + + IBridgeDomainConfigService configurationService = getConfigurationService(); + if (configurationService == null) { + throw new ServiceUnavailableException("IBridgeDomainConfigService not available."); + } + + Node node = Node.fromString(nodeType, nodeId); + Status status = null; + try { + status = configurationService.createBridgeDomain(node, name, null); + if (status.getCode().equals(StatusCode.SUCCESS)) { + return Response.status(Response.Status.CREATED).build(); + } + } catch (Throwable t) { + return Response.status(Response.Status.PRECONDITION_FAILED).build(); + } + throw new ResourceNotFoundException(status.getDescription()); + } + + /** + * Add a Port to a Bridge + *
+    * Example :
+    * Request : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
+    *
+ * @param nodeType Node Type of the node with the management session. + * @param nodeId Node Identifier of the node with the management session. + * @param bridgeName Name / Identifier of the bridge to which a Port is being added. + * @param portName Name / Identifier of a Port that is being added to a bridge. + */ + + @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}") + @POST + @StatusCodes( { @ResponseCode(code = 201, condition = "Port added successfully"), + @ResponseCode(code = 404, condition = "Could not add Port to the Bridge"), + @ResponseCode(code = 412, condition = "Failed to add Port due to an exception"), + @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} ) + + public Response addPort( + @PathParam(value = "nodeType") String nodeType, + @PathParam(value = "nodeId") String nodeId, + @PathParam(value = "bridgeName") String bridge, + @PathParam(value = "portName") String port) { + + IBridgeDomainConfigService configurationService = getConfigurationService(); + if (configurationService == null) { + throw new ServiceUnavailableException("IBridgeDomainConfigService not available."); + } + + Node node = Node.fromString(nodeType, nodeId); + Status status = null; + try { + status = configurationService.addPort(node, bridge, port, null); + if (status.getCode().equals(StatusCode.SUCCESS)) { + return Response.status(Response.Status.CREATED).build(); + } + } catch (Throwable t) { + return Response.status(Response.Status.PRECONDITION_FAILED).build(); + } + throw new ResourceNotFoundException(status.getDescription()); + } + + /** + * Add a Port,Vlan to a Bridge + *
+    * Example :
+    * Request : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port2/200
+    *
+ * @param nodeType Node Type of the node with the management session. + * @param nodeId Node Identifier of the node with the management session. + * @param bridgeName Name / Identifier of the bridge to which a Port is being added. + * @param portName Name / Identifier of a Port that is being added to a bridge. + * @param vlan Vlan Id. + */ + + @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}/{vlan}") + @POST + @StatusCodes( { @ResponseCode(code = 201, condition = "Created Port with Vlan tag successfully"), + @ResponseCode(code = 404, condition = "Could not add Port,Vlan to the Bridge"), + @ResponseCode(code = 406, condition = "Invalid Vlan parameter passed."), + @ResponseCode(code = 412, condition = "Failed to add Port,Vlan due to an exception"), + @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} ) + + public Response addPort( + @PathParam(value = "nodeType") String nodeType, + @PathParam(value = "nodeId") String nodeId, + @PathParam(value = "bridgeName") String bridge, + @PathParam(value = "portName") String port, + @PathParam(value = "vlan") String vlan) { + + IBridgeDomainConfigService configurationService = getConfigurationService(); + if (configurationService == null) { + throw new ServiceUnavailableException("IBridgeDomainConfigService not available."); + } + try { + Integer.parseInt(vlan); + } catch (Exception e) { + throw new NotAcceptableException("Incorrect Vlan :"+vlan); + } + + Node node = Node.fromString(nodeType, nodeId); + Map configs = new HashMap(); + configs.put(ConfigConstants.TYPE, ConfigConstants.VLAN); + configs.put(ConfigConstants.VLAN, vlan); + + Status status = null; + try { + status = configurationService.addPort(node, bridge, port, configs); + if (status.getCode().equals(StatusCode.SUCCESS)) { + return Response.status(Response.Status.CREATED).build(); + } + } catch (Exception e) { + return Response.status(Response.Status.PRECONDITION_FAILED).build(); + } + throw new ResourceNotFoundException(status.getDescription()); + } +} diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthboundApplication.java b/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthboundApplication.java new file mode 100644 index 0000000000..1d1fd15a4a --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthboundApplication.java @@ -0,0 +1,30 @@ + +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.networkconfig.bridgedomain.northbound; + +import java.util.HashSet; +import java.util.Set; +import javax.ws.rs.core.Application; + +/** + * Instance of javax.ws.rs.core.Application used to return the classes + * that will be instantiated for JAXRS processing, this is necessary + * because the package scanning in jersey doesn't yet work in OSGi + * environment. + * + */ +public class BridgeDomainNorthboundApplication extends Application { + @Override + public Set> getClasses() { + Set> classes = new HashSet>(); + classes.add(BridgeDomainNorthbound.class); + return classes; + } +} diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/resources/WEB-INF/web.xml b/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/resources/WEB-INF/web.xml new file mode 100644 index 0000000000..b7f35c3f96 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/src/main/resources/WEB-INF/web.xml @@ -0,0 +1,51 @@ + + + + BridgeDomainConfiguration + com.sun.jersey.spi.container.servlet.ServletContainer + + javax.ws.rs.Application + org.opendaylight.controller.networkconfig.bridgedomain.northbound.BridgeDomainNorthboundApplication + + 1 + + + + BridgeDomainConfiguration + /* + + + + + BridgeDomain Configuration NorthBound API + /* + + + System-Admin + Network-Admin + Network-Operator + Container-User + + + + + System-Admin + + + Network-Admin + + + Network-Operator + + + Container-User + + + + BASIC + opendaylight + + + \ No newline at end of file -- 2.36.6