Few additional fixes to enable Client script access to Northbound.
[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.connection.ConnectionConstants;
33 import org.opendaylight.controller.sal.core.Node;
34 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
35 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IBridgeDomainConfigService;
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         if (context != null && context.getUserPrincipal() != null) 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      *
80      * Example :
81      *
82      * Request :
83      * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/mgmt1/1.1.1.1/6634
84      *
85      * Response :
86      * Node :
87      * xml :
88      * &lt;node&gt;
89      *    &lt;id&gt;mgmt1&lt;/id&gt;
90      *    &lt;type&gt;STUB&lt;/type&gt;
91      * &lt;/node&gt;
92      *
93      * json:
94      * {"id": "mgmt1","type": "STUB"}
95      *
96      *</pre>
97      * @param nodeName User-Defined name of the node to connect with. This can be any alpha numeric value
98      * @param ipAddress IP Address of the Node to connect with.
99      * @param port Layer4 Port of the management session to connect with.
100      * @return Node If the connection is successful, HTTP 404 otherwise.
101      */
102
103     @Path("/connect/{nodeName}/{ipAddress}/{port}/")
104     @PUT
105     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
106     @TypeHint(Node.class)
107     @StatusCodes( {
108         @ResponseCode(code = 201, condition = "Node connected successfully"),
109         @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
110         @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
111         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
112     public Node connect(
113             @PathParam(value = "nodeName") String nodeName,
114             @PathParam(value = "ipAddress") String ipAddress,
115             @PathParam(value = "port") String port) {
116
117         IConnectionManager connectionManager = getConnectionManager();
118         if (connectionManager == null) {
119             throw new ServiceUnavailableException("IConnectionManager not available.");
120         }
121
122         if (!NetUtils.isIPv4AddressValid(ipAddress)) {
123             throw new NotAcceptableException("Invalid ip address "+ipAddress);
124         }
125
126         try {
127             Integer.parseInt(port);
128         } catch (Exception e) {
129             throw new NotAcceptableException("Invalid Layer4 Port "+port);
130         }
131
132         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
133         params.put(ConnectionConstants.ADDRESS, ipAddress);
134         params.put(ConnectionConstants.PORT, port);
135
136         Node node = null;
137         try {
138             node = connectionManager.connect(nodeName, params);
139             if (node == null) {
140                 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
141             }
142             return node;
143         } catch (Exception e) {
144             throw new ResourceNotFoundException(e.getMessage());
145         }
146     }
147
148     /**
149      * If a Network Configuration Service needs a special Management Connection, and if the
150      * node Type is known, the user can choose to use this REST api to connect to the management session.
151      * <pre>
152      *
153      * Example :
154      *
155      * Request :
156      * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/connect/STUB/mgmt1/1.1.1.1/6634
157      *
158      * Response : Node :
159      * xml :
160      * &lt;node&gt;
161      *    &lt;id&gt;mgmt1&lt;/id&gt;
162      *    &lt;type&gt;STUB&lt;/type&gt;
163      * &lt;/node&gt;
164      *
165      * json:
166      * {"id": "mgmt1","type": "STUB"}
167      *
168      *</pre>
169      * @param nodeName User-Defined name of the node to connect with. This can be any alpha numeric value
170      * @param ipAddress IP Address of the Node to connect with.
171      * @param port Layer4 Port of the management session to connect with.
172      * @return Node If the connection is successful, HTTP 404 otherwise.
173      */
174
175     @Path("/connect/{nodeType}/{nodeId}/{ipAddress}/{port}/")
176     @PUT
177     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
178     @TypeHint(Node.class)
179     @StatusCodes( {
180         @ResponseCode(code = 201, condition = "Node connected successfully"),
181         @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
182         @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
183         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
184     public Node connect(
185             @PathParam(value = "nodeType") String nodeType,
186             @PathParam(value = "nodeId") String nodeId,
187             @PathParam(value = "ipAddress") String ipAddress,
188             @PathParam(value = "port") String port) {
189
190         IConnectionManager connectionManager = getConnectionManager();
191         if (connectionManager == null) {
192             throw new ServiceUnavailableException("IConnectionManager not available.");
193         }
194
195         if (!NetUtils.isIPv4AddressValid(ipAddress)) {
196             throw new NotAcceptableException("Invalid ip address "+ipAddress);
197         }
198
199         try {
200             Integer.parseInt(port);
201         } catch (Exception e) {
202             throw new NotAcceptableException("Invalid Layer4 Port "+port);
203         }
204
205         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
206         params.put(ConnectionConstants.ADDRESS, ipAddress);
207         params.put(ConnectionConstants.PORT, port);
208
209         Node node = null;
210         try {
211             node = connectionManager.connect(nodeType, nodeId, params);
212             if (node == null) {
213                 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
214             }
215             return node;
216         } catch (Exception e) {
217             throw new ResourceNotFoundException(e.getMessage());
218         }
219     }
220
221     /**
222      * Create a Bridge.
223      * <pre>
224      *
225      * Example :
226      *
227      * Request :
228      * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
229      *
230      *</pre>
231      * @param nodeType Node Type of the node with the management session.
232      * @param nodeId Node Identifier of the node with the management session.
233      * @param bridgeName Name / Identifier for a bridge to be created.
234      */
235
236    @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
237    @POST
238    @StatusCodes( { @ResponseCode(code = 201, condition = "Bridge created successfully"),
239        @ResponseCode(code = 404, condition = "Could not create Bridge"),
240        @ResponseCode(code = 412, condition = "Failed to create Bridge due to an exception"),
241        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
242
243    public Response createBridge(
244            @PathParam(value = "nodeType") String nodeType,
245            @PathParam(value = "nodeId") String nodeId,
246            @PathParam(value = "bridgeName") String name) {
247
248        IBridgeDomainConfigService configurationService = getConfigurationService();
249        if (configurationService == null) {
250            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
251        }
252
253        Node node = Node.fromString(nodeType, nodeId);
254        Status status = null;
255        try {
256            status = configurationService.createBridgeDomain(node, name, null);
257            if (status.getCode().equals(StatusCode.SUCCESS)) {
258                return Response.status(Response.Status.CREATED).build();
259            }
260        } catch (Throwable t) {
261            return Response.status(Response.Status.PRECONDITION_FAILED).build();
262        }
263        throw new ResourceNotFoundException(status.getDescription());
264    }
265
266    /**
267     * Add a Port to a Bridge
268     * <pre>
269     *
270     * Example :
271     *
272     * Request :
273     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
274     *
275     *</pre>
276     * @param nodeType Node Type of the node with the management session.
277     * @param nodeId Node Identifier of the node with the management session.
278     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
279     * @param portName Name / Identifier of a Port that is being added to a bridge.
280     */
281
282    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
283    @POST
284    @StatusCodes( { @ResponseCode(code = 201, condition = "Port added successfully"),
285        @ResponseCode(code = 404, condition = "Could not add Port to the Bridge"),
286        @ResponseCode(code = 412, condition = "Failed to add Port due to an exception"),
287        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
288
289    public Response addPort(
290            @PathParam(value = "nodeType") String nodeType,
291            @PathParam(value = "nodeId") String nodeId,
292            @PathParam(value = "bridgeName") String bridge,
293            @PathParam(value = "portName") String port) {
294
295        IBridgeDomainConfigService configurationService = getConfigurationService();
296        if (configurationService == null) {
297            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
298        }
299
300        Node node = Node.fromString(nodeType, nodeId);
301        Status status = null;
302        try {
303            status = configurationService.addPort(node, bridge, port, null);
304            if (status.getCode().equals(StatusCode.SUCCESS)) {
305                return Response.status(Response.Status.CREATED).build();
306            }
307        } catch (Throwable t) {
308            return Response.status(Response.Status.PRECONDITION_FAILED).build();
309        }
310        throw new ResourceNotFoundException(status.getDescription());
311    }
312
313    /**
314     * Add a Port,Vlan to a Bridge
315     * <pre>
316     *
317     * Example :
318     * Request :
319     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port2/200
320     *
321     * </pre>
322     * @param nodeType Node Type of the node with the management session.
323     * @param nodeId Node Identifier of the node with the management session.
324     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
325     * @param portName Name / Identifier of a Port that is being added to a bridge.
326     * @param vlan Vlan Id.
327     */
328
329    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}/{vlan}")
330    @POST
331    @StatusCodes( { @ResponseCode(code = 201, condition = "Created Port with Vlan tag successfully"),
332        @ResponseCode(code = 404, condition = "Could not add Port,Vlan to the Bridge"),
333        @ResponseCode(code = 406, condition = "Invalid Vlan parameter passed."),
334        @ResponseCode(code = 412, condition = "Failed to add Port,Vlan due to an exception"),
335        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
336
337    public Response addPort(
338            @PathParam(value = "nodeType") String nodeType,
339            @PathParam(value = "nodeId") String nodeId,
340            @PathParam(value = "bridgeName") String bridge,
341            @PathParam(value = "portName") String port,
342            @PathParam(value = "vlan") String vlan) {
343
344        IBridgeDomainConfigService configurationService = getConfigurationService();
345        if (configurationService == null) {
346            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
347        }
348        try {
349            Integer.parseInt(vlan);
350        } catch (Exception e) {
351            throw new NotAcceptableException("Incorrect Vlan :"+vlan);
352        }
353
354        Node node = Node.fromString(nodeType, nodeId);
355        Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
356        configs.put(ConfigConstants.TYPE, ConfigConstants.VLAN.name());
357        configs.put(ConfigConstants.VLAN, vlan);
358
359        Status status = null;
360        try {
361        status = configurationService.addPort(node, bridge, port, configs);
362        if (status.getCode().equals(StatusCode.SUCCESS)) {
363            return Response.status(Response.Status.CREATED).build();
364        }
365        } catch (Exception e) {
366            return Response.status(Response.Status.PRECONDITION_FAILED).build();
367        }
368        throw new ResourceNotFoundException(status.getDescription());
369    }
370 }