3 * Copyright (c) 2013 Red Hat, Inc. and others. All rights reserved.
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
10 package org.opendaylight.controller.connectionmanager.northbound;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.HashMap;
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 import javax.ws.rs.ext.ContextResolver;
32 import org.codehaus.enunciate.jaxrs.ResponseCode;
33 import org.codehaus.enunciate.jaxrs.StatusCodes;
34 import org.codehaus.enunciate.jaxrs.TypeHint;
35 import org.opendaylight.controller.connectionmanager.IConnectionManager;
36 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
37 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
38 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
39 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
40 import org.opendaylight.controller.northbound.commons.query.QueryContext;
41 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
42 import org.opendaylight.controller.sal.authorization.Privilege;
43 import org.opendaylight.controller.sal.connection.ConnectionConstants;
44 import org.opendaylight.controller.sal.core.Node;
45 import org.opendaylight.controller.sal.utils.NetUtils;
46 import org.opendaylight.controller.sal.utils.ServiceHelper;
47 import org.opendaylight.controller.sal.utils.Status;
50 * Connection Manager Northbound APIs
53 public class ConnectionManagerNorthbound {
54 private String username;
55 private QueryContext queryContext;
58 public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
59 if (queryCtxResolver != null) {
60 queryContext = queryCtxResolver.getContext(QueryContext.class);
64 public void setSecurityContext(SecurityContext context) {
65 if (context != null && context.getUserPrincipal() != null) {
66 username = context.getUserPrincipal().getName();
69 protected String getUserName() {
73 private IConnectionManager getConnectionManager() {
74 return (IConnectionManager) ServiceHelper
75 .getGlobalInstance(IConnectionManager.class, this);
80 * Retrieve a list of all the nodes connected to a given controller in the cluster.
82 * @param controllerAddress Optional parameter to retrieve the nodes connected to another
83 * controller in the cluster
84 * @return A list of Nodes {@link org.opendaylight.controller.sal.core.Node}
91 * http://localhost:8080/controller/nb/v2/connectionmanager/nodes?controller=1.1.1.1
93 * Response body in XML:
96 * <id>00:00:00:00:00:00:00:52</id>
97 * <type>OF</type>
100 * <id>00:00:00:00:00:00:00:3e</id>
101 * <type>OF</type>
105 * Response body in JSON:
110 * "id": "00:00:00:00:00:00:00:52"
114 * "id": "00:00:00:00:00:00:00:3e"
122 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
123 @TypeHint(Nodes.class)
125 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
126 @ResponseCode(code = 406, condition = "Invalid Controller IP Address passed."),
127 @ResponseCode(code = 503, condition = "Connection Manager Service not available")})
129 public Nodes getNodes(@DefaultValue("") @QueryParam("controller") String controllerAddress,
130 @QueryParam("_q") String queryString) {
131 if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.READ, this)) {
132 throw new UnauthorizedException("User is not authorized to perform this operation on container");
135 IConnectionManager connectionManager = getConnectionManager();
136 if (connectionManager == null) {
137 throw new ServiceUnavailableException("IConnectionManager not available.");
140 if ((controllerAddress != null) && (controllerAddress.trim().length() > 0) &&
141 !NetUtils.isIPv4AddressValid(controllerAddress)) {
142 throw new NotAcceptableException("Invalid ip address "+controllerAddress);
144 Set<Node> nodeSet = null;
146 if (controllerAddress != null) {
148 nodeSet = connectionManager.getNodes(InetAddress.getByName(controllerAddress));
149 } catch (UnknownHostException e) {
150 throw new NotAcceptableException("Invalid ip address "+controllerAddress);
153 nodeSet = connectionManager.getLocalNodes();
155 Nodes nodes = new Nodes(nodeSet);
156 if (queryString != null) {
157 queryContext.createQuery(queryString, Nodes.class)
158 .filter(nodes, Node.class);
164 * If a Network Configuration Service needs a Management Connection and if the
165 * Node Type is unknown, use this REST api to connect to the management session.
171 * PUT http://localhost:8080/controller/nb/v2/connectionmanager/node/mgmt1/address/1.1.1.1/port/6634
177 * <id>mgmt1</id>
178 * <type>STUB</type>
182 * {"id": "mgmt1","type": "STUB"}
185 * @param nodeId User-Defined name of the node to connect with. This can be any alpha numeric value
186 * @param ipAddress IP Address of the Node to connect with.
187 * @param port Layer4 Port of the management session to connect with.
188 * @return Node If the connection is successful, HTTP 404 otherwise.
191 @Path("/node/{nodeId}/address/{ipAddress}/port/{port}/")
193 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
194 @TypeHint(Node.class)
196 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
197 @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
198 @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
199 @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
201 @PathParam(value = "nodeId") String nodeId,
202 @PathParam(value = "ipAddress") String ipAddress,
203 @PathParam(value = "port") String port) {
205 if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
206 throw new UnauthorizedException("User is not authorized to perform this operation on container");
209 IConnectionManager connectionManager = getConnectionManager();
210 if (connectionManager == null) {
211 throw new ServiceUnavailableException("IConnectionManager not available.");
214 if (!NetUtils.isIPv4AddressValid(ipAddress)) {
215 throw new NotAcceptableException("Invalid ip address "+ipAddress);
219 Integer.parseInt(port);
220 } catch (Exception e) {
221 throw new NotAcceptableException("Invalid Layer4 Port "+port);
224 Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
225 params.put(ConnectionConstants.ADDRESS, ipAddress);
226 params.put(ConnectionConstants.PORT, port);
230 node = connectionManager.connect(nodeId, params);
232 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
235 } catch (Exception e) {
236 throw new ResourceNotFoundException("Failed to connect to Node with Exception "+e.getMessage());
241 * If a Network Configuration Service needs a Management Connection, and if the
242 * node Type is known, the user can choose to use this REST api to connect to the management session.
248 * PUT http://localhost:8080/controller/nb/v2/connectionmanager/node/STUB/mgmt1/address/1.1.1.1/port/6634
253 * <id>mgmt1</id>
254 * <type>STUB</type>
258 * {"id": "mgmt1","type": "STUB"}
261 * @param nodeType Type of the Node the connection is made for.
262 * @param nodeId User-Defined name of the node to connect with. This can be any alpha numeric value
263 * @param ipAddress IP Address of the Node to connect with.
264 * @param port Layer4 Port of the management session to connect with.
265 * @return Node If the connection is successful, HTTP 404 otherwise.
268 @Path("/node/{nodeType}/{nodeId}/address/{ipAddress}/port/{port}/")
270 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
271 @TypeHint(Node.class)
273 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
274 @ResponseCode(code = 404, condition = "Could not connect to the Node with the specified parameters"),
275 @ResponseCode(code = 406, condition = "Invalid IP Address or Port parameter passed."),
276 @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
278 @PathParam(value = "nodeType") String nodeType,
279 @PathParam(value = "nodeId") String nodeId,
280 @PathParam(value = "ipAddress") String ipAddress,
281 @PathParam(value = "port") String port) {
283 if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
284 throw new UnauthorizedException("User is not authorized to perform this operation on container");
287 IConnectionManager connectionManager = getConnectionManager();
288 if (connectionManager == null) {
289 throw new ServiceUnavailableException("IConnectionManager not available.");
292 if (!NetUtils.isIPv4AddressValid(ipAddress)) {
293 throw new NotAcceptableException("Invalid ip address "+ipAddress);
297 Integer.parseInt(port);
298 } catch (Exception e) {
299 throw new NotAcceptableException("Invalid Layer4 Port "+port);
302 Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
303 params.put(ConnectionConstants.ADDRESS, ipAddress);
304 params.put(ConnectionConstants.PORT, port);
308 node = connectionManager.connect(nodeType, nodeId, params);
310 throw new ResourceNotFoundException("Failed to connect to Node at "+ipAddress+":"+port);
313 } catch (Exception e) {
314 throw new ResourceNotFoundException(e.getMessage());
319 * Disconnect an existing Connection.
325 * DELETE http://localhost:8080/controller/nb/v2/connectionmanager/node/STUB/mgmt1
328 * @param nodeType Type of the Node
329 * @param nodeId Connection's NodeId.
332 @Path("/node/{nodeType}/{nodeId}/")
334 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
335 @TypeHint(Response.class)
337 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
338 @ResponseCode(code = 200, condition = "Node disconnected successfully"),
339 @ResponseCode(code = 404, condition = "Could not find a connection with the specified Node identifier"),
340 @ResponseCode(code = 503, condition = "Connection Manager Service not available")} )
341 public Response disconnect(
342 @PathParam(value = "nodeType") String nodeType,
343 @PathParam(value = "nodeId") String nodeId) {
345 if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
346 throw new UnauthorizedException("User is not authorized to perform this operation on container");
348 IConnectionManager connectionManager = getConnectionManager();
349 if (connectionManager == null) {
350 throw new ServiceUnavailableException("IConnectionManager not available.");
354 Node node = Node.fromString(nodeType, nodeId);
355 Status status = connectionManager.disconnect(node);
356 if (status.isSuccess()) {
357 return Response.ok().build();
359 return NorthboundUtils.getResponse(status);
360 } catch (Exception e) {
361 throw new ResourceNotFoundException(e.getMessage());