Moving the connection manager NB-API from the network configuration APIs to connectio...
[controller.git] / opendaylight / northbound / connectionmanager / src / main / java / org / opendaylight / controller / connectionmanager / northbound / ConnectionManagerNorthbound.java
1
2 /*
3  * Copyright (c) 2013 Red Hat, 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.connectionmanager.northbound;
11
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.HashMap;
15 import java.util.Map;
16 import java.util.Set;
17
18 import javax.ws.rs.DELETE;
19 import javax.ws.rs.DefaultValue;
20 import javax.ws.rs.GET;
21 import javax.ws.rs.PUT;
22 import javax.ws.rs.Path;
23 import javax.ws.rs.PathParam;
24 import javax.ws.rs.Produces;
25 import javax.ws.rs.QueryParam;
26 import javax.ws.rs.core.Context;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
29 import javax.ws.rs.core.SecurityContext;
30
31 import org.codehaus.enunciate.jaxrs.ResponseCode;
32 import org.codehaus.enunciate.jaxrs.StatusCodes;
33 import org.codehaus.enunciate.jaxrs.TypeHint;
34 import org.opendaylight.controller.connectionmanager.IConnectionManager;
35 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
36 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
37 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
38 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
39 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
40 import org.opendaylight.controller.sal.authorization.Privilege;
41 import org.opendaylight.controller.sal.connection.ConnectionConstants;
42 import org.opendaylight.controller.sal.core.Node;
43 import org.opendaylight.controller.sal.utils.NetUtils;
44 import org.opendaylight.controller.sal.utils.ServiceHelper;
45 import org.opendaylight.controller.sal.utils.Status;
46
47 /**
48  * Connection Manager Northbound APIs
49  */
50 @Path("/")
51 public class ConnectionManagerNorthbound {
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 IConnectionManager getConnectionManager() {
63         return (IConnectionManager) ServiceHelper
64                 .getGlobalInstance(IConnectionManager.class, this);
65     }
66
67     /**
68      *
69      * Retrieve a list of all the nodes connected to a given controller in the cluster.
70      *
71      * @param controllerAddress Optional parameter to retrieve the nodes connected to another
72      *        controller in the cluster
73      * @return A list of Nodes {@link org.opendaylight.controller.sal.core.Node}
74      *
75      * <pre>
76      *
77      * Example:
78      *
79      * Request URL:
80      * http://localhost:8080/controller/nb/v2/connectionmanager/nodes?controller=1.1.1.1
81      *
82      * Response body in XML:
83      *  &lt;list&gt;
84      *       &lt;node&gt;
85      *           &lt;id&gt;00:00:00:00:00:00:00:52&lt;/id&gt;
86      *           &lt;type&gt;OF&lt;/type&gt;
87      *       &lt;/node&gt;
88      *       &lt;node&gt;
89      *           &lt;id&gt;00:00:00:00:00:00:00:3e&lt;/id&gt;
90      *           &lt;type&gt;OF&lt;/type&gt;
91      *       &lt;/node&gt;
92      *   &lt;/list&gt;
93      *
94      *  Response body in JSON:
95      *  {
96      *       "node": [
97      *           {
98      *               "type": "OF",
99      *               "id": "00:00:00:00:00:00:00:52"
100      *           },
101      *           {
102      *               "type": "OF",
103      *               "id": "00:00:00:00:00:00:00:3e"
104      *           }
105      *       ]
106      *   }
107      * </pre>
108      */
109     @Path("/nodes")
110     @GET
111     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
112     @TypeHint(Nodes.class)
113     @StatusCodes( {
114         @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
115         @ResponseCode(code = 406, condition = "Invalid Controller IP Address passed."),
116         @ResponseCode(code = 503, condition = "Connection Manager Service not available")})
117
118     public Nodes getNodes(@DefaultValue("") @QueryParam("controller") String controllerAddress) {
119         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.READ, this)) {
120             throw new UnauthorizedException("User is not authorized to perform this operation on container");
121         }
122
123         IConnectionManager connectionManager = getConnectionManager();
124         if (connectionManager == null) {
125             throw new ServiceUnavailableException("IConnectionManager not available.");
126         }
127
128         if ((controllerAddress != null) && (controllerAddress.trim().length() > 0) &&
129             !NetUtils.isIPv4AddressValid(controllerAddress)) {
130             throw new NotAcceptableException("Invalid ip address "+controllerAddress);
131         }
132         Set<Node> nodeSet = null;
133
134         if (controllerAddress != null) {
135             try {
136                 nodeSet = connectionManager.getNodes(InetAddress.getByName(controllerAddress));
137             } catch (UnknownHostException e) {
138                 throw new NotAcceptableException("Invalid ip address "+controllerAddress);
139             }
140         } else {
141             nodeSet = connectionManager.getLocalNodes();
142         }
143         return new Nodes(nodeSet);
144     }
145
146     /**
147      * If a Network Configuration Service needs a Management Connection and if the
148      * Node Type is unknown, use this REST api to connect to the management session.
149      * <pre>
150      *
151      * Example :
152      *
153      * Request :
154      * PUT http://localhost:8080/controller/nb/v2/connectionmanager/node/mgmt1/address/1.1.1.1/port/6634
155      *
156      * Response :
157      * Node :
158      * xml :
159      * &lt;node&gt;
160      *    &lt;id&gt;mgmt1&lt;/id&gt;
161      *    &lt;type&gt;STUB&lt;/type&gt;
162      * &lt;/node&gt;
163      *
164      * json:
165      * {"id": "mgmt1","type": "STUB"}
166      *
167      *</pre>
168      * @param nodeId User-Defined name of the node to connect with. This can be any alpha numeric value
169      * @param ipAddress IP Address of the Node to connect with.
170      * @param port Layer4 Port of the management session to connect with.
171      * @return Node If the connection is successful, HTTP 404 otherwise.
172      */
173
174     @Path("/node/{nodeId}/address/{ipAddress}/port/{port}/")
175     @PUT
176     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
177     @TypeHint(Node.class)
178     @StatusCodes( {
179         @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
180         @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
181         @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
182         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
183     public Node connect(
184             @PathParam(value = "nodeId") String nodeId,
185             @PathParam(value = "ipAddress") String ipAddress,
186             @PathParam(value = "port") String port) {
187
188         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
189             throw new UnauthorizedException("User is not authorized to perform this operation on container");
190         }
191
192         IConnectionManager connectionManager = getConnectionManager();
193         if (connectionManager == null) {
194             throw new ServiceUnavailableException("IConnectionManager not available.");
195         }
196
197         if (!NetUtils.isIPv4AddressValid(ipAddress)) {
198             throw new NotAcceptableException("Invalid ip address "+ipAddress);
199         }
200
201         try {
202             Integer.parseInt(port);
203         } catch (Exception e) {
204             throw new NotAcceptableException("Invalid Layer4 Port "+port);
205         }
206
207         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
208         params.put(ConnectionConstants.ADDRESS, ipAddress);
209         params.put(ConnectionConstants.PORT, port);
210
211         Node node = null;
212         try {
213             node = connectionManager.connect(nodeId, params);
214             if (node == null) {
215                 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
216             }
217             return node;
218         } catch (Exception e) {
219             throw new ResourceNotFoundException("Failed to connect to Node with Exception "+e.getMessage());
220         }
221     }
222
223     /**
224      * If a Network Configuration Service needs a Management Connection, and if the
225      * node Type is known, the user can choose to use this REST api to connect to the management session.
226      * <pre>
227      *
228      * Example :
229      *
230      * Request :
231      * PUT http://localhost:8080/controller/nb/v2/connectionmanager/node/STUB/mgmt1/address/1.1.1.1/port/6634
232      *
233      * Response : Node :
234      * xml :
235      * &lt;node&gt;
236      *    &lt;id&gt;mgmt1&lt;/id&gt;
237      *    &lt;type&gt;STUB&lt;/type&gt;
238      * &lt;/node&gt;
239      *
240      * json:
241      * {"id": "mgmt1","type": "STUB"}
242      *
243      *</pre>
244      * @param nodeType Type of the Node the connection is made for.
245      * @param nodeId User-Defined name of the node to connect with. This can be any alpha numeric value
246      * @param ipAddress IP Address of the Node to connect with.
247      * @param port Layer4 Port of the management session to connect with.
248      * @return Node If the connection is successful, HTTP 404 otherwise.
249      */
250
251     @Path("/node/{nodeType}/{nodeId}/address/{ipAddress}/port/{port}/")
252     @PUT
253     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
254     @TypeHint(Node.class)
255     @StatusCodes( {
256         @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
257         @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
258         @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
259         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
260     public Node connect(
261             @PathParam(value = "nodeType") String nodeType,
262             @PathParam(value = "nodeId") String nodeId,
263             @PathParam(value = "ipAddress") String ipAddress,
264             @PathParam(value = "port") String port) {
265
266         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
267             throw new UnauthorizedException("User is not authorized to perform this operation on container");
268         }
269
270         IConnectionManager connectionManager = getConnectionManager();
271         if (connectionManager == null) {
272             throw new ServiceUnavailableException("IConnectionManager not available.");
273         }
274
275         if (!NetUtils.isIPv4AddressValid(ipAddress)) {
276             throw new NotAcceptableException("Invalid ip address "+ipAddress);
277         }
278
279         try {
280             Integer.parseInt(port);
281         } catch (Exception e) {
282             throw new NotAcceptableException("Invalid Layer4 Port "+port);
283         }
284
285         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
286         params.put(ConnectionConstants.ADDRESS, ipAddress);
287         params.put(ConnectionConstants.PORT, port);
288
289         Node node = null;
290         try {
291             node = connectionManager.connect(nodeType, nodeId, params);
292             if (node == null) {
293                 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
294             }
295             return node;
296         } catch (Exception e) {
297             throw new ResourceNotFoundException(e.getMessage());
298         }
299     }
300
301     /**
302      * Disconnect an existing Connection.
303      * <pre>
304      *
305      * Example :
306      *
307      * Request :
308      * DELETE http://localhost:8080/controller/nb/v2/connectionmanager/node/STUB/mgmt1
309      *
310      *</pre>
311      * @param nodeType Type of the Node
312      * @param nodeId Connection's NodeId.
313      */
314
315     @Path("/node/{nodeType}/{nodeId}/")
316     @DELETE
317     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
318     @TypeHint(Response.class)
319     @StatusCodes( {
320         @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
321         @ResponseCode(code = 200, condition = "Node disconnected successfully"),
322         @ResponseCode(code = 404, condition = "Could not find a connection with the specified Node identifier"),
323         @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
324     public Response disconnect(
325             @PathParam(value = "nodeType") String nodeType,
326             @PathParam(value = "nodeId") String nodeId) {
327
328         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
329             throw new UnauthorizedException("User is not authorized to perform this operation on container");
330         }
331         IConnectionManager connectionManager = getConnectionManager();
332         if (connectionManager == null) {
333             throw new ServiceUnavailableException("IConnectionManager not available.");
334         }
335
336         try {
337             Node node = new Node(nodeType, nodeId);
338             Status status = connectionManager.disconnect(node);
339             if (status.isSuccess()) {
340                 return Response.ok().build();
341             }
342             return NorthboundUtils.getResponse(status);
343         } catch (Exception e) {
344             throw new ResourceNotFoundException(e.getMessage());
345         }
346     }
347 }