Merge "Unified implementations of BrokerService Proxies which are provided to Consume...
[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 (Throwable t) {
118            return Response.status(Response.Status.PRECONDITION_FAILED).build();
119        }
120        throw new ResourceNotFoundException(status.getDescription());
121    }
122
123
124    /**
125     * Remove a Bridge.
126     * <pre>
127     *
128     * Example :
129     *
130     * Request :
131     * DELETE
132     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
133     *
134     *</pre>
135     * @param nodeType Node Type of the node with the management session.
136     * @param nodeId Node Identifier of the node with the management session.
137     * @param bridgeName Name / Identifier for a bridge to be deleted.
138     */
139
140   @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
141   @DELETE
142   @StatusCodes( { @ResponseCode(code = 200, condition = "Bridge deleted successfully"),
143       @ResponseCode(code = 404, condition = "Could not delete Bridge"),
144       @ResponseCode(code = 412, condition = "Failed to delete Bridge due to an exception"),
145       @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
146
147   public Response deleteBridge(
148           @PathParam(value = "nodeType") String nodeType,
149           @PathParam(value = "nodeId") String nodeId,
150           @PathParam(value = "bridgeName") String name) {
151
152       IBridgeDomainConfigService configurationService = getConfigurationService();
153       if (configurationService == null) {
154           throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
155       }
156
157       Node node = Node.fromString(nodeType, nodeId);
158       Status status = null;
159       try {
160           status = configurationService.deleteBridgeDomain(node, name);
161           if (status.getCode().equals(StatusCode.SUCCESS)) {
162               return Response.status(Response.Status.OK).build();
163           }
164       } catch (Throwable t) {
165           return Response.status(Response.Status.PRECONDITION_FAILED).build();
166       }
167       throw new ResourceNotFoundException(status.getDescription());
168   }
169
170    /**
171     * Add a Port to a Bridge
172     * <pre>
173     *
174     * Example :
175     *
176     * Request :
177     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
178     *
179     *</pre>
180     * @param nodeType Node Type of the node with the management session.
181     * @param nodeId Node Identifier of the node with the management session.
182     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
183     * @param portName Name / Identifier of a Port that is being added to a bridge.
184     * @param portConfigs Additional Port Configurations.
185     *        It takes in complex structures under the ConfigConstants.CUSTOM key.
186     *        The use-cases are documented under wiki.opendaylight.org project pages :
187     *        https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
188     */
189
190    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
191    @POST
192    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
193    @StatusCodes( { @ResponseCode(code = 201, condition = "Port added successfully"),
194        @ResponseCode(code = 404, condition = "Could not add Port to the Bridge"),
195        @ResponseCode(code = 412, condition = "Failed to add Port due to an exception"),
196        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
197
198    public Response addPort(
199            @PathParam(value = "nodeType") String nodeType,
200            @PathParam(value = "nodeId") String nodeId,
201            @PathParam(value = "bridgeName") String bridge,
202            @PathParam(value = "portName") String port,
203            Map<String, Object> portConfigs) {
204
205        IBridgeDomainConfigService configurationService = getConfigurationService();
206        if (configurationService == null) {
207            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
208        }
209
210        Node node = Node.fromString(nodeType, nodeId);
211        Status status = null;
212        try {
213            Map<ConfigConstants, Object> configs = this.buildConfig(portConfigs);
214            status = configurationService.addPort(node, bridge, port, configs);
215            if (status.getCode().equals(StatusCode.SUCCESS)) {
216                return Response.status(Response.Status.CREATED).build();
217            }
218        } catch (Throwable t) {
219            return Response.status(Response.Status.PRECONDITION_FAILED).build();
220        }
221        throw new ResourceNotFoundException(status.getDescription());
222    }
223
224    /**
225     * Remove a Port from a Bridge
226     * <pre>
227     *
228     * Example :
229     *
230     * Request :
231     * DELETE
232     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
233     *
234     *</pre>
235     * @param nodeType Node Type of the node with the management session.
236     * @param nodeId Node Identifier of the node with the management session.
237     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
238     * @param portName Name / Identifier of a Port that is being deleted from a bridge.
239     */
240
241    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
242    @DELETE
243    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
244    @StatusCodes( { @ResponseCode(code = 200, condition = "Port deleted successfully"),
245        @ResponseCode(code = 404, condition = "Could not delete Port to the Bridge"),
246        @ResponseCode(code = 412, condition = "Failed to delete Port due to an exception"),
247        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
248
249    public Response deletePort(
250            @PathParam(value = "nodeType") String nodeType,
251            @PathParam(value = "nodeId") String nodeId,
252            @PathParam(value = "bridgeName") String bridge,
253            @PathParam(value = "portName") String port) {
254
255        IBridgeDomainConfigService configurationService = getConfigurationService();
256        if (configurationService == null) {
257            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
258        }
259
260        Node node = Node.fromString(nodeType, nodeId);
261        Status status = null;
262        try {
263            status = configurationService.deletePort(node, bridge, port);
264            if (status.getCode().equals(StatusCode.SUCCESS)) {
265                return Response.status(Response.Status.OK).build();
266            }
267        } catch (Throwable t) {
268            return Response.status(Response.Status.PRECONDITION_FAILED).build();
269        }
270        throw new ResourceNotFoundException(status.getDescription());
271    }
272
273    private Map<ConfigConstants, Object> buildConfig(Map<String, Object> rawConfigs) {
274        if (rawConfigs == null) return null;
275        Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
276        for (String key : rawConfigs.keySet()) {
277            ConfigConstants cc = ConfigConstants.valueOf(key.toUpperCase());
278            configs.put(cc, rawConfigs.get(key));
279        }
280        return configs;
281    }
282 /**
283     * Add a Port,Vlan to a Bridge
284     * <pre>
285     *
286     * Example :
287     * Request :
288     * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port2/200
289     *
290     * </pre>
291     * @param nodeType Node Type of the node with the management session.
292     * @param nodeId Node Identifier of the node with the management session.
293     * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
294     * @param portName Name / Identifier of a Port that is being added to a bridge.
295     * @param vlan Vlan Id.
296     */
297
298    @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}/{vlan}")
299    @POST
300    @StatusCodes( { @ResponseCode(code = 201, condition = "Created Port with Vlan tag successfully"),
301        @ResponseCode(code = 404, condition = "Could not add Port,Vlan to the Bridge"),
302        @ResponseCode(code = 406, condition = "Invalid Vlan parameter passed."),
303        @ResponseCode(code = 412, condition = "Failed to add Port,Vlan due to an exception"),
304        @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
305
306    public Response addPort(
307            @PathParam(value = "nodeType") String nodeType,
308            @PathParam(value = "nodeId") String nodeId,
309            @PathParam(value = "bridgeName") String bridge,
310            @PathParam(value = "portName") String port,
311            @PathParam(value = "vlan") String vlan) {
312
313        IBridgeDomainConfigService configurationService = getConfigurationService();
314        if (configurationService == null) {
315            throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
316        }
317        try {
318            Integer.parseInt(vlan);
319        } catch (Exception e) {
320            throw new NotAcceptableException("Incorrect Vlan :"+vlan);
321        }
322
323        Node node = Node.fromString(nodeType, nodeId);
324        Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
325        configs.put(ConfigConstants.TYPE, ConfigConstants.VLAN.name());
326        configs.put(ConfigConstants.VLAN, vlan);
327
328        Status status = null;
329        try {
330        status = configurationService.addPort(node, bridge, port, configs);
331        if (status.getCode().equals(StatusCode.SUCCESS)) {
332            return Response.status(Response.Status.CREATED).build();
333        }
334        } catch (Exception e) {
335            return Response.status(Response.Status.PRECONDITION_FAILED).build();
336        }
337        throw new ResourceNotFoundException(status.getDescription());
338    }
339 }