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