Fixed a minor bug (replace VLAN enum with string to Configuration map) in the Bridge...
[controller.git] / opendaylight / northbound / networkconfiguration / bridgedomain / src / main / java / org / opendaylight / controller / networkconfig / bridgedomain / northbound / BridgeDomainNorthbound.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.networkconfig.bridgedomain.northbound;
11
12 import java.util.HashMap;
13 import java.util.Map;
14
15 import javax.ws.rs.POST;
16 import javax.ws.rs.PUT;
17 import javax.ws.rs.Path;
18 import javax.ws.rs.PathParam;
19 import javax.ws.rs.Produces;
20 import javax.ws.rs.core.Context;
21 import javax.ws.rs.core.MediaType;
22 import javax.ws.rs.core.Response;
23 import javax.ws.rs.core.SecurityContext;
24
25 import org.codehaus.enunciate.jaxrs.ResponseCode;
26 import org.codehaus.enunciate.jaxrs.StatusCodes;
27 import org.codehaus.enunciate.jaxrs.TypeHint;
28 import org.opendaylight.controller.connectionmanager.IConnectionManager;
29 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
30 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
31 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
32 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
33 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IBridgeDomainConfigService;
34 import org.opendaylight.controller.sal.connection.ConnectionConstants;
35 import org.opendaylight.controller.sal.core.Node;
36 import org.opendaylight.controller.sal.utils.NetUtils;
37 import org.opendaylight.controller.sal.utils.ServiceHelper;
38 import org.opendaylight.controller.sal.utils.Status;
39 import org.opendaylight.controller.sal.utils.StatusCode;
40
41 /**
42  * BridgeDomain Configuration Northbound APIs
43  *
44  * <br><br>
45  * Authentication scheme : <b>HTTP Basic</b><br>
46  * Authentication realm : <b>opendaylight</b><br>
47  * Transport : <b>HTTP and HTTPS</b><br>
48  * <br>
49  * HTTPS Authentication is disabled by default. Administrator can enable it in tomcat-server.xml after adding
50  * a proper keystore / SSL certificate from a trusted authority.<br>
51  * More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
52  */
53 @Path("/")
54 public class BridgeDomainNorthbound {
55     private String username;
56
57     @Context
58     public void setSecurityContext(SecurityContext context) {
59         username = context.getUserPrincipal().getName();
60     }
61     protected String getUserName() {
62         return username;
63     }
64
65     private IBridgeDomainConfigService getConfigurationService() {
66         return (IBridgeDomainConfigService) ServiceHelper
67                 .getGlobalInstance(IBridgeDomainConfigService.class, this);
68     }
69
70     private IConnectionManager getConnectionManager() {
71         return (IConnectionManager) ServiceHelper
72                 .getGlobalInstance(IConnectionManager.class, this);
73     }
74
75     /**
76      * If a Network Configuration Service needs a special Management Connection and if the
77      * Node Type is unknown, use this REST api to connect to the management session.
78      * <pre>
79      * Example :
80      * Request : PUT http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/mgmt1/1.1.1.1/6634
81      * Response : Node :
82      *                  xml : &lt;node type="STUB" id="mgmt1"/&gt;
83      *                  json: {"@type": "STUB","@id": "mgmt1"}
84      *</pre>
85      * @param nodeName User-Defined name of the node to connect with. This can be any alpha numeric value
86      * @param ipAddress IP Address of the Node to connect with.
87      * @param port Layer4 Port of the management session to connect with.
88      * @return Node If the connection is successful, HTTP 404 otherwise.
89      */
90
91     @Path("/connect/{nodeName}/{ipAddress}/{port}/")
92     @PUT
93     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
94     @TypeHint(Node.class)
95     @StatusCodes( {
96         @ResponseCode(code = 201, condition = "Node connected successfully"),
97         @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
98         @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
99         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
100     public Node connect(
101             @PathParam(value = "nodeName") String nodeName,
102             @PathParam(value = "ipAddress") String ipAddress,
103             @PathParam(value = "port") String port) {
104
105         IConnectionManager connectionManager = getConnectionManager();
106         if (connectionManager == null) {
107             throw new ServiceUnavailableException("IConnectionManager not available.");
108         }
109
110         if (!NetUtils.isIPv4AddressValid(ipAddress)) {
111             throw new NotAcceptableException("Invalid ip address "+ipAddress);
112         }
113
114         try {
115             Integer.parseInt(port);
116         } catch (Exception e) {
117             throw new NotAcceptableException("Invalid Layer4 Port "+port);
118         }
119
120         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
121         params.put(ConnectionConstants.ADDRESS, ipAddress);
122         params.put(ConnectionConstants.PORT, port);
123
124         Node node = null;
125         try {
126             node = connectionManager.connect(nodeName, params);
127             if (node == null) {
128                 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
129             }
130             return node;
131         } catch (Exception e) {
132             throw new ResourceNotFoundException(e.getMessage());
133         }
134     }
135
136     /**
137      * If a Network Configuration Service needs a special Management Connection, and if the
138      * node Type is known, the user can choose to use this REST api to connect to the management session.
139      * <pre>
140      * Example :
141      * Request : PUT http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/STUB/mgmt1/1.1.1.1/6634
142      * Response : Node :
143      *                  xml : &lt;node type="STUB" id="mgmt1"/&gt;
144      *                  json: {"@type": "STUB","@id": "mgmt1"}
145      *</pre>
146      * @param nodeName User-Defined name of the node to connect with. This can be any alpha numeric value
147      * @param ipAddress IP Address of the Node to connect with.
148      * @param port Layer4 Port of the management session to connect with.
149      * @return Node If the connection is successful, HTTP 404 otherwise.
150      */
151
152     @Path("/connect/{nodeType}/{nodeId}/{ipAddress}/{port}/")
153     @PUT
154     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
155     @TypeHint(Node.class)
156     @StatusCodes( {
157         @ResponseCode(code = 201, condition = "Node connected successfully"),
158         @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
159         @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
160         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
161     public Node connect(
162             @PathParam(value = "nodeType") String nodeType,
163             @PathParam(value = "nodeId") String nodeId,
164             @PathParam(value = "ipAddress") String ipAddress,
165             @PathParam(value = "port") String port) {
166
167         IConnectionManager connectionManager = getConnectionManager();
168         if (connectionManager == null) {
169             throw new ServiceUnavailableException("IConnectionManager not available.");
170         }
171
172         if (!NetUtils.isIPv4AddressValid(ipAddress)) {
173             throw new NotAcceptableException("Invalid ip address "+ipAddress);
174         }
175
176         try {
177             Integer.parseInt(port);
178         } catch (Exception e) {
179             throw new NotAcceptableException("Invalid Layer4 Port "+port);
180         }
181
182         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
183         params.put(ConnectionConstants.ADDRESS, ipAddress);
184         params.put(ConnectionConstants.PORT, port);
185
186         Node node = null;
187         try {
188             node = connectionManager.connect(nodeType, nodeId, params);
189             if (node == null) {
190                 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
191             }
192             return node;
193         } catch (Exception e) {
194             throw new ResourceNotFoundException(e.getMessage());
195         }
196     }
197
198     /**
199      * Create a Bridge.
200      * <pre>
201      * Example :
202      * Request : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
203      *</pre>
204      * @param nodeType Node Type of the node with the management session.
205      * @param nodeId Node Identifier of the node with the management session.
206      * @param bridgeName Name / Identifier for a bridge to be created.
207      */
208
209    @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
210    @POST
211    @StatusCodes( { @ResponseCode(code = 201, condition = "Bridge created successfully"),
212        @ResponseCode(code = 404, condition = "Could not create Bridge"),
213        @ResponseCode(code = 412, condition = "Failed to create Bridge due to an exception"),
214        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
215
216    public Response createBridge(
217            @PathParam(value = "nodeType") String nodeType,
218            @PathParam(value = "nodeId") String nodeId,
219            @PathParam(value = "bridgeName") String name) {
220
221        IBridgeDomainConfigService configurationService = getConfigurationService();
222        if (configurationService == null) {
223            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
224        }
225
226        Node node = Node.fromString(nodeType, nodeId);
227        Status status = null;
228        try {
229            status = configurationService.createBridgeDomain(node, name, null);
230            if (status.getCode().equals(StatusCode.SUCCESS)) {
231                return Response.status(Response.Status.CREATED).build();
232            }
233        } catch (Throwable t) {
234            return Response.status(Response.Status.PRECONDITION_FAILED).build();
235        }
236        throw new ResourceNotFoundException(status.getDescription());
237    }
238
239    /**
240     * Add a Port to a Bridge
241     * <pre>
242     * Example :
243     * Request : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
244     *</pre>
245     * @param nodeType Node Type of the node with the management session.
246     * @param nodeId Node Identifier of the node with the management session.
247     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
248     * @param portName Name / Identifier of a Port that is being added to a bridge.
249     */
250
251    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
252    @POST
253    @StatusCodes( { @ResponseCode(code = 201, condition = "Port added successfully"),
254        @ResponseCode(code = 404, condition = "Could not add Port to the Bridge"),
255        @ResponseCode(code = 412, condition = "Failed to add Port due to an exception"),
256        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
257
258    public Response addPort(
259            @PathParam(value = "nodeType") String nodeType,
260            @PathParam(value = "nodeId") String nodeId,
261            @PathParam(value = "bridgeName") String bridge,
262            @PathParam(value = "portName") String port) {
263
264        IBridgeDomainConfigService configurationService = getConfigurationService();
265        if (configurationService == null) {
266            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
267        }
268
269        Node node = Node.fromString(nodeType, nodeId);
270        Status status = null;
271        try {
272            status = configurationService.addPort(node, bridge, port, null);
273            if (status.getCode().equals(StatusCode.SUCCESS)) {
274                return Response.status(Response.Status.CREATED).build();
275            }
276        } catch (Throwable t) {
277            return Response.status(Response.Status.PRECONDITION_FAILED).build();
278        }
279        throw new ResourceNotFoundException(status.getDescription());
280    }
281
282    /**
283     * Add a Port,Vlan to a Bridge
284     * <pre>
285     * Example :
286     * Request : POST http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port2/200
287     *</pre>
288     * @param nodeType Node Type of the node with the management session.
289     * @param nodeId Node Identifier of the node with the management session.
290     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
291     * @param portName Name / Identifier of a Port that is being added to a bridge.
292     * @param vlan Vlan Id.
293     */
294
295    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}/{vlan}")
296    @POST
297    @StatusCodes( { @ResponseCode(code = 201, condition = "Created Port with Vlan tag successfully"),
298        @ResponseCode(code = 404, condition = "Could not add Port,Vlan to the Bridge"),
299        @ResponseCode(code = 406, condition = "Invalid Vlan parameter passed."),
300        @ResponseCode(code = 412, condition = "Failed to add Port,Vlan due to an exception"),
301        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
302
303    public Response addPort(
304            @PathParam(value = "nodeType") String nodeType,
305            @PathParam(value = "nodeId") String nodeId,
306            @PathParam(value = "bridgeName") String bridge,
307            @PathParam(value = "portName") String port,
308            @PathParam(value = "vlan") String vlan) {
309
310        IBridgeDomainConfigService configurationService = getConfigurationService();
311        if (configurationService == null) {
312            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
313        }
314        try {
315            Integer.parseInt(vlan);
316        } catch (Exception e) {
317            throw new NotAcceptableException("Incorrect Vlan :"+vlan);
318        }
319
320        Node node = Node.fromString(nodeType, nodeId);
321        Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
322        configs.put(ConfigConstants.TYPE, ConfigConstants.VLAN.name());
323        configs.put(ConfigConstants.VLAN, vlan);
324
325        Status status = null;
326        try {
327        status = configurationService.addPort(node, bridge, port, configs);
328        if (status.getCode().equals(StatusCode.SUCCESS)) {
329            return Response.status(Response.Status.CREATED).build();
330        }
331        } catch (Exception e) {
332            return Response.status(Response.Status.PRECONDITION_FAILED).build();
333        }
334        throw new ResourceNotFoundException(status.getDescription());
335    }
336 }