blob: 4fffe6e5a421a6d4c7ce3238e2bf7001f58effbc [file] [log] [blame]
Georgios Katsikas83600982017-05-28 20:41:45 +02001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.drivers.server;
17
Georgios Katsikas80e0b9f2018-07-21 20:29:18 +020018import org.onosproject.drivers.server.devices.RestServerSBDevice;
19
20import org.onosproject.net.DeviceId;
Georgios Katsikas83600982017-05-28 20:41:45 +020021import org.onosproject.net.driver.AbstractHandlerBehaviour;
22import org.onosproject.net.driver.DriverHandler;
23import org.onosproject.protocol.rest.RestSBController;
Georgios Katsikas30bede52018-07-28 14:46:07 +020024import org.onosproject.protocol.rest.RestSBDevice;
Georgios Katsikas83600982017-05-28 20:41:45 +020025
26import org.slf4j.Logger;
Georgios Katsikas80e0b9f2018-07-21 20:29:18 +020027
Georgios Katsikas83600982017-05-28 20:41:45 +020028import com.fasterxml.jackson.databind.JsonNode;
29
30import java.util.EnumSet;
31import javax.ws.rs.core.MediaType;
32import javax.ws.rs.core.Response;
33
34import static org.slf4j.LoggerFactory.getLogger;
35import static com.google.common.base.Preconditions.checkNotNull;
36
37/**
38 * The basic functionality of the server driver.
39 */
40public class BasicServerDriver extends AbstractHandlerBehaviour {
41
42 private final Logger log = getLogger(getClass());
43
44 /**
45 * Resource endpoints of the server agent (REST server-side).
46 */
47 public static final MediaType JSON = MediaType.valueOf(MediaType.APPLICATION_JSON);
48 protected static final String ROOT_URL = "";
Georgios Katsikas30bede52018-07-28 14:46:07 +020049 protected static final String SLASH = "/";
50 public static final String BASE_URL = ROOT_URL + SLASH + "metron";
Georgios Katsikas83600982017-05-28 20:41:45 +020051
52 /**
Georgios Katsikas2ebd8a02018-06-27 18:32:50 +020053 * Common parameters to be exchanged with the server's agent.
54 */
55 public static final String PARAM_ID = "id";
56 public static final String PARAM_NICS = "nics";
57 public static final String PARAM_CPUS = "cpus";
58 public static final String NIC_PARAM_RX_FILTER = "rxFilter";
59 public static final String NIC_PARAM_RX_METHOD = "method";
60
61
62 /**
Georgios Katsikas83600982017-05-28 20:41:45 +020063 * Successful HTTP status codes.
64 */
65 private static final int STATUS_OK = Response.Status.OK.getStatusCode();
66 private static final int STATUS_CREATED = Response.Status.CREATED.getStatusCode();
67 private static final int STATUS_ACCEPTED = Response.Status.ACCEPTED.getStatusCode();
68
69 /**
70 * Messages for error handlers.
71 */
72 protected static final String MASTERSHIP_NULL = "Mastership service is null";
73 protected static final String CONTROLLER_NULL = "RestSB controller is null";
74 protected static final String DEVICE_ID_NULL = "Device ID cannot be null";
75 protected static final String HANDLER_NULL = "Handler cannot be null";
76 protected static final String DEVICE_NULL = "Device cannot be null";
77
78 /**
79 * A unique controller that handles the REST-based communication.
80 */
81 protected static RestSBController controller = null;
82 protected static DriverHandler handler = null;
Ray Milkeyc6c9b172018-02-26 09:36:31 -080083 private static final Object CONTROLLER_LOCK = new Object();
Georgios Katsikas83600982017-05-28 20:41:45 +020084
85 public BasicServerDriver() {};
86
87 /**
Georgios Katsikas30bede52018-07-28 14:46:07 +020088 * Retrieve an instance of the driver handler.
Georgios Katsikas83600982017-05-28 20:41:45 +020089 *
Georgios Katsikas30bede52018-07-28 14:46:07 +020090 * @return DriverHandler instance
Georgios Katsikas83600982017-05-28 20:41:45 +020091 */
Georgios Katsikas30bede52018-07-28 14:46:07 +020092 protected DriverHandler getHandler() {
Ray Milkeyc6c9b172018-02-26 09:36:31 -080093 synchronized (CONTROLLER_LOCK) {
Georgios Katsikas83600982017-05-28 20:41:45 +020094 handler = handler();
95 checkNotNull(handler, HANDLER_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +020096 }
Georgios Katsikas30bede52018-07-28 14:46:07 +020097
98 return handler;
Georgios Katsikas83600982017-05-28 20:41:45 +020099 }
100
101 /**
102 * Retrieve an instance of the REST SB controller.
Georgios Katsikas83600982017-05-28 20:41:45 +0200103 *
104 * @return RestSBController instance
105 */
Georgios Katsikas2ebd8a02018-06-27 18:32:50 +0200106 public RestSBController getController() {
Ray Milkeyc6c9b172018-02-26 09:36:31 -0800107 synchronized (CONTROLLER_LOCK) {
108 if (controller == null) {
Georgios Katsikas30bede52018-07-28 14:46:07 +0200109 controller = getHandler().get(RestSBController.class);
110 checkNotNull(controller, CONTROLLER_NULL);
Ray Milkeyc6c9b172018-02-26 09:36:31 -0800111 }
Georgios Katsikas83600982017-05-28 20:41:45 +0200112 }
Georgios Katsikas30bede52018-07-28 14:46:07 +0200113
Georgios Katsikas83600982017-05-28 20:41:45 +0200114 return controller;
115 }
116
117 /**
Georgios Katsikas80e0b9f2018-07-21 20:29:18 +0200118 * Finds the NIC name that corresponds to a device's port number.
119 *
120 * @param deviceId a device ID
121 * @param port a NIC port number
122 * @return device's NIC name
123 */
124 public static String findNicInterfaceWithPort(DeviceId deviceId, long port) {
Georgios Katsikas30bede52018-07-28 14:46:07 +0200125 if (controller == null) {
126 return null;
127 }
128
Georgios Katsikas80e0b9f2018-07-21 20:29:18 +0200129 RestServerSBDevice device = null;
130 try {
131 device = (RestServerSBDevice) controller.getDevice(deviceId);
132 } catch (ClassCastException ccEx) {
133 return null;
134 }
135 checkNotNull(device, DEVICE_NULL);
136
137 return device.portNameFromNumber(port);
138 }
139
140 /**
Georgios Katsikas83600982017-05-28 20:41:45 +0200141 * Return all the enumeration's types in a space-separated string.
142 *
143 * @param <E> the expected class of the enum
144 * @param enumType the enum class to get its types
145 * @return String with all enumeration types
146 */
Georgios Katsikas30bede52018-07-28 14:46:07 +0200147 public static <E extends Enum<E>> String enumTypesToString(Class<E> enumType) {
Georgios Katsikas83600982017-05-28 20:41:45 +0200148 String allTypes = "";
149 for (E en : EnumSet.allOf(enumType)) {
150 allTypes += en.toString() + " ";
151 }
152
153 return allTypes.trim();
154 }
155
156 /**
157 * Return a string value after reading the input
158 * attribute from the input JSON node.
159 *
160 * @param jsonNode JSON node to read from
161 * @param attribute to lookup in the JSON node
162 * @return string value mapped to the attribute
163 */
164 public static String get(JsonNode jsonNode, String attribute) {
165 if (jsonNode == null || (attribute == null || attribute.isEmpty())) {
166 return null;
167 }
168
169 String result = "";
170
171 try {
172 result = jsonNode.get(attribute).asText();
173 } catch (Exception ex) {
Ray Milkey067c44b2018-02-26 12:48:23 -0800174 throw new IllegalArgumentException(
Georgios Katsikas83600982017-05-28 20:41:45 +0200175 "Failed to read JSON attribute: " + attribute
176 );
177 }
178
179 return result;
180 }
181
182 /**
183 * Assess a given HTTP status code.
184 *
185 * @param statusCode the HTTP status code to check
186 * @return boolean status (success or failure)
187 */
188 public static boolean checkStatusCode(int statusCode) {
189 if (statusCode == STATUS_OK || statusCode == STATUS_CREATED || statusCode == STATUS_ACCEPTED) {
190 return true;
191 }
192
193 return false;
194 }
195
Georgios Katsikas30bede52018-07-28 14:46:07 +0200196 /**
197 * Upon a failure to contact a device, the driver
198 * raises a disconnect event by resetting the
199 * activity flag of this device.
200 *
201 * @param device a device to disconnect
202 */
203 protected void raiseDeviceDisconnect(RestSBDevice device) {
204 // Already done!
205 if (!device.isActive()) {
206 return;
207 }
208
209 log.info("Setting device {} inactive", device.deviceId());
210 device.setActive(false);
211 }
212
Georgios Katsikas83600982017-05-28 20:41:45 +0200213}