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