Merge "Add MountInstance client documentation and promote to ListenableFuture"
[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.Consumes;
16 import javax.ws.rs.DELETE;
17 import javax.ws.rs.POST;
18 import javax.ws.rs.Path;
19 import javax.ws.rs.PathParam;
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.opendaylight.controller.connectionmanager.IConnectionManager;
28 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
29 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
30 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
31 import org.opendaylight.controller.sal.core.Node;
32 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
33 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IBridgeDomainConfigService;
34 import org.opendaylight.controller.sal.utils.ServiceHelper;
35 import org.opendaylight.controller.sal.utils.Status;
36 import org.opendaylight.controller.sal.utils.StatusCode;
37
38 /**
39  * BridgeDomain Configuration Northbound APIs
40  *
41  * <br><br>
42  * Authentication scheme : <b>HTTP Basic</b><br>
43  * Authentication realm : <b>opendaylight</b><br>
44  * Transport : <b>HTTP and HTTPS</b><br>
45  * <br>
46  * HTTPS Authentication is disabled by default. Administrator can enable it in tomcat-server.xml after adding
47  * a proper keystore / SSL certificate from a trusted authority.<br>
48  * More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
49  */
50 @Path("/")
51 public class BridgeDomainNorthbound {
52     private String username;
53
54     @Context
55     public void setSecurityContext(SecurityContext context) {
56         if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
57     }
58     protected String getUserName() {
59         return username;
60     }
61
62     private IBridgeDomainConfigService getConfigurationService() {
63         return (IBridgeDomainConfigService) ServiceHelper
64                 .getGlobalInstance(IBridgeDomainConfigService.class, this);
65     }
66
67     private IConnectionManager getConnectionManager() {
68         return (IConnectionManager) ServiceHelper
69                 .getGlobalInstance(IConnectionManager.class, this);
70     }
71
72     /**
73      * Create a Bridge.
74      * <pre>
75      *
76      * Example :
77      *
78      * Request :
79      * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
80      *
81      *</pre>
82      * @param nodeType Node Type of the node with the management session.
83      * @param nodeId Node Identifier of the node with the management session.
84      * @param bridgeName Name / Identifier for a bridge to be created.
85      * @param bridgeConfigs Additional Bridge Configurations.
86      *        It takes in complex structures under the ConfigConstants.CUSTOM key.
87      *        The use-cases are documented under wiki.opendaylight.org project pages:
88      *        https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
89      */
90
91    @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
92    @POST
93    @StatusCodes( { @ResponseCode(code = 201, condition = "Bridge created successfully"),
94        @ResponseCode(code = 404, condition = "Could not create Bridge"),
95        @ResponseCode(code = 412, condition = "Failed to create Bridge due to an exception"),
96        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
97
98    public Response createBridge(
99            @PathParam(value = "nodeType") String nodeType,
100            @PathParam(value = "nodeId") String nodeId,
101            @PathParam(value = "bridgeName") String name,
102            Map<String, Object> bridgeConfigs) {
103
104        IBridgeDomainConfigService configurationService = getConfigurationService();
105        if (configurationService == null) {
106            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
107        }
108
109        Node node = Node.fromString(nodeType, nodeId);
110        Status status = null;
111        try {
112            Map<ConfigConstants, Object> configs = this.buildConfig(bridgeConfigs);
113            status = configurationService.createBridgeDomain(node, name, configs);
114            if (status.getCode().equals(StatusCode.SUCCESS)) {
115                return Response.status(Response.Status.CREATED).build();
116            }
117        } catch (Error e) {
118            throw e;
119        } catch (Throwable t) {
120            return Response.status(Response.Status.PRECONDITION_FAILED).build();
121        }
122        throw new ResourceNotFoundException(status.getDescription());
123    }
124
125
126    /**
127     * Remove a Bridge.
128     * <pre>
129     *
130     * Example :
131     *
132     * Request :
133     * DELETE
134     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
135     *
136     *</pre>
137     * @param nodeType Node Type of the node with the management session.
138     * @param nodeId Node Identifier of the node with the management session.
139     * @param bridgeName Name / Identifier for a bridge to be deleted.
140     */
141
142   @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
143   @DELETE
144   @StatusCodes( { @ResponseCode(code = 200, condition = "Bridge deleted successfully"),
145       @ResponseCode(code = 404, condition = "Could not delete Bridge"),
146       @ResponseCode(code = 412, condition = "Failed to delete Bridge due to an exception"),
147       @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
148
149   public Response deleteBridge(
150           @PathParam(value = "nodeType") String nodeType,
151           @PathParam(value = "nodeId") String nodeId,
152           @PathParam(value = "bridgeName") String name) {
153
154       IBridgeDomainConfigService configurationService = getConfigurationService();
155       if (configurationService == null) {
156           throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
157       }
158
159       Node node = Node.fromString(nodeType, nodeId);
160       Status status = null;
161       try {
162           status = configurationService.deleteBridgeDomain(node, name);
163           if (status.getCode().equals(StatusCode.SUCCESS)) {
164               return Response.status(Response.Status.OK).build();
165           }
166       } catch (Exception t) {
167           return Response.status(Response.Status.PRECONDITION_FAILED).build();
168       }
169       throw new ResourceNotFoundException(status.getDescription());
170   }
171
172    /**
173     * Add a Port to a Bridge
174     * <pre>
175     *
176     * Example :
177     *
178     * Request :
179     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
180     *
181     *</pre>
182     * @param nodeType Node Type of the node with the management session.
183     * @param nodeId Node Identifier of the node with the management session.
184     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
185     * @param portName Name / Identifier of a Port that is being added to a bridge.
186     * @param portConfigs Additional Port Configurations.
187     *        It takes in complex structures under the ConfigConstants.CUSTOM key.
188     *        The use-cases are documented under wiki.opendaylight.org project pages :
189     *        https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
190     */
191
192    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
193    @POST
194    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
195    @StatusCodes( { @ResponseCode(code = 201, condition = "Port added successfully"),
196        @ResponseCode(code = 404, condition = "Could not add Port to the Bridge"),
197        @ResponseCode(code = 412, condition = "Failed to add Port due to an exception"),
198        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
199
200    public Response addPort(
201            @PathParam(value = "nodeType") String nodeType,
202            @PathParam(value = "nodeId") String nodeId,
203            @PathParam(value = "bridgeName") String bridge,
204            @PathParam(value = "portName") String port,
205            Map<String, Object> portConfigs) {
206
207        IBridgeDomainConfigService configurationService = getConfigurationService();
208        if (configurationService == null) {
209            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
210        }
211
212        Node node = Node.fromString(nodeType, nodeId);
213        Status status = null;
214        try {
215            Map<ConfigConstants, Object> configs = this.buildConfig(portConfigs);
216            status = configurationService.addPort(node, bridge, port, configs);
217            if (status.getCode().equals(StatusCode.SUCCESS)) {
218                return Response.status(Response.Status.CREATED).build();
219            }
220        } catch (Exception t) {
221            return Response.status(Response.Status.PRECONDITION_FAILED).build();
222        }
223        throw new ResourceNotFoundException(status.getDescription());
224    }
225
226    /**
227     * Remove a Port from a Bridge
228     * <pre>
229     *
230     * Example :
231     *
232     * Request :
233     * DELETE
234     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
235     *
236     *</pre>
237     * @param nodeType Node Type of the node with the management session.
238     * @param nodeId Node Identifier of the node with the management session.
239     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
240     * @param portName Name / Identifier of a Port that is being deleted from a bridge.
241     */
242
243    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
244    @DELETE
245    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
246    @StatusCodes( { @ResponseCode(code = 200, condition = "Port deleted successfully"),
247        @ResponseCode(code = 404, condition = "Could not delete Port to the Bridge"),
248        @ResponseCode(code = 412, condition = "Failed to delete Port due to an exception"),
249        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
250
251    public Response deletePort(
252            @PathParam(value = "nodeType") String nodeType,
253            @PathParam(value = "nodeId") String nodeId,
254            @PathParam(value = "bridgeName") String bridge,
255            @PathParam(value = "portName") String port) {
256
257        IBridgeDomainConfigService configurationService = getConfigurationService();
258        if (configurationService == null) {
259            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
260        }
261
262        Node node = Node.fromString(nodeType, nodeId);
263        Status status = null;
264        try {
265            status = configurationService.deletePort(node, bridge, port);
266            if (status.getCode().equals(StatusCode.SUCCESS)) {
267                return Response.status(Response.Status.OK).build();
268            }
269        } catch (Exception t) {
270            return Response.status(Response.Status.PRECONDITION_FAILED).build();
271        }
272        throw new ResourceNotFoundException(status.getDescription());
273    }
274
275    private Map<ConfigConstants, Object> buildConfig(Map<String, Object> rawConfigs) {
276        if (rawConfigs == null) return null;
277        Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
278        for (String key : rawConfigs.keySet()) {
279            ConfigConstants cc = ConfigConstants.valueOf(key.toUpperCase());
280            configs.put(cc, rawConfigs.get(key));
281        }
282        return configs;
283    }
284 /**
285     * Add a Port,Vlan to a Bridge
286     * <pre>
287     *
288     * Example :
289     * Request :
290     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port2/200
291     *
292     * </pre>
293     * @param nodeType Node Type of the node with the management session.
294     * @param nodeId Node Identifier of the node with the management session.
295     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
296     * @param portName Name / Identifier of a Port that is being added to a bridge.
297     * @param vlan Vlan Id.
298     */
299
300    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}/{vlan}")
301    @POST
302    @StatusCodes( { @ResponseCode(code = 201, condition = "Created Port with Vlan tag successfully"),
303        @ResponseCode(code = 404, condition = "Could not add Port,Vlan to the Bridge"),
304        @ResponseCode(code = 406, condition = "Invalid Vlan parameter passed."),
305        @ResponseCode(code = 412, condition = "Failed to add Port,Vlan due to an exception"),
306        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
307
308    public Response addPort(
309            @PathParam(value = "nodeType") String nodeType,
310            @PathParam(value = "nodeId") String nodeId,
311            @PathParam(value = "bridgeName") String bridge,
312            @PathParam(value = "portName") String port,
313            @PathParam(value = "vlan") String vlan) {
314
315        IBridgeDomainConfigService configurationService = getConfigurationService();
316        if (configurationService == null) {
317            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
318        }
319        try {
320            Integer.parseInt(vlan);
321        } catch (Exception e) {
322            throw new NotAcceptableException("Incorrect Vlan :"+vlan);
323        }
324
325        Node node = Node.fromString(nodeType, nodeId);
326        Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
327        configs.put(ConfigConstants.TYPE, ConfigConstants.VLAN.name());
328        configs.put(ConfigConstants.VLAN, vlan);
329
330        Status status = null;
331        try {
332        status = configurationService.addPort(node, bridge, port, configs);
333        if (status.getCode().equals(StatusCode.SUCCESS)) {
334            return Response.status(Response.Status.CREATED).build();
335        }
336        } catch (Exception e) {
337            return Response.status(Response.Status.PRECONDITION_FAILED).build();
338        }
339        throw new ResourceNotFoundException(status.getDescription());
340    }
341 }