blob: 046578a2ce54a3bcf63d229ba9fdbb5e27c9fb3b [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;
24
25import org.onlab.osgi.ServiceNotFoundException;
26
27import org.slf4j.Logger;
Georgios Katsikas80e0b9f2018-07-21 20:29:18 +020028
Georgios Katsikas83600982017-05-28 20:41:45 +020029import com.fasterxml.jackson.databind.JsonNode;
30
31import java.util.EnumSet;
32import javax.ws.rs.core.MediaType;
33import javax.ws.rs.core.Response;
34
35import static org.slf4j.LoggerFactory.getLogger;
36import static com.google.common.base.Preconditions.checkNotNull;
37
38/**
39 * The basic functionality of the server driver.
40 */
41public class BasicServerDriver extends AbstractHandlerBehaviour {
42
43 private final Logger log = getLogger(getClass());
44
45 /**
46 * Resource endpoints of the server agent (REST server-side).
47 */
48 public static final MediaType JSON = MediaType.valueOf(MediaType.APPLICATION_JSON);
49 protected static final String ROOT_URL = "";
50 public static final String BASE_URL = ROOT_URL + "/metron";
51
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 /**
88 * Initialize the REST SB controller (if not already).
89 * Creates a handler and a controller only once, and
90 * then re-uses these objects.
91 *
92 * @throws ServiceNotFoundException when either the handler
93 * or the controller cannot be retrieved.
94 */
95 private void init() {
Ray Milkeyc6c9b172018-02-26 09:36:31 -080096 synchronized (CONTROLLER_LOCK) {
97 // Already done
98 if ((handler != null) && (controller != null)) {
99 return;
100 }
Georgios Katsikas83600982017-05-28 20:41:45 +0200101
Georgios Katsikas83600982017-05-28 20:41:45 +0200102 handler = handler();
103 checkNotNull(handler, HANDLER_NULL);
104 controller = handler.get(RestSBController.class);
105 checkNotNull(controller, CONTROLLER_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +0200106 }
107 }
108
109 /**
110 * Retrieve an instance of the REST SB controller.
111 * Method init will only be called the first time
112 * this method (or getHandler) is invoked.
113 *
114 * @return RestSBController instance
115 */
Georgios Katsikas2ebd8a02018-06-27 18:32:50 +0200116 public RestSBController getController() {
Ray Milkeyc6c9b172018-02-26 09:36:31 -0800117 synchronized (CONTROLLER_LOCK) {
118 if (controller == null) {
119 init();
120 }
Georgios Katsikas83600982017-05-28 20:41:45 +0200121 }
Georgios Katsikas83600982017-05-28 20:41:45 +0200122 return controller;
123 }
124
125 /**
126 * Retrieve an instance of the driver handler.
127 * Method init will only be called the first time
128 * this method (or getController) is invoked.
129 *
130 * @return DriverHandler instance
131 */
132 protected DriverHandler getHandler() {
Ray Milkeyc6c9b172018-02-26 09:36:31 -0800133 synchronized (CONTROLLER_LOCK) {
134 if (handler == null) {
135 init();
136 }
Georgios Katsikas83600982017-05-28 20:41:45 +0200137 }
138
139 return handler;
140 }
141
142 /**
Georgios Katsikas80e0b9f2018-07-21 20:29:18 +0200143 * Finds the NIC name that corresponds to a device's port number.
144 *
145 * @param deviceId a device ID
146 * @param port a NIC port number
147 * @return device's NIC name
148 */
149 public static String findNicInterfaceWithPort(DeviceId deviceId, long port) {
150 RestServerSBDevice device = null;
151 try {
152 device = (RestServerSBDevice) controller.getDevice(deviceId);
153 } catch (ClassCastException ccEx) {
154 return null;
155 }
156 checkNotNull(device, DEVICE_NULL);
157
158 return device.portNameFromNumber(port);
159 }
160
161 /**
Georgios Katsikas83600982017-05-28 20:41:45 +0200162 * Return all the enumeration's types in a space-separated string.
163 *
164 * @param <E> the expected class of the enum
165 * @param enumType the enum class to get its types
166 * @return String with all enumeration types
167 */
168 public static <E extends Enum<E>> String enumTypesToString(
169 Class<E> enumType) {
170 String allTypes = "";
171 for (E en : EnumSet.allOf(enumType)) {
172 allTypes += en.toString() + " ";
173 }
174
175 return allTypes.trim();
176 }
177
178 /**
179 * Return a string value after reading the input
180 * attribute from the input JSON node.
181 *
182 * @param jsonNode JSON node to read from
183 * @param attribute to lookup in the JSON node
184 * @return string value mapped to the attribute
185 */
186 public static String get(JsonNode jsonNode, String attribute) {
187 if (jsonNode == null || (attribute == null || attribute.isEmpty())) {
188 return null;
189 }
190
191 String result = "";
192
193 try {
194 result = jsonNode.get(attribute).asText();
195 } catch (Exception ex) {
Ray Milkey067c44b2018-02-26 12:48:23 -0800196 throw new IllegalArgumentException(
Georgios Katsikas83600982017-05-28 20:41:45 +0200197 "Failed to read JSON attribute: " + attribute
198 );
199 }
200
201 return result;
202 }
203
204 /**
205 * Assess a given HTTP status code.
206 *
207 * @param statusCode the HTTP status code to check
208 * @return boolean status (success or failure)
209 */
210 public static boolean checkStatusCode(int statusCode) {
211 if (statusCode == STATUS_OK || statusCode == STATUS_CREATED || statusCode == STATUS_ACCEPTED) {
212 return true;
213 }
214
215 return false;
216 }
217
218}