Server device driver extensions
* Additional behaviours implemented
* BasicSystemOperations
* DeviceHandshaker
* InterfaceConfig
* PortAdmin
* QueueConfig
* TableStatisticsDiscovery
* DeviceSystemStatisticsQuery
* New device abstractions on CPU cache and main memory
* Additional statistics (main memory)
* New UI with Memory statistics (based on the old gui)
* Constants decoupled from implementations
* More builders used for interface implementations
* Style fixes and refactoring
Change-Id: Ie54ed0fb4760456cfd6339c74b36486dd3c20f87
Signed-off-by: Georgios Katsikas <katsikas.gp@gmail.com>
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java b/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java
index d1cb020..5e6781d 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server;
import org.onosproject.drivers.server.devices.RestServerSBDevice;
@@ -28,11 +29,13 @@
import com.fasterxml.jackson.databind.JsonNode;
import java.util.EnumSet;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import static org.slf4j.LoggerFactory.getLogger;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_CONTROLLER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_HANDLER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* The basic functionality of the server driver.
@@ -42,24 +45,6 @@
private final Logger log = getLogger(getClass());
/**
- * Resource endpoints of the server agent (REST server-side).
- */
- public static final MediaType JSON = MediaType.valueOf(MediaType.APPLICATION_JSON);
- protected static final String ROOT_URL = "";
- protected static final String SLASH = "/";
- public static final String BASE_URL = ROOT_URL + SLASH + "metron";
-
- /**
- * Common parameters to be exchanged with the server's agent.
- */
- public static final String PARAM_ID = "id";
- public static final String PARAM_NICS = "nics";
- public static final String PARAM_CPUS = "cpus";
- public static final String NIC_PARAM_RX_FILTER = "rxFilter";
- public static final String NIC_PARAM_RX_METHOD = "method";
-
-
- /**
* Successful HTTP status codes.
*/
private static final int STATUS_OK = Response.Status.OK.getStatusCode();
@@ -67,20 +52,11 @@
private static final int STATUS_ACCEPTED = Response.Status.ACCEPTED.getStatusCode();
/**
- * Messages for error handlers.
- */
- protected static final String MASTERSHIP_NULL = "Mastership service is null";
- protected static final String CONTROLLER_NULL = "RestSB controller is null";
- protected static final String DEVICE_ID_NULL = "Device ID cannot be null";
- protected static final String HANDLER_NULL = "Handler cannot be null";
- protected static final String DEVICE_NULL = "Device cannot be null";
-
- /**
* A unique controller that handles the REST-based communication.
*/
protected static RestSBController controller = null;
protected static DriverHandler handler = null;
- private static final Object CONTROLLER_LOCK = new Object();
+ protected static final Object CONTROLLER_LOCK = new Object();
public BasicServerDriver() {};
@@ -90,9 +66,11 @@
* @return DriverHandler instance
*/
protected DriverHandler getHandler() {
- synchronized (CONTROLLER_LOCK) {
- handler = handler();
- checkNotNull(handler, HANDLER_NULL);
+ if (handler == null) {
+ synchronized (CONTROLLER_LOCK) {
+ handler = super.handler();
+ checkNotNull(handler, MSG_HANDLER_NULL);
+ }
}
return handler;
@@ -107,7 +85,7 @@
synchronized (CONTROLLER_LOCK) {
if (controller == null) {
controller = getHandler().get(RestSBController.class);
- checkNotNull(controller, CONTROLLER_NULL);
+ checkNotNull(controller, MSG_CONTROLLER_NULL);
}
}
@@ -115,6 +93,25 @@
}
/**
+ * Retrieve an instance of the REST SB device, given its ID.
+ *
+ * @param deviceId a device ID
+ * @return RestSBDevice instance
+ */
+ public RestSBDevice getDevice(DeviceId deviceId) {
+ return getController().getDevice(deviceId);
+ }
+
+ /**
+ * Retrieve a REST SB device ID.
+ *
+ * @return a device Id
+ */
+ public DeviceId getDeviceId() {
+ return getHandler().data().deviceId();
+ }
+
+ /**
* Finds the NIC name that corresponds to a device's port number.
*
* @param deviceId a device ID
@@ -132,7 +129,7 @@
} catch (ClassCastException ccEx) {
return null;
}
- checkNotNull(device, DEVICE_NULL);
+ checkNotNull(device, MSG_DEVICE_NULL);
return device.portNameFromNumber(port);
}
@@ -194,6 +191,16 @@
}
/**
+ * Check whether a server device is active or not.
+ *
+ * @param device a device to check
+ * @return boolean status (true for active or false for inactive)
+ */
+ protected boolean deviceIsActive(RestSBDevice device) {
+ return device.isActive();
+ }
+
+ /**
* Raise a connect event by setting the
* activity flag of this device.
*
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/Constants.java b/drivers/server/src/main/java/org/onosproject/drivers/server/Constants.java
new file mode 100644
index 0000000..aa594ae
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/Constants.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onosproject.drivers.server.devices.cpu.CpuCoreId;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuVendor;
+import org.onosproject.drivers.server.devices.memory.MemoryModuleDevice;
+import org.onosproject.drivers.server.devices.nic.NicDevice;
+import org.onosproject.drivers.server.devices.nic.NicRxFilter.RxFilter;
+import org.onosproject.drivers.server.stats.CpuStatistics;
+
+import javax.ws.rs.core.MediaType;
+
+/**
+ * Provides constants used by the server device driver.
+ */
+public final class Constants {
+
+ private Constants() {
+
+ }
+
+ /**
+ * Generic parameters to be exchanged with the server's agent.
+ */
+ public static final String PARAM_AUTOSCALE = "autoScale";
+ public static final String PARAM_CAPACITY = "capacity";
+ public static final String PARAM_CHASSIS_ID = "chassisId";
+ public static final String PARAM_CONNECTION_STATUS = "connectionStatus";
+ public static final String PARAM_CPU_CACHES = "cpuCaches";
+ public static final String PARAM_CPU_CACHE_HIERARCHY = "cpuCacheHierarchy";
+ public static final String PARAM_CPUS = "cpus";
+ public static final String PARAM_HW_VENDOR = "hwVersion";
+ public static final String PARAM_ID = "id";
+ public static final String PARAM_MANUFACTURER = "manufacturer";
+ public static final String PARAM_MEMORY = "memory";
+ public static final String PARAM_MEMORY_HIERARCHY = "memoryHierarchy";
+ public static final String PARAM_MEMORY_MODULES = "modules";
+ public static final String PARAM_NAME = "name";
+ public static final String PARAM_NICS = "nics";
+ public static final String PARAM_QUEUES = "queues";
+ public static final String PARAM_RULES = "rules";
+ public static final String PARAM_RULE_CONTENT = "content";
+ public static final String PARAM_SPEED = "speed";
+ public static final String PARAM_SPEED_CONF = "speedConfigured";
+ public static final String PARAM_SW_VENDOR = "swVersion";
+ public static final String PARAM_SERIAL = "serial";
+ public static final String PARAM_STATUS = "status";
+ public static final String PARAM_TIME = "time";
+ public static final String PARAM_TIMING_STATS = "timingStats";
+ public static final String PARAM_TIMING_STATS_AUTOSCALE = "timingStatsAutoscale";
+ public static final String PARAM_TYPE = "type";
+
+ /**
+ * Controller configuration parameters.
+ */
+ public static final String PARAM_CTRL = "controllers";
+ public static final String PARAM_CTRL_IP = "ip";
+ public static final String PARAM_CTRL_PORT = "port";
+ public static final String PARAM_CTRL_TYPE = "type";
+
+ /**
+ * CPU parameters.
+ */
+ public static final String PARAM_CPU_CORES = "cores";
+ public static final String PARAM_CPU_ID_LOG = "logicalId";
+ public static final String PARAM_CPU_ID_PHY = "physicalId";
+ public static final String PARAM_CPU_SOCKET = "socket";
+ public static final String PARAM_CPU_SOCKETS = "sockets";
+ public static final String PARAM_CPU_VENDOR = "vendor";
+ public static final String PARAM_CPUS_MAX = "maxCpus";
+
+ /**
+ * CPU cache parameters.
+ */
+ public static final String PARAM_CPU_CACHE_LEVEL = "level";
+ public static final String PARAM_CPU_CACHE_LEVELS = "levels";
+ public static final String PARAM_CPU_CACHE_SHARED = "shared";
+ public static final String PARAM_CPU_CACHE_LINE_LEN = "lineLength";
+ public static final String PARAM_CPU_CACHE_POLICY = "policy";
+ public static final String PARAM_CPU_CACHE_SETS = "sets";
+ public static final String PARAM_CPU_CACHE_TYPE = "type";
+ public static final String PARAM_CPU_CACHE_WAYS = "ways";
+
+ /**
+ * Memory parameters.
+ */
+ public static final String PARAM_MEMORY_STATS_FREE = "free";
+ public static final String PARAM_MEMORY_STATS_TOTAL = "total";
+ public static final String PARAM_MEMORY_STATS_USED = "used";
+ public static final String PARAM_MEMORY_WIDTH_DATA = "dataWidth";
+ public static final String PARAM_MEMORY_WIDTH_TOTAL = "totalWidth";
+
+ /**
+ * NIC parameters.
+ */
+ public static final String PARAM_NIC_HW_ADDR = "hwAddr";
+ public static final String PARAM_NIC_MAX_RATE = "maxRate";
+ public static final String PARAM_NIC_PORT = "port";
+ public static final String PARAM_NIC_PORT_TYPE = "portType";
+ public static final String PARAM_NIC_PORT_TYPE_COPPER = "copper";
+ public static final String PARAM_NIC_PORT_TYPE_FIBER = "fiber";
+ public static final String PARAM_NIC_PORT_STATUS = "portStatus";
+ public static final String PARAM_NIC_RX_FILTER = "rxFilter";
+ public static final String PARAM_NIC_RX_FILTER_FD = "flow";
+ /* Rx filtering methods usually implemented by NICs in commodity servers. */
+ public static final String PARAM_NIC_RX_METHOD = "method";
+ public static final String PARAM_NIC_RX_METHOD_FLOW = "flow";
+ public static final String PARAM_NIC_RX_METHOD_MAC = "mac";
+ public static final String PARAM_NIC_RX_METHOD_MPLS = "mpls";
+ public static final String PARAM_NIC_RX_METHOD_RSS = "rss";
+ public static final String PARAM_NIC_RX_METHOD_VLAN = "vlan";
+ public static final String PARAM_NIC_RX_METHOD_VALUES = "values";
+ public static final String PARAM_NIC_TABLE = "table";
+ public static final String PARAM_NIC_TABLE_ACTIVE_ENTRIES = "activeEntries";
+ public static final String PARAM_NIC_TABLE_PKTS_LOOKED_UP = "pktsLookedUp";
+ public static final String PARAM_NIC_TABLE_PKTS_MATCHED = "pktsMatched";
+ public static final String PARAM_NIC_TABLE_MAX_SIZE = "maxSize";
+
+ /**
+ * NIC statistics' parameters.
+ */
+ public static final String PARAM_NIC_STATS_RX_COUNT = "rxCount";
+ public static final String PARAM_NIC_STATS_RX_BYTES = "rxBytes";
+ public static final String PARAM_NIC_STATS_RX_DROPS = "rxDropped";
+ public static final String PARAM_NIC_STATS_RX_ERRORS = "rxErrors";
+ public static final String PARAM_NIC_STATS_TX_COUNT = "txCount";
+ public static final String PARAM_NIC_STATS_TX_BYTES = "txBytes";
+ public static final String PARAM_NIC_STATS_TX_DROPS = "txDropped";
+ public static final String PARAM_NIC_STATS_TX_ERRORS = "txErrors";
+
+ /**
+ * CPU statistics' parameters.
+ */
+ public static final String PARAM_CPU_FREQUENCY = "frequency";
+ public static final String PARAM_CPU_LATENCY = "latency";
+ public static final String PARAM_CPU_LOAD = "load";
+ public static final String PARAM_CPU_QUEUE = "queue";
+ public static final String PARAM_CPU_STATUS = "busy";
+ public static final String PARAM_CPU_THROUGHPUT = "throughput";
+
+ /**
+ * Other monitoring statistics' parameters.
+ */
+ public static final String PARAM_MON_AVERAGE = "average";
+ public static final String PARAM_MON_BUSY_CPUS = "busyCpus";
+ public static final String PARAM_MON_FREE_CPUS = "freeCpus";
+ public static final String PARAM_MON_MAX = "max";
+ public static final String PARAM_MON_MIN = "min";
+ public static final String PARAM_MON_UNIT = "unit";
+
+ /**
+ * Timing statistics' parameters.
+ */
+ public static final String PARAM_TIMING_AUTOSCALE = "autoScaleTime";
+ public static final String PARAM_TIMING_DEPLOY = "deployTime";
+ public static final String PARAM_TIMING_LAUNCH = "launchTime";
+ public static final String PARAM_TIMING_PARSE = "parseTime";
+
+ /**
+ * Resource API endpoints.
+ */
+ public static final MediaType JSON = MediaType.valueOf(MediaType.APPLICATION_JSON);
+ public static final String SLASH = "/";
+ public static final String URL_ROOT = "";
+ public static final String URL_BASE = URL_ROOT + SLASH + "metron";
+
+ public static final String URL_CONTROLLERS_GET = URL_BASE + SLASH + "controllers";
+ public static final String URL_CONTROLLERS_SET = URL_BASE + SLASH + "controllers";
+ public static final String URL_CONTROLLERS_DEL = URL_BASE + SLASH + "controllers_delete";
+ public static final String URL_NIC_LINK_DISCOVERY = URL_BASE + SLASH + "nic_link_disc";
+ public static final String URL_NIC_PORT_ADMIN = URL_BASE + SLASH + "nic_ports";
+ public static final String URL_NIC_QUEUE_ADMIN = URL_BASE + SLASH + "nic_queues";
+ public static final String URL_RULE_MANAGEMENT = URL_BASE + SLASH + "rules";
+ public static final String URL_RULE_TABLE_STATS = URL_BASE + SLASH + "rules_table_stats";
+ public static final String URL_SERVICE_CHAINS_STATS = URL_BASE + SLASH + "service_chains_stats"; // + /ID
+ public static final String URL_SRV_GLOBAL_STATS = URL_BASE + SLASH + "server_stats";
+ public static final String URL_SRV_PROBE_CONNECT = URL_BASE + SLASH + "server_connect";
+ public static final String URL_SRV_PROBE_DISCONNECT = URL_BASE + SLASH + "server_disconnect";
+ public static final String URL_SRV_RESOURCE_DISCOVERY = URL_BASE + SLASH + "server_resources";
+ public static final String URL_SRV_TIME_DISCOVERY = URL_BASE + SLASH + "server_time";
+
+ /**
+ * Messages for error handlers.
+ */
+ public static final String MSG_CONTROLLER_NULL = "RestSB controller is NULL";
+ public static final String MSG_DEVICE_NULL = "Device cannot be NULL";
+ public static final String MSG_DEVICE_ID_NULL = "Device ID cannot be NULL";
+ public static final String MSG_HANDLER_NULL = "Handler cannot be NULL";
+ public static final String MSG_MASTERSHIP_NULL = "Mastership service is NULL";
+ public static final String MSG_RESPONSE_NULL = "Server's response is NULL";
+
+ public static final String MSG_CPU_CACHE_CAPACITY_NEGATIVE =
+ "CPU cache capacity (in kilo bytes) must be a positive integer";
+ public static final String MSG_CPU_CACHE_CAPACITY_CORE_NEGATIVE = "Per core CPU cache capacity must be positive";
+ public static final String MSG_CPU_CACHE_CAPACITY_LLC_NEGATIVE = "LLC capacity must be positive";
+ public static final String MSG_CPU_CACHE_CAPACITY_TOTAL_NEGATIVE = "Total CPU cache capacity must be positive";
+ public static final String MSG_CPU_CACHE_HIERARCHY_NULL = "CPU cache hierarchy cannot be NULL";
+ public static final String MSG_CPU_CACHE_ID_NULL = "CPU cache ID cannot be NULL";
+ public static final String MSG_CPU_CACHE_INSERTION_FAILED = "Failed to insert basic CPU cache into the hierarchy";
+ public static final String MSG_CPU_CACHE_LEVELS_EXCEEDED =
+ "Exceeded the typical number of levels of a CPU cache hierarchy";
+ public static final String MSG_CPU_CACHE_LEVEL_NULL = "CPU cache level cannot be NULL";
+ public static final String MSG_CPU_CACHE_LEVELS_NEGATIVE =
+ "Number of CPU cache levels must be positive";
+ public static final String MSG_CPU_CACHE_LINE_NEGATIVE =
+ "CPU cache line length (in bytes) must be a positive integer";
+ public static final String MSG_CPU_CACHE_POLICY_NULL = "PU cache policy cannot be NULL";
+ public static final String MSG_CPU_CACHE_SETS_NEGATIVE = "CPU cache sets must be a positive integer";
+ public static final String MSG_CPU_CACHE_TYPE_NULL = "CPU cache type cannot be NULL";
+ public static final String MSG_CPU_CACHE_WAYS_NEGATIVE = "CPU cache ways must be a positive integer";
+
+ public static final String MSG_CPU_CORE_ID_NULL = "CPU core ID cannot be NULL";
+ public static final String MSG_CPU_CORE_NEGATIVE = "CPU core ID must be in [0, " +
+ String.valueOf(CpuCoreId.MAX_CPU_CORE_NB - 1) + "]";
+ public static final String MSG_CPU_CORES_NEGATIVE = "Number of CPU cores must be positive";
+ public static final String MSG_CPU_LIST_NULL = "Device's set of CPUs cannot be NULL";
+ public static final String MSG_CPU_LOAD_NEGATIVE = "CPU load must be in [" + CpuStatistics.MIN_CPU_LOAD +
+ ", " + CpuStatistics.MAX_CPU_LOAD + "]";
+ public static final String MSG_CPU_FREQUENCY_NEGATIVE = "CPU core frequency must be positive" +
+ " and less or equal than " + CpuDevice.MAX_FREQUENCY_MHZ + " MHz";
+ public static final String MSG_CPU_SOCKET_NEGATIVE = "CPU socket ID must be in [0, " +
+ String.valueOf(CpuCoreId.MAX_CPU_SOCKET_NB - 1) + "]";
+ public static final String MSG_CPU_SOCKETS_NEGATIVE = "Number of CPU sockets must be positive";
+ public static final String MSG_CPU_VENDOR_NULL = "Unsupported CPU vendor" +
+ " Choose one in: " + BasicServerDriver.enumTypesToString(CpuVendor.class);
+
+ public static final String MSG_CONVERSION_TO_BITS = "Invalid conversion to bits";
+ public static final String MSG_CONVERSION_TO_BYTES = "Invalid conversion to bytes";
+
+ public static final String MSG_MEM_CAPACITY_NEGATIVE = "Total memory capacity must be positive";
+ public static final String MSG_MEM_HIERARCHY_EMPTY = "Memory hierarchy cannot be empty";
+ public static final String MSG_MEM_HIERARCHY_NULL = "Memory hierarchy cannot be NULL";
+ public static final String MSG_MEM_MANUFACTURER_NULL = "Memory manufacturer cannot be NULL";
+ public static final String MSG_MEM_MODULE_NULL = "Memory module cannot be NULL";
+ public static final String MSG_MEM_SERIAL_NB_NULL = "Memory serial number cannot be NULL";
+ public static final String MSG_MEM_SIZE_NEGATIVE = "Memory size must be positive";
+ public static final String MSG_MEM_SPEED_CONF_NEGATIVE = "Configured memory speed must be positive" +
+ " and less or equal than total speed";
+ public static final String MSG_MEM_SPEED_NEGATIVE = "Memory speed must be positive and less or equal than " +
+ MemoryModuleDevice.MAX_SPEED_MTS + " MT/s";
+ public static final String MSG_MEM_TYPE_NULL = "Memory type cannot be NULL";
+ public static final String MSG_MEM_WIDTH_DATA_NEGATIVE = "Memory data width must be positive";
+ public static final String MSG_MEM_WIDTH_TOTAL_NEGATIVE = "Memory total width must be positive";
+
+ public static final String MSG_NIC_FLOW_FILTER_MAC_NULL = "MAC address of NIC Rx filter cannot be NULL";
+ public static final String MSG_NIC_FLOW_FILTER_MECH_NULL = "NIC flow Rx filter mechanism cannot be NULL";
+ public static final String MSG_NIC_FLOW_FILTER_MPLS_NULL = "MPLS label of NIC Rx filter cannot be NULL";
+ public static final String MSG_NIC_FLOW_FILTER_NEGATIVE = "NIC flow Rx filter has invalid CPU core ID";
+ public static final String MSG_NIC_FLOW_FILTER_NULL = "NIC flow Rx filter cannot be NULL";
+ public static final String MSG_NIC_FLOW_FILTER_RSS_NEGATIVE = "RSS NIC Rx filter cannot be negative";
+ public static final String MSG_NIC_FLOW_FILTER_VLAN_NULL = "VLAN ID of NIC Rx filter cannot be NULL";
+ public static final String MSG_NIC_FLOW_RULE_ACTION_VAL_NULL = "NIC rule action value cannot be NULL";
+ public static final String MSG_NIC_FLOW_RULE_ACTION_TYPE_NULL = "NIC rule action type cannot be NULL";
+ public static final String MSG_NIC_FLOW_RULE_CORE_ID_NEGATIVE = "NIC rule's CPU core index must not be negative";
+ public static final String MSG_NIC_FLOW_RULE_IFACE_NEGATIVE = "NIC rule's interface number must be positive";
+ public static final String MSG_NIC_FLOW_RULE_IFACE_NULL = "NIC rule's interface name cannot be NULL";
+ public static final String MSG_NIC_FLOW_RULE_NULL = "NIC flow Rx filter rule cannot be NULL";
+ public static final String MSG_NIC_FLOW_RULE_SCOPE_NULL = "NIC rule's scope is NULL or empty";
+ public static final String MSG_NIC_FLOW_RULE_TC_ID_NULL = "NIC rule's traffic class ID is NULL or empty";
+
+ public static final String MSG_NIC_LIST_NULL = "Device's set of NICs cannot be NULL";
+ public static final String MSG_NIC_NAME_NULL = "NIC name cannot be empty or NULL";
+ public static final String MSG_NIC_MAC_NULL = "NIC MAC address cannot be NULL";
+ public static final String MSG_NIC_PORT_NUMBER_NEGATIVE = "NIC port number cannot be negative";
+ public static final String MSG_NIC_PORT_TYPE_NULL = "NIC port type cannot be NULL";
+ public static final String MSG_NIC_RX_FILTER_NULL = "Unsupported NIC Rx filter" +
+ " Choose one in: " + BasicServerDriver.enumTypesToString(RxFilter.class);
+ public static final String MSG_NIC_RX_FILTERS_NULL = "NIC Rx filters' list is NULL";
+ public static final String MSG_NIC_SPEED_NEGATIVE = "NIC speed must be positive and less or equal than " +
+ NicDevice.MAX_SPEED + " Mbps";
+ public static final String MSG_NIC_TABLE_SIZE_NEGATIVE = "Invalid NIC table size";
+ public static final String MSG_NIC_TABLE_INDEX_NEGATIVE = "Invalid NIC table index";
+ public static final String MSG_NIC_TABLE_COUNTER_NEGATIVE = "Invalid NIC table counter";
+
+ public static final String MSG_STATS_CPU_NULL = "CPU statistics are NULL";
+ public static final String MSG_STATS_CPU_CACHE_NULL = "CPU cache statistics are NULL";
+ public static final String MSG_STATS_MEMORY_FREE_NEGATIVE = "Free memory must be positive";
+ public static final String MSG_STATS_MEMORY_NULL = "Memory statistics are NULL";
+ public static final String MSG_STATS_MEMORY_TOTAL_NEGATIVE = "Total memory must be positive";
+ public static final String MSG_STATS_MEMORY_USED_NEGATIVE = "Used memory must be positive";
+ public static final String MSG_STATS_NIC_NULL = "NIC statistics are NULL";
+ public static final String MSG_STATS_TIMING_NULL = "Timing statistics are NULL";
+ public static final String MSG_STATS_TIMING_AUTO_SCALE_NEGATIVE = "Auto-scale time must be positive";
+ public static final String MSG_STATS_TIMING_DEPLOY_INCONSISTENT = "Deploy time must be equal to the" +
+ " summary of parsing and launching times";
+ public static final String MSG_STATS_TIMING_LAUNCH_NEGATIVE = "Launching time must be positive";
+ public static final String MSG_STATS_TIMING_PARSE_NEGATIVE = "Parsing time must be positive";
+ public static final String MSG_STATS_UNIT_NULL = "Statistics unit is NULL";
+
+ public static final String MSG_UI_DATA_CPU_NULL = "No CPU data to visualize";
+ public static final String MSG_UI_DATA_LATENCY_NULL = "No latency data to visualize";
+ public static final String MSG_UI_DATA_MEMORY_NULL = "No memory data to visualize";
+ public static final String MSG_UI_DATA_THROUGHPUT_NULL = "No throughput data to visualize";
+ public static final String MSG_UI_SUBMETRIC_NULL = "UI submetric is NULL";
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java b/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java
index 7542698..dbfe36b 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java
@@ -16,12 +16,6 @@
package org.onosproject.drivers.server;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Sets;
-
import org.onosproject.drivers.server.devices.nic.NicFlowRule;
import org.onosproject.drivers.server.devices.nic.NicRxFilter.RxFilter;
import org.onosproject.net.DeviceId;
@@ -35,6 +29,13 @@
import org.slf4j.Logger;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -47,10 +48,20 @@
import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.ProcessingException;
-import com.google.common.base.Strings;
-
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.PARAM_ID;
+import static org.onosproject.drivers.server.Constants.PARAM_CPUS;
+import static org.onosproject.drivers.server.Constants.PARAM_NICS;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_RX_FILTER;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_RX_FILTER_FD;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_RX_METHOD;
+import static org.onosproject.drivers.server.Constants.PARAM_RULES;
+import static org.onosproject.drivers.server.Constants.PARAM_RULE_CONTENT;
+import static org.onosproject.drivers.server.Constants.SLASH;
+import static org.onosproject.drivers.server.Constants.URL_RULE_MANAGEMENT;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -58,35 +69,26 @@
* converting ONOS FlowRule objetcs into
* network interface card (NIC) rules and vice versa.
*/
-public class FlowRuleProgrammableServerImpl extends BasicServerDriver
+public class FlowRuleProgrammableServerImpl
+ extends BasicServerDriver
implements FlowRuleProgrammable {
private final Logger log = getLogger(getClass());
/**
- * Resource endpoints of the server agent (REST server-side).
- */
- private static final String RULE_MANAGEMENT_URL = BASE_URL + SLASH + "rules";
-
- /**
- * Parameters to be exchanged with the server's agent.
- */
- private static final String PARAM_RULES = "rules";
- private static final String PARAM_CPU_ID = "cpuId";
- private static final String PARAM_CPU_RULES = "cpuRules";
- private static final String PARAM_RULE_ID = "ruleId";
- private static final String PARAM_RULE_CONTENT = "ruleContent";
- private static final String PARAM_RX_FILTER_FD = "flow";
-
- /**
* Driver's property to specify how many rules the controller can remove at once.
*/
private static final String RULE_DELETE_BATCH_SIZE_PROPERTY = "ruleDeleteBatchSize";
+ public FlowRuleProgrammableServerImpl() {
+ super();
+ log.debug("Started");
+ }
+
@Override
public Collection<FlowEntry> getFlowEntries() {
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// Expected FlowEntries installed through ONOS
FlowRuleService flowService = getHandler().get(FlowRuleService.class);
@@ -95,7 +97,7 @@
// Hit the path that provides the server's flow rules
InputStream response = null;
try {
- response = getController().get(deviceId, RULE_MANAGEMENT_URL, JSON);
+ response = getController().get(deviceId, URL_RULE_MANAGEMENT, JSON);
} catch (ProcessingException pEx) {
log.error("Failed to get NIC flow entries from device: {}", deviceId);
return Collections.EMPTY_LIST;
@@ -127,7 +129,7 @@
for (JsonNode scNode : scsNode) {
String scId = get(scNode, PARAM_ID);
String rxFilter = get(
- scNode.path(NIC_PARAM_RX_FILTER), NIC_PARAM_RX_METHOD);
+ scNode.path(PARAM_NIC_RX_FILTER), PARAM_NIC_RX_METHOD);
// Only Flow-based RxFilter is permitted
if (RxFilter.getByName(rxFilter) != RxFilter.FLOW) {
@@ -142,12 +144,12 @@
// Each NIC can dispatch to multiple CPU cores
for (JsonNode cpuNode : cpusNode) {
- String cpuId = get(cpuNode, PARAM_CPU_ID);
- JsonNode rulesNode = cpuNode.path(PARAM_CPU_RULES);
+ String cpuId = get(cpuNode, PARAM_ID);
+ JsonNode rulesNode = cpuNode.path(PARAM_RULES);
// Multiple rules might correspond to each CPU core
for (JsonNode ruleNode : rulesNode) {
- long ruleId = ruleNode.path(PARAM_RULE_ID).asLong();
+ long ruleId = ruleNode.path(PARAM_ID).asLong();
String ruleContent = get(ruleNode, PARAM_RULE_CONTENT);
// Search for this rule ID in ONOS's store
@@ -159,7 +161,7 @@
// Rule trully present in the data plane => Add
} else {
actualFlowEntries.add(new DefaultFlowEntry(
- r, FlowEntry.FlowEntryState.ADDED, 0, 0, 0));
+ r, FlowEntry.FlowEntryState.ADDED, 0, 0, 0));
}
}
}
@@ -171,8 +173,8 @@
@Override
public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// Set of truly-installed rules to be reported
Set<FlowRule> installedRules = Sets.<FlowRule>newConcurrentHashSet();
@@ -195,8 +197,8 @@
@Override
public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
int ruleDeleteBatchSize = getRuleDeleteBatchSizeProperty(deviceId);
@@ -258,7 +260,7 @@
try {
nicRule = (NicFlowRule) rule;
} catch (ClassCastException cEx) {
- log.warn("Skipping rule not crafted for NIC: {}", rule);
+ log.warn("Skipping flow rule not crafted for NIC: {}", rule);
}
if (nicRule != null) {
@@ -319,12 +321,12 @@
ObjectNode scsObjNode = mapper.createObjectNode();
// Add the service chain's traffic class ID that requested these rules
- scsObjNode.put(BasicServerDriver.PARAM_ID, trafficClassId);
+ scsObjNode.put(PARAM_ID, trafficClassId);
// Create the object node to host the Rx filter method
ObjectNode methodObjNode = mapper.createObjectNode();
- methodObjNode.put(BasicServerDriver.NIC_PARAM_RX_METHOD, PARAM_RX_FILTER_FD);
- scsObjNode.put(BasicServerDriver.NIC_PARAM_RX_FILTER, methodObjNode);
+ methodObjNode.put(PARAM_NIC_RX_METHOD, PARAM_NIC_RX_FILTER_FD);
+ scsObjNode.put(PARAM_NIC_RX_FILTER, methodObjNode);
// Map each core to an array of rule IDs and rules
Map<Long, ArrayNode> cpuObjSet =
@@ -336,7 +338,7 @@
while (it.hasNext()) {
NicFlowRule nicRule = (NicFlowRule) it.next();
if (nicRule.isFullWildcard() && (rulesToInstall > 1)) {
- log.warn("Skipping wildcard rule: {}", nicRule);
+ log.warn("Skipping wildcard flow rule: {}", nicRule);
it.remove();
continue;
}
@@ -347,7 +349,7 @@
if (nic == null) {
nic = findNicInterfaceWithPort(deviceId, nicRule.interfaceNumber());
checkArgument(!Strings.isNullOrEmpty(nic),
- "Attempted to install rules in an invalid NIC");
+ "Attempted to install flow rules in an invalid NIC");
}
// Create a JSON array for this CPU core
@@ -383,7 +385,7 @@
ObjectNode cpuObjNode = mapper.createObjectNode();
cpuObjNode.put("cpuId", coreIndex);
- cpuObjNode.putArray(PARAM_CPU_RULES).addAll(ruleArrayNode);
+ cpuObjNode.putArray(PARAM_RULES).addAll(ruleArrayNode);
cpusArrayNode.add(cpuObjNode);
}
@@ -396,7 +398,7 @@
// Post the NIC rules to the server
int response = getController().post(
- deviceId, RULE_MANAGEMENT_URL,
+ deviceId, URL_RULE_MANAGEMENT,
new ByteArrayInputStream(sendObjNode.toString().getBytes()), JSON);
// Upon an error, return an empty set of rules
@@ -427,7 +429,7 @@
// Try to remove the rules, although server might be unreachable
try {
response = getController().delete(deviceId,
- RULE_MANAGEMENT_URL + SLASH + ruleIds, null, JSON);
+ URL_RULE_MANAGEMENT + SLASH + ruleIds, null, JSON);
} catch (Exception ex) {
log.error("Failed to remove NIC flow rule batch with {} rules from device {}", ruleCount, deviceId);
return false;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerBasicSystemOperations.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerBasicSystemOperations.java
new file mode 100644
index 0000000..eb4536f
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerBasicSystemOperations.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.BasicSystemOperations;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.protocol.rest.RestSBDevice;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import javax.ws.rs.ProcessingException;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.CompletableFuture.completedFuture;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.MSG_HANDLER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.PARAM_TIME;
+import static org.onosproject.drivers.server.Constants.URL_SRV_TIME_DISCOVERY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of basic system operations' behaviour for server devices.
+ */
+public class ServerBasicSystemOperations
+ extends BasicServerDriver
+ implements BasicSystemOperations {
+
+ private final Logger log = getLogger(getClass());
+
+ public ServerBasicSystemOperations() {
+ super();
+ log.debug("Started");
+ }
+
+ @Override
+ public DriverHandler handler() {
+ return super.getHandler();
+ }
+
+ @Override
+ public void setHandler(DriverHandler handler) {
+ checkNotNull(handler, MSG_HANDLER_NULL);
+ this.handler = handler;
+ }
+
+ @Override
+ public CompletableFuture<Boolean> reboot() {
+ throw new UnsupportedOperationException("Reboot operation not supported");
+ }
+
+ @Override
+ public CompletableFuture<Long> time() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Get the device
+ RestSBDevice device = super.getDevice(deviceId);
+ checkNotNull(device, MSG_DEVICE_NULL);
+
+ // Hit the path that provides the server's time
+ InputStream response = null;
+ try {
+ response = getController().get(deviceId, URL_SRV_TIME_DISCOVERY, JSON);
+ } catch (ProcessingException pEx) {
+ log.error("Failed to get the time of device: {}", deviceId);
+ return null;
+ }
+
+ // Load the JSON into object
+ ObjectMapper mapper = new ObjectMapper();
+ Map<String, Object> jsonMap = null;
+ JsonNode jsonNode = null;
+ try {
+ jsonMap = mapper.readValue(response, Map.class);
+ jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
+ } catch (IOException ioEx) {
+ log.error("Failed to discover the device details of: {}", deviceId);
+ return null;
+ }
+
+ if (jsonNode == null) {
+ log.error("Failed to discover the device details of: {}", deviceId);
+ return null;
+ }
+
+ long time = jsonNode.path(PARAM_TIME).asLong();
+ checkArgument(time > 0, "Invalid time format: {}", time);
+
+ return completedFuture(new Long(time));
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerControllerConfig.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerControllerConfig.java
index 3ffbc91..184b8b7 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerControllerConfig.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerControllerConfig.java
@@ -39,31 +39,29 @@
import javax.ws.rs.ProcessingException;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MASTERSHIP_NULL;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL_IP;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL_PORT;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL_TYPE;
+import static org.onosproject.drivers.server.Constants.SLASH;
+import static org.onosproject.drivers.server.Constants.URL_CONTROLLERS_GET;
+import static org.onosproject.drivers.server.Constants.URL_CONTROLLERS_DEL;
+import static org.onosproject.drivers.server.Constants.URL_CONTROLLERS_SET;
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Sets, gets, and removes controller configuration
- * from a commodity server (i.e., a REST device).
+ * Implementation of controller configuration behaviour for server devices.
*/
-public class ServerControllerConfig extends BasicServerDriver
+public class ServerControllerConfig
+ extends BasicServerDriver
implements ControllerConfig {
private final Logger log = getLogger(getClass());
/**
- * Resource endpoints of the server agent (REST server-side).
- */
- private static final String CONTROLLERS_CONF_URL = BASE_URL + SLASH + "controllers";
-
- /**
- * Parameters to be exchanged with the server's agent.
- */
- private static final String PARAM_CTRL = "controllers";
- private static final String PARAM_CTRL_IP = "ip";
- private static final String PARAM_CTRL_PORT = "port";
- private static final String PARAM_CTRL_TYPE = "type";
-
- /**
* Constructs controller configuration for server.
*/
public ServerControllerConfig() {
@@ -75,11 +73,11 @@
public List<ControllerInfo> getControllers() {
List<ControllerInfo> controllers = Lists.newArrayList();
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
MastershipService mastershipService = getHandler().get(MastershipService.class);
- checkNotNull(deviceId, MASTERSHIP_NULL);
+ checkNotNull(deviceId, MSG_MASTERSHIP_NULL);
if (!mastershipService.isLocalMaster(deviceId)) {
log.warn(
@@ -92,7 +90,7 @@
// Hit the path that provides the server's controllers
InputStream response = null;
try {
- response = getController().get(deviceId, CONTROLLERS_CONF_URL, JSON);
+ response = getController().get(deviceId, URL_CONTROLLERS_GET, JSON);
} catch (ProcessingException pEx) {
log.error("Failed to get controllers of device: {}", deviceId);
return controllers;
@@ -117,9 +115,9 @@
return controllers;
}
+ // Fetch controllers' array
JsonNode ctrlNode = objNode.path(PARAM_CTRL);
- // Fetch controller objects
for (JsonNode cn : ctrlNode) {
ObjectNode ctrlObjNode = (ObjectNode) cn;
@@ -156,11 +154,11 @@
@Override
public void setControllers(List<ControllerInfo> controllers) {
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
MastershipService mastershipService = getHandler().get(MastershipService.class);
- checkNotNull(deviceId, MASTERSHIP_NULL);
+ checkNotNull(deviceId, MSG_MASTERSHIP_NULL);
if (!mastershipService.isLocalMaster(deviceId)) {
log.warn(
@@ -189,7 +187,7 @@
// Post the controllers to the device
int response = getController().post(
- deviceId, CONTROLLERS_CONF_URL,
+ deviceId, URL_CONTROLLERS_SET,
new ByteArrayInputStream(sendObjNode.toString().getBytes()), JSON);
if (!checkStatusCode(response)) {
@@ -201,11 +199,11 @@
@Override
public void removeControllers(List<ControllerInfo> controllers) {
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
MastershipService mastershipService = getHandler().get(MastershipService.class);
- checkNotNull(deviceId, MASTERSHIP_NULL);
+ checkNotNull(deviceId, MSG_MASTERSHIP_NULL);
if (!mastershipService.isLocalMaster(deviceId)) {
log.warn(
@@ -219,7 +217,7 @@
log.info("Remove controller with {}:{}:{}",
ctrl.type(), ctrl.ip().toString(), ctrl.port());
- String remCtrlUrl = CONTROLLERS_CONF_URL + SLASH + ctrl.ip().toString();
+ String remCtrlUrl = URL_CONTROLLERS_DEL + SLASH + ctrl.ip().toString();
// Remove this controller
int response = getController().delete(deviceId, remCtrlUrl, null, JSON);
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
index ac6c28d..346c8ca 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
@@ -18,22 +18,27 @@
import org.onosproject.drivers.server.behavior.CpuStatisticsDiscovery;
import org.onosproject.drivers.server.behavior.MonitoringStatisticsDiscovery;
-import org.onosproject.drivers.server.devices.CpuDevice;
-import org.onosproject.drivers.server.devices.CpuVendor;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheHierarchyDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryHierarchyDevice;
import org.onosproject.drivers.server.devices.nic.NicDevice;
-import org.onosproject.drivers.server.devices.nic.NicRxFilter;
-import org.onosproject.drivers.server.devices.nic.NicRxFilter.RxFilter;
import org.onosproject.drivers.server.devices.ServerDeviceDescription;
import org.onosproject.drivers.server.devices.RestServerSBDevice;
import org.onosproject.drivers.server.stats.CpuStatistics;
+import org.onosproject.drivers.server.stats.MemoryStatistics;
import org.onosproject.drivers.server.stats.MonitoringStatistics;
import org.onosproject.drivers.server.stats.TimingStatistics;
+import org.onosproject.drivers.server.impl.devices.DefaultBasicCpuCacheDevice;
+import org.onosproject.drivers.server.impl.devices.DefaultCpuCacheHierarchyDevice;
import org.onosproject.drivers.server.impl.devices.DefaultCpuDevice;
+import org.onosproject.drivers.server.impl.devices.DefaultMemoryHierarchyDevice;
+import org.onosproject.drivers.server.impl.devices.DefaultMemoryModuleDevice;
import org.onosproject.drivers.server.impl.devices.DefaultNicDevice;
import org.onosproject.drivers.server.impl.devices.DefaultRestServerSBDevice;
import org.onosproject.drivers.server.impl.devices.DefaultServerDeviceDescription;
import org.onosproject.drivers.server.impl.stats.DefaultCpuStatistics;
+import org.onosproject.drivers.server.impl.stats.DefaultMemoryStatistics;
import org.onosproject.drivers.server.impl.stats.DefaultMonitoringStatistics;
import org.onosproject.drivers.server.impl.stats.DefaultTimingStatistics;
@@ -43,6 +48,10 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.behaviour.DevicesDiscovery;
+import org.onosproject.net.behaviour.DeviceCpuStats;
+import org.onosproject.net.behaviour.DeviceMemoryStats;
+import org.onosproject.net.behaviour.DeviceSystemStatisticsQuery;
+import org.onosproject.net.behaviour.DeviceSystemStats;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
import org.onosproject.net.device.DefaultPortStatistics;
@@ -50,10 +59,8 @@
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.device.PortStatisticsDiscovery;
-import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.protocol.rest.RestSBDevice;
-import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;
import org.slf4j.Logger;
@@ -64,6 +71,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableList;
import java.io.InputStream;
@@ -74,113 +82,109 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import javax.ws.rs.ProcessingException;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_NAME_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_PORT_NUMBER_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_TIMING_DEPLOY_INCONSISTENT;
+import static org.onosproject.drivers.server.Constants.PARAM_ID;
+import static org.onosproject.drivers.server.Constants.PARAM_CAPACITY;
+import static org.onosproject.drivers.server.Constants.PARAM_CHASSIS_ID;
+import static org.onosproject.drivers.server.Constants.PARAM_CPUS;
+import static org.onosproject.drivers.server.Constants.PARAM_NICS;
+import static org.onosproject.drivers.server.Constants.PARAM_NAME;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_HIERARCHY;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_MODULES;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_STATS_FREE;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_STATS_TOTAL;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_STATS_USED;
+import static org.onosproject.drivers.server.Constants.PARAM_MANUFACTURER;
+import static org.onosproject.drivers.server.Constants.PARAM_HW_VENDOR;
+import static org.onosproject.drivers.server.Constants.PARAM_SW_VENDOR;
+import static org.onosproject.drivers.server.Constants.PARAM_SERIAL;
+import static org.onosproject.drivers.server.Constants.PARAM_TIMING_STATS;
+import static org.onosproject.drivers.server.Constants.PARAM_TIMING_STATS_AUTOSCALE;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_LEVEL;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_LEVELS;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_LINE_LEN;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_POLICY;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_SETS;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_SHARED;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_TYPE;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_WAYS;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHES;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CACHE_HIERARCHY;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_CORES;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_FREQUENCY;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_ID_LOG;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_ID_PHY;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_LOAD;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_LATENCY;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_QUEUE;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_SOCKET;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_SOCKETS;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_STATUS;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_THROUGHPUT;
+import static org.onosproject.drivers.server.Constants.PARAM_CPU_VENDOR;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_WIDTH_DATA;
+import static org.onosproject.drivers.server.Constants.PARAM_MEMORY_WIDTH_TOTAL;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_HW_ADDR;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_PORT_TYPE;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_RX_FILTER;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_RX_COUNT;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_RX_BYTES;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_RX_DROPS;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_RX_ERRORS;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_TX_COUNT;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_TX_BYTES;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_TX_DROPS;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_STATS_TX_ERRORS;
+import static org.onosproject.drivers.server.Constants.PARAM_MON_AVERAGE;
+import static org.onosproject.drivers.server.Constants.PARAM_MON_BUSY_CPUS;
+import static org.onosproject.drivers.server.Constants.PARAM_MON_FREE_CPUS;
+import static org.onosproject.drivers.server.Constants.PARAM_MON_MAX;
+import static org.onosproject.drivers.server.Constants.PARAM_MON_MIN;
+import static org.onosproject.drivers.server.Constants.PARAM_MON_UNIT;
+import static org.onosproject.drivers.server.Constants.PARAM_SPEED;
+import static org.onosproject.drivers.server.Constants.PARAM_SPEED_CONF;
+import static org.onosproject.drivers.server.Constants.PARAM_STATUS;
+import static org.onosproject.drivers.server.Constants.PARAM_TIMING_PARSE;
+import static org.onosproject.drivers.server.Constants.PARAM_TIMING_LAUNCH;
+import static org.onosproject.drivers.server.Constants.PARAM_TIMING_DEPLOY;
+import static org.onosproject.drivers.server.Constants.PARAM_TIMING_AUTOSCALE;
+import static org.onosproject.drivers.server.Constants.PARAM_TYPE;
+import static org.onosproject.drivers.server.Constants.SLASH;
+import static org.onosproject.drivers.server.Constants.URL_SRV_GLOBAL_STATS;
+import static org.onosproject.drivers.server.Constants.URL_SRV_RESOURCE_DISCOVERY;
+import static org.onosproject.drivers.server.Constants.URL_SERVICE_CHAINS_STATS;
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Discovers the device details of
- * REST-based commodity server devices.
+ * Discovers the device details of server devices.
*/
-public class ServerDevicesDiscovery extends BasicServerDriver
+public class ServerDevicesDiscovery
+ extends BasicServerDriver
implements DevicesDiscovery, DeviceDescriptionDiscovery,
PortStatisticsDiscovery, CpuStatisticsDiscovery,
- MonitoringStatisticsDiscovery {
+ MonitoringStatisticsDiscovery, DeviceSystemStatisticsQuery {
private final Logger log = getLogger(getClass());
/**
- * Resource endpoints of the server agent (REST server-side).
- */
- private static final String RESOURCE_DISCOVERY_URL = BASE_URL + SLASH + "resources";
- private static final String GLOBAL_STATS_URL = BASE_URL + SLASH + "stats";
- private static final String SERVICE_CHAINS_STATS_URL = BASE_URL + SLASH + "chains_stats"; // + /ID
-
- /**
- * Parameters to be exchanged with the server's agent.
- */
- private static final String PARAM_MANUFACTURER = "manufacturer";
- private static final String PARAM_HW_VENDOR = "hwVersion";
- private static final String PARAM_SW_VENDOR = "swVersion";
- private static final String PARAM_SERIAL = "serial";
- private static final String PARAM_TIMING_STATS = "timingStats";
- private static final String PARAM_TIMING_AUTOSCALE = "autoScaleTimingStats";
-
- private static final String NIC_PARAM_NAME = "name";
- private static final String NIC_PARAM_PORT_INDEX = "index";
- private static final String NIC_PARAM_PORT_TYPE = "portType";
- private static final String NIC_PARAM_PORT_TYPE_FIBER = "fiber";
- private static final String NIC_PARAM_PORT_TYPE_COPPER = "copper";
- private static final String NIC_PARAM_SPEED = "speed";
- private static final String NIC_PARAM_STATUS = "status";
- private static final String NIC_PARAM_HW_ADDR = "hwAddr";
-
- /**
- * NIC statistics.
- */
- private static final String NIC_STATS_TX_COUNT = "txCount";
- private static final String NIC_STATS_TX_BYTES = "txBytes";
- private static final String NIC_STATS_TX_DROPS = "txDropped";
- private static final String NIC_STATS_TX_ERRORS = "txErrors";
- private static final String NIC_STATS_RX_COUNT = "rxCount";
- private static final String NIC_STATS_RX_BYTES = "rxBytes";
- private static final String NIC_STATS_RX_DROPS = "rxDropped";
- private static final String NIC_STATS_RX_ERRORS = "rxErrors";
-
- /**
- * CPU statistics.
- */
- private static final String CPU_PARAM_ID = "id";
- private static final String CPU_PARAM_VENDOR = "vendor";
- private static final String CPU_PARAM_FREQUENCY = "frequency";
- private static final String CPU_PARAM_LOAD = "load";
- private static final String CPU_PARAM_QUEUE = "queue";
- private static final String CPU_PARAM_STATUS = "busy";
- private static final String CPU_PARAM_THROUGHPUT = "throughput";
- private static final String CPU_PARAM_LATENCY = "latency";
- private static final String MON_PARAM_UNIT = "unit";
- private static final String MON_PARAM_BUSY_CPUS = "busyCpus";
- private static final String MON_PARAM_FREE_CPUS = "freeCpus";
- private static final String MON_PARAM_MIN = "min";
- private static final String MON_PARAM_AVERAGE = "average";
- private static final String MON_PARAM_MAX = "max";
-
- /**
- * Timing statistics.
- */
- private static final String TIMING_PARAM_PARSE = "parseTime";
- private static final String TIMING_PARAM_LAUNCH = "launchTime";
- private static final String TIMING_PARAM_DEPLOY = "deployTime";
- private static final String TIMING_PARAM_AUTOSCALE = "autoScaleTime";
-
- /**
* Auxiliary constants.
*/
- private static final short DISCOVERY_RETRIES = 3;
- private static final String CPU_VENDOR_NULL = "Unsupported CPU vendor" +
- " Choose one in: " + BasicServerDriver.enumTypesToString(CpuVendor.class);
- private static final String NIC_RX_FILTER_NULL = "Unsupported NIC Rx filter" +
- " Choose one in: " + BasicServerDriver.enumTypesToString(RxFilter.class);
-
- /**
- * Port types that usually appear in commodity servers.
- */
- public static final Map<String, Port.Type> PORT_TYPE_MAP =
- Collections.unmodifiableMap(
- new HashMap<String, Port.Type>() {
- {
- put(NIC_PARAM_PORT_TYPE_FIBER, Port.Type.FIBER);
- put(NIC_PARAM_PORT_TYPE_COPPER, Port.Type.COPPER);
- }
- }
- );
+ private static final short DISCOVERY_RETRIES = 3;
/**
* Constructs server device discovery.
@@ -190,13 +194,16 @@
log.debug("Started");
}
+ /**
+ * Implements DevicesDiscovery behaviour.
+ */
@Override
public Set<DeviceId> deviceIds() {
// Set of devices to return
Set<DeviceId> devices = new HashSet<DeviceId>();
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
devices.add(deviceId);
return devices;
@@ -207,6 +214,9 @@
return getDeviceDetails(deviceId);
}
+ /**
+ * Implements DeviceDescriptionDiscovery behaviour.
+ */
@Override
public DeviceDescription discoverDeviceDetails() {
return getDeviceDetails(null);
@@ -221,18 +231,18 @@
private DeviceDescription getDeviceDetails(DeviceId deviceId) {
// Retrieve the device ID, if null given
if (deviceId == null) {
- deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
}
// Get the device
- RestSBDevice device = getController().getDevice(deviceId);
- checkNotNull(device, DEVICE_NULL);
+ RestSBDevice device = getDevice(deviceId);
+ checkNotNull(device, MSG_DEVICE_NULL);
// Hit the path that provides the server's resources
InputStream response = null;
try {
- response = getController().get(deviceId, RESOURCE_DISCOVERY_URL, JSON);
+ response = getController().get(deviceId, URL_SRV_RESOURCE_DISCOVERY, JSON);
} catch (ProcessingException pEx) {
log.error("Failed to discover the device details of: {}", deviceId);
return null;
@@ -258,62 +268,237 @@
}
// Get all the attributes
- String id = get(jsonNode, BasicServerDriver.PARAM_ID);
- String vendor = get(jsonNode, PARAM_MANUFACTURER);
- String hw = get(jsonNode, PARAM_HW_VENDOR);
- String sw = get(jsonNode, PARAM_SW_VENDOR);
- String serial = get(jsonNode, PARAM_SERIAL);
+ String id = get(jsonNode, PARAM_ID);
+ String vendor = get(jsonNode, PARAM_MANUFACTURER);
+ String hw = get(jsonNode, PARAM_HW_VENDOR);
+ String sw = get(jsonNode, PARAM_SW_VENDOR);
+ String serial = get(jsonNode, PARAM_SERIAL);
+ long chassisId = objNode.path(PARAM_CHASSIS_ID).asLong();
- // CPUs are composite attributes
- Set<CpuDevice> cpuSet = new HashSet<CpuDevice>();
- JsonNode cpuNode = objNode.path(BasicServerDriver.PARAM_CPUS);
+ // Pass the southbound protocol as an annotation
+ DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
+ annotations.set(AnnotationKeys.PROTOCOL, "REST");
+
+ // Parse CPU devices
+ Collection<CpuDevice> cpuSet = parseCpuDevices(objNode);
+
+ // Parse memory hierarchy device
+ MemoryHierarchyDevice memHierarchyDev = parseMemoryHierarchyDevice(objNode);
+
+ // Parse CPU cache hierachy device
+ CpuCacheHierarchyDevice cacheHierarchyDev = parseCpuCacheHierarchyDevice(objNode);
+
+ // NICs are composite attributes too
+ Collection<NicDevice> nicSet = parseNicDevices(mapper, objNode, annotations);
+
+ // Construct a server device,
+ // i.e., a RestSBDevice extended with CPU, cache, memory, and NIC information
+ RestServerSBDevice dev = new DefaultRestServerSBDevice(
+ device.ip(), device.port(), device.username(),
+ device.password(), device.protocol(), device.url(),
+ device.isActive(), device.testUrl().orElse(""),
+ vendor, hw, sw, cpuSet, cacheHierarchyDev,
+ memHierarchyDev, nicSet);
+ checkNotNull(dev, MSG_DEVICE_NULL);
+
+ // Set alive
+ raiseDeviceReconnect(dev);
+
+ // Updates the controller with the complete device information
+ getController().removeDevice(deviceId);
+ getController().addDevice((RestSBDevice) dev);
+
+ // Create a description for this server device
+ ServerDeviceDescription desc = null;
+ try {
+ desc = new DefaultServerDeviceDescription(
+ new URI(id), Device.Type.SERVER, vendor,
+ hw, sw, serial, new ChassisId(chassisId),
+ cpuSet, cacheHierarchyDev, memHierarchyDev,
+ nicSet, annotations.build());
+ } catch (URISyntaxException uEx) {
+ log.error("Failed to create a server device description for: {}",
+ deviceId);
+ return null;
+ }
+
+ log.info("Device's {} details sent to the controller", deviceId);
+
+ return desc;
+ }
+
+ /**
+ * Parse the input JSON object, looking for CPU-related
+ * information. Upon success, construct and return a list
+ * of CPU devices.
+ *
+ * @param objNode input JSON node with CPU device information
+ * @return list of CPU devices
+ */
+ private Collection<CpuDevice> parseCpuDevices(ObjectNode objNode) {
+ Collection<CpuDevice> cpuSet = Sets.newHashSet();
+ JsonNode cpuNode = objNode.path(PARAM_CPUS);
// Construct CPU objects
for (JsonNode cn : cpuNode) {
ObjectNode cpuObjNode = (ObjectNode) cn;
// All the CPU attributes
- int cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
- String cpuVendorStr = get(cn, CPU_PARAM_VENDOR);
- long cpuFrequency = cpuObjNode.path(CPU_PARAM_FREQUENCY).asLong();
+ int physicalCpuId = cpuObjNode.path(PARAM_CPU_ID_PHY).asInt();
+ int logicalCpuId = cpuObjNode.path(PARAM_CPU_ID_LOG).asInt();
+ int cpuSocket = cpuObjNode.path(PARAM_CPU_SOCKET).asInt();
+ String cpuVendorStr = get(cn, PARAM_CPU_VENDOR);
+ long cpuFrequency = cpuObjNode.path(PARAM_CPU_FREQUENCY).asLong();
- // Verify that this is a valid vendor
- CpuVendor cpuVendor = CpuVendor.getByName(cpuVendorStr);
- checkNotNull(cpuVendor, CPU_VENDOR_NULL);
-
- // Construct a CPU device
- CpuDevice cpu = new DefaultCpuDevice(cpuId, cpuVendor, cpuFrequency);
-
- // Add it to the set
- cpuSet.add(cpu);
+ // Construct a CPU device and add it to the set
+ cpuSet.add(
+ DefaultCpuDevice.builder()
+ .setCoreId(logicalCpuId, physicalCpuId)
+ .setVendor(cpuVendorStr)
+ .setSocket(cpuSocket)
+ .setFrequency(cpuFrequency)
+ .build());
}
- // NICs are composite attributes too
- Set<NicDevice> nicSet = new HashSet<NicDevice>();
+ return cpuSet;
+ }
+
+ /**
+ * Parse the input JSON object, looking for CPU cache-related
+ * information. Upon success, construct and return a CPU cache
+ * hierarchy device.
+ *
+ * @param objNode input JSON node with CPU cache device information
+ * @return a CPU cache hierarchy devices
+ */
+ private CpuCacheHierarchyDevice parseCpuCacheHierarchyDevice(ObjectNode objNode) {
+ JsonNode cacheHierarchyNode = objNode.path(PARAM_CPU_CACHE_HIERARCHY);
+ ObjectNode cacheHierarchyObjNode = (ObjectNode) cacheHierarchyNode;
+ if (cacheHierarchyObjNode == null) {
+ return null;
+ }
+
+ int socketsNb = cacheHierarchyObjNode.path(PARAM_CPU_SOCKETS).asInt();
+ int coresNb = cacheHierarchyObjNode.path(PARAM_CPU_CORES).asInt();
+ int levels = cacheHierarchyObjNode.path(PARAM_CPU_CACHE_LEVELS).asInt();
+
+ JsonNode cacheNode = cacheHierarchyObjNode.path(PARAM_CPU_CACHES);
+
+ DefaultCpuCacheHierarchyDevice.Builder cacheBuilder =
+ DefaultCpuCacheHierarchyDevice.builder()
+ .setSocketsNumber(socketsNb)
+ .setCoresNumber(coresNb)
+ .setLevels(levels);
+
+ // Construct CPU cache objects
+ for (JsonNode cn : cacheNode) {
+ ObjectNode cacheObjNode = (ObjectNode) cn;
+
+ // CPU cache attributes
+ String cpuVendorStr = get(cn, PARAM_CPU_VENDOR);
+ String levelStr = get(cn, PARAM_CPU_CACHE_LEVEL);
+ String typeStr = get(cn, PARAM_CPU_CACHE_TYPE);
+ String policyStr = get(cn, PARAM_CPU_CACHE_POLICY);
+ long capacity = cacheObjNode.path(PARAM_CAPACITY).asLong();
+ int sets = cacheObjNode.path(PARAM_CPU_CACHE_SETS).asInt();
+ int ways = cacheObjNode.path(PARAM_CPU_CACHE_WAYS).asInt();
+ int lineLen = cacheObjNode.path(PARAM_CPU_CACHE_LINE_LEN).asInt();
+ boolean shared = cacheObjNode.path(PARAM_CPU_CACHE_SHARED).asInt() > 0;
+
+ // Construct a basic CPU cache device and add it to the hierarchy
+ cacheBuilder.addBasicCpuCacheDevice(
+ DefaultBasicCpuCacheDevice.builder()
+ .setVendor(cpuVendorStr)
+ .setCacheId(levelStr, typeStr)
+ .setPolicy(policyStr)
+ .setCapacity(capacity)
+ .setNumberOfSets(sets)
+ .setNumberOfWays(ways)
+ .setLineLength(lineLen)
+ .isShared(shared)
+ .build());
+ }
+
+ return cacheBuilder.build();
+ }
+
+ /**
+ * Parse the input JSON object, looking for memory-related
+ * information. Upon success, construct and return a memory
+ * hierarchy device.
+ *
+ * @param objNode input JSON node with memory device information
+ * @return a memory hierarchy device
+ */
+ private MemoryHierarchyDevice parseMemoryHierarchyDevice(ObjectNode objNode) {
+ JsonNode memHierarchyNode = objNode.path(PARAM_MEMORY_HIERARCHY);
+ ObjectNode memoryHierarchyObjNode = (ObjectNode) memHierarchyNode;
+ if (memoryHierarchyObjNode == null) {
+ return null;
+ }
+
+ JsonNode memoryNode = memoryHierarchyObjNode.path(PARAM_MEMORY_MODULES);
+
+ DefaultMemoryHierarchyDevice.Builder memoryBuilder =
+ DefaultMemoryHierarchyDevice.builder();
+
+ // Construct memory modules
+ for (JsonNode mn : memoryNode) {
+ ObjectNode memoryObjNode = (ObjectNode) mn;
+
+ String typeStr = get(mn, PARAM_TYPE);
+ String manufacturerStr = get(mn, PARAM_MANUFACTURER);
+ String serialStr = get(mn, PARAM_SERIAL);
+ int dataWidth = memoryObjNode.path(PARAM_MEMORY_WIDTH_DATA).asInt();
+ int totalWidth = memoryObjNode.path(PARAM_MEMORY_WIDTH_TOTAL).asInt();
+ long capacity = memoryObjNode.path(PARAM_CAPACITY).asLong();
+ long speed = memoryObjNode.path(PARAM_SPEED).asLong();
+ long configuredSpeed = memoryObjNode.path(PARAM_SPEED_CONF).asLong();
+
+ // Construct a memory module and add it to the hierarchy
+ memoryBuilder.addMemoryModule(
+ DefaultMemoryModuleDevice.builder()
+ .setType(typeStr)
+ .setManufacturer(manufacturerStr)
+ .setSerialNumber(serialStr)
+ .setDataWidth(dataWidth)
+ .setTotalWidth(totalWidth)
+ .setCapacity(capacity)
+ .setSpeed(speed)
+ .setConfiguredSpeed(configuredSpeed)
+ .build());
+ }
+
+ return memoryBuilder.build();
+ }
+
+ /**
+ * Parse the input JSON object, looking for NIC-related
+ * information. Upon success, construct and return a list
+ * of NIC devices.
+ *
+ * @param mapper input JSON object mapper
+ * @param objNode input JSON node with NIC device information
+ * @param annotations device annotations
+ * @return list of CPU devices
+ */
+ private Collection<NicDevice> parseNicDevices(
+ ObjectMapper mapper, ObjectNode objNode, DefaultAnnotations.Builder annotations) {
+ Collection<NicDevice> nicSet = Sets.newHashSet();
JsonNode nicNode = objNode.path(PARAM_NICS);
- DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
-
- // Pass the southbound protocol as an annotation
- annotations.set(AnnotationKeys.PROTOCOL, "REST");
-
// Construct NIC objects
for (JsonNode nn : nicNode) {
ObjectNode nicObjNode = (ObjectNode) nn;
// All the NIC attributes
- String nicName = get(nn, NIC_PARAM_NAME);
- long nicIndex = nicObjNode.path(NIC_PARAM_PORT_INDEX).asLong();
- long speed = nicObjNode.path(NIC_PARAM_SPEED).asLong();
- String portTypeStr = get(nn, NIC_PARAM_PORT_TYPE);
- Port.Type portType = PORT_TYPE_MAP.get(portTypeStr);
- if (portType == null) {
- throw new IllegalArgumentException(
- portTypeStr + " is not a valid port type for NIC " + nicName);
- }
- boolean status = nicObjNode.path(NIC_PARAM_STATUS).asInt() > 0;
- String hwAddr = get(nn, NIC_PARAM_HW_ADDR);
- JsonNode tagNode = nicObjNode.path(BasicServerDriver.NIC_PARAM_RX_FILTER);
+ String nicName = get(nn, PARAM_NAME);
+ long nicIndex = nicObjNode.path(PARAM_ID).asLong();
+ long speed = nicObjNode.path(PARAM_SPEED).asLong();
+ String portTypeStr = get(nn, PARAM_NIC_PORT_TYPE);
+ boolean status = nicObjNode.path(PARAM_STATUS).asInt() > 0;
+ String hwAddr = get(nn, PARAM_NIC_HW_ADDR);
+ JsonNode tagNode = nicObjNode.path(PARAM_NIC_RX_FILTER);
if (tagNode == null) {
throw new IllegalArgumentException(
"The Rx filters of NIC " + nicName + " are not reported");
@@ -328,76 +513,36 @@
continue;
}
- // Parse the array of strings and create an RxFilter object
- NicRxFilter rxFilterMechanism = new NicRxFilter();
- for (String s : rxFilters) {
- // Verify that this is a valid Rx filter
- RxFilter rf = RxFilter.getByName(s);
- checkNotNull(rf, NIC_RX_FILTER_NULL);
-
- rxFilterMechanism.addRxFilter(rf);
- }
-
// Store NIC name to number mapping as an annotation
annotations.set(nicName, Long.toString(nicIndex));
- // Construct a NIC device for this server
- NicDevice nic = new DefaultNicDevice(
- nicName, nicIndex, portType, speed, status, hwAddr, rxFilterMechanism);
-
- // Add it to the set
- nicSet.add(nic);
+ // Construct a NIC device and add it to the set
+ nicSet.add(
+ DefaultNicDevice.builder()
+ .setName(nicName)
+ .setPortNumber(nicIndex)
+ .setPortNumber(nicIndex)
+ .setPortType(portTypeStr)
+ .setSpeed(speed)
+ .setStatus(status)
+ .setMacAddress(hwAddr)
+ .setRxFilters(rxFilters)
+ .build());
}
- // Construct a complete server device object.
- // Lists of NICs and CPUs extend the information
- // already in RestSBDevice (parent class).
- RestServerSBDevice dev = new DefaultRestServerSBDevice(
- device.ip(), device.port(), device.username(),
- device.password(), device.protocol(), device.url(),
- device.isActive(), device.testUrl().orElse(""),
- vendor, hw, sw, AuthenticationScheme.BASIC, "",
- cpuSet, nicSet
- );
- checkNotNull(dev, DEVICE_NULL);
-
- // Set alive
- raiseDeviceReconnect(dev);
-
- // Updates the controller with the complete device information
- getController().removeDevice(deviceId);
- getController().addDevice((RestSBDevice) dev);
-
- // Create a description for this server device
- ServerDeviceDescription desc = null;
-
- try {
- desc = new DefaultServerDeviceDescription(
- new URI(id), Device.Type.SERVER, vendor,
- hw, sw, serial, new ChassisId(),
- cpuSet, nicSet, annotations.build()
- );
- } catch (URISyntaxException uEx) {
- log.error("Failed to create a server device description for: {}",
- deviceId);
- return null;
- }
-
- log.info("Device's {} details sent to the controller", deviceId);
-
- return desc;
+ return nicSet;
}
@Override
public List<PortDescription> discoverPortDetails() {
// Retrieve the device ID
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// .. and object
RestServerSBDevice device = null;
try {
- device = (RestServerSBDevice) getController().getDevice(deviceId);
+ device = (RestServerSBDevice) getDevice(deviceId);
} catch (ClassCastException ccEx) {
log.error("Failed to discover ports for device {}", deviceId);
return Collections.EMPTY_LIST;
@@ -427,7 +572,8 @@
// Create a port description and add it to the list
portDescriptions.add(
DefaultPortDescription.builder()
- .withPortNumber(PortNumber.portNumber(nic.portNumber(), nic.name()))
+ // CHECK: .withPortNumber(PortNumber.portNumber(nic.portNumber(), nic.name()))
+ .withPortNumber(PortNumber.portNumber(nic.portNumber()))
.isEnabled(nic.status())
.type(nic.portType())
.portSpeed(nic.speed())
@@ -442,11 +588,14 @@
return ImmutableList.copyOf(portDescriptions);
}
+ /**
+ * Implements PortStatisticsDiscovery behaviour.
+ */
@Override
public Collection<PortStatistics> discoverPortStatistics() {
// Retrieve the device ID
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// Get port statistics for this device
return getPortStatistics(deviceId);
@@ -476,11 +625,14 @@
return portStats;
}
+ /**
+ * Implements CpuStatisticsDiscovery behaviour.
+ */
@Override
public Collection<CpuStatistics> discoverCpuStatistics() {
// Retrieve the device ID
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// Get CPU statistics for this device
return getCpuStatistics(deviceId);
@@ -510,11 +662,14 @@
return cpuStats;
}
+ /**
+ * Implements MonitoringStatisticsDiscovery behaviour.
+ */
@Override
public MonitoringStatistics discoverGlobalMonitoringStatistics() {
// Retrieve the device ID
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// Get global monitoring statistics for this device
return getGlobalMonitoringStatistics(deviceId);
@@ -532,7 +687,7 @@
RestServerSBDevice device = null;
try {
- device = (RestServerSBDevice) getController().getDevice(deviceId);
+ device = (RestServerSBDevice) getDevice(deviceId);
} catch (ClassCastException ccEx) {
log.error("Failed to retrieve global monitoring statistics from device {}",
deviceId);
@@ -545,7 +700,7 @@
// Hit the path that provides the server's global resources
InputStream response = null;
try {
- response = getController().get(deviceId, GLOBAL_STATS_URL, JSON);
+ response = getController().get(deviceId, URL_SRV_GLOBAL_STATS, JSON);
} catch (ProcessingException pEx) {
log.error("Failed to retrieve global monitoring statistics from device {}",
deviceId);
@@ -576,28 +731,29 @@
}
// Get high-level CPU statistics
- int busyCpus = objNode.path(MON_PARAM_BUSY_CPUS).asInt();
- int freeCpus = objNode.path(MON_PARAM_FREE_CPUS).asInt();
+ int busyCpus = objNode.path(PARAM_MON_BUSY_CPUS).asInt();
+ int freeCpus = objNode.path(PARAM_MON_FREE_CPUS).asInt();
// Get a list of CPU statistics per core
Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);
+ // Get main memory statistics
+ MemoryStatistics memStats = parseMemoryStatistics(deviceId, objNode);
+
// Get a list of port statistics
Collection<PortStatistics> nicStats = parseNicStatistics(deviceId, objNode);
// Get zero timing statistics
TimingStatistics timinsgStats = getZeroTimingStatistics();
- // Ready to construct the grand object
- DefaultMonitoringStatistics.Builder statsBuilder =
- DefaultMonitoringStatistics.builder();
-
- statsBuilder.setDeviceId(deviceId)
- .setTimingStatistics(timinsgStats)
- .setCpuStatistics(cpuStats)
- .setNicStatistics(nicStats);
-
- monStats = statsBuilder.build();
+ // Construct a global monitoring statistics object out of smaller ones
+ monStats = DefaultMonitoringStatistics.builder()
+ .setDeviceId(deviceId)
+ .setTimingStatistics(timinsgStats)
+ .setCpuStatistics(cpuStats)
+ .setMemoryStatistics(memStats)
+ .setNicStatistics(nicStats)
+ .build();
// When a device reports monitoring data, it means it is alive
raiseDeviceReconnect(device);
@@ -610,8 +766,8 @@
@Override
public MonitoringStatistics discoverMonitoringStatistics(URI tcId) {
// Retrieve the device ID
- DeviceId deviceId = getHandler().data().deviceId();
- checkNotNull(deviceId, DEVICE_ID_NULL);
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
// Get resource-specific monitoring statistics for this device
return getMonitoringStatistics(deviceId, tcId);
@@ -631,7 +787,7 @@
RestServerSBDevice device = null;
try {
- device = (RestServerSBDevice) getController().getDevice(deviceId);
+ device = (RestServerSBDevice) getDevice(deviceId);
} catch (ClassCastException ccEx) {
log.error("Failed to retrieve monitoring statistics from device {}",
deviceId);
@@ -642,7 +798,7 @@
}
// Create a resource-specific URL
- String scUrl = SERVICE_CHAINS_STATS_URL + SLASH + tcId.toString();
+ String scUrl = URL_SERVICE_CHAINS_STATS + SLASH + tcId.toString();
// Hit the path that provides the server's specific resources
InputStream response = null;
@@ -692,22 +848,23 @@
// Get a list of CPU statistics per core
Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);
+ // Get main memory statistics
+ MemoryStatistics memStats = parseMemoryStatistics(deviceId, objNode);
+
// Get a list of port statistics
Collection<PortStatistics> nicStats = parseNicStatistics(deviceId, objNode);
// Get timing statistics
TimingStatistics timinsgStats = parseTimingStatistics(objNode);
- // Ready to construct the grand object
- DefaultMonitoringStatistics.Builder statsBuilder =
- DefaultMonitoringStatistics.builder();
-
- statsBuilder.setDeviceId(deviceId)
- .setTimingStatistics(timinsgStats)
- .setCpuStatistics(cpuStats)
- .setNicStatistics(nicStats);
-
- monStats = statsBuilder.build();
+ // Construct a global monitoring statistics object out of smaller ones
+ monStats = DefaultMonitoringStatistics.builder()
+ .setDeviceId(deviceId)
+ .setTimingStatistics(timinsgStats)
+ .setCpuStatistics(cpuStats)
+ .setMemoryStatistics(memStats)
+ .setNicStatistics(nicStats)
+ .build();
// When a device reports monitoring data, it means it is alive
raiseDeviceReconnect(device);
@@ -733,74 +890,106 @@
Collection<CpuStatistics> cpuStats = Lists.newArrayList();
- JsonNode cpuNode = objNode.path(BasicServerDriver.PARAM_CPUS);
+ JsonNode cpuNode = objNode.path(PARAM_CPUS);
for (JsonNode cn : cpuNode) {
ObjectNode cpuObjNode = (ObjectNode) cn;
// CPU statistics builder
- DefaultCpuStatistics.Builder cpuBuilder = DefaultCpuStatistics.builder();
+ DefaultCpuStatistics.Builder cpuStatsBuilder = DefaultCpuStatistics.builder();
// Throughput statistics are optional
- JsonNode throughputNode = cpuObjNode.get(CPU_PARAM_THROUGHPUT);
+ JsonNode throughputNode = cpuObjNode.get(PARAM_CPU_THROUGHPUT);
if (throughputNode != null) {
- String throughputUnit = get(throughputNode, MON_PARAM_UNIT);
+ String throughputUnit = get(throughputNode, PARAM_MON_UNIT);
if (!Strings.isNullOrEmpty(throughputUnit)) {
- cpuBuilder.setThroughputUnit(throughputUnit);
+ cpuStatsBuilder.setThroughputUnit(throughputUnit);
}
float averageThroughput = (float) 0;
- if (throughputNode.get(MON_PARAM_AVERAGE) != null) {
- averageThroughput = throughputNode.path(MON_PARAM_AVERAGE).floatValue();
+ if (throughputNode.get(PARAM_MON_AVERAGE) != null) {
+ averageThroughput = throughputNode.path(PARAM_MON_AVERAGE).floatValue();
}
- cpuBuilder.setAverageThroughput(averageThroughput);
+ cpuStatsBuilder.setAverageThroughput(averageThroughput);
}
// Latency statistics are optional
- JsonNode latencyNode = cpuObjNode.get(CPU_PARAM_LATENCY);
+ JsonNode latencyNode = cpuObjNode.get(PARAM_CPU_LATENCY);
if (latencyNode != null) {
- String latencyUnit = get(latencyNode, MON_PARAM_UNIT);
+ String latencyUnit = get(latencyNode, PARAM_MON_UNIT);
if (!Strings.isNullOrEmpty(latencyUnit)) {
- cpuBuilder.setLatencyUnit(latencyUnit);
+ cpuStatsBuilder.setLatencyUnit(latencyUnit);
}
float minLatency = (float) 0;
- if (latencyNode.get(MON_PARAM_MIN) != null) {
- minLatency = latencyNode.path(MON_PARAM_MIN).floatValue();
+ if (latencyNode.get(PARAM_MON_MIN) != null) {
+ minLatency = latencyNode.path(PARAM_MON_MIN).floatValue();
}
float averageLatency = (float) 0;
- if (latencyNode.get(MON_PARAM_AVERAGE) != null) {
- averageLatency = latencyNode.path(MON_PARAM_AVERAGE).floatValue();
+ if (latencyNode.get(PARAM_MON_AVERAGE) != null) {
+ averageLatency = latencyNode.path(PARAM_MON_AVERAGE).floatValue();
}
float maxLatency = (float) 0;
- if (latencyNode.get(MON_PARAM_MAX) != null) {
- maxLatency = latencyNode.path(MON_PARAM_MAX).floatValue();
+ if (latencyNode.get(PARAM_MON_MAX) != null) {
+ maxLatency = latencyNode.path(PARAM_MON_MAX).floatValue();
}
- cpuBuilder.setMinLatency(minLatency)
+ cpuStatsBuilder.setMinLatency(minLatency)
.setAverageLatency(averageLatency)
.setMaxLatency(maxLatency);
}
// CPU ID with its load and status
- int cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
- float cpuLoad = cpuObjNode.path(CPU_PARAM_LOAD).floatValue();
- int queueId = cpuObjNode.path(CPU_PARAM_QUEUE).asInt();
- int busySince = cpuObjNode.path(CPU_PARAM_STATUS).asInt();
+ int cpuId = cpuObjNode.path(PARAM_ID).asInt();
+ float cpuLoad = cpuObjNode.path(PARAM_CPU_LOAD).floatValue();
+ int queueId = cpuObjNode.path(PARAM_CPU_QUEUE).asInt();
+ int busySince = cpuObjNode.path(PARAM_CPU_STATUS).asInt();
- // This is mandatory information
- cpuBuilder.setDeviceId(deviceId)
+ // We have all the statistics for this CPU core
+ cpuStats.add(
+ cpuStatsBuilder
+ .setDeviceId(deviceId)
.setId(cpuId)
.setLoad(cpuLoad)
.setQueue(queueId)
- .setBusySince(busySince);
-
- // We have all the statistics for this CPU core
- cpuStats.add(cpuBuilder.build());
+ .setBusySince(busySince)
+ .build());
}
return cpuStats;
}
/**
+ * Parse the input JSON object, looking for memory-related
+ * statistics. Upon success, construct and return a memory
+ * statistics objects.
+ *
+ * @param deviceId the device ID that sent the JSON object
+ * @param objNode input JSON node with memory statistics information
+ * @return memory statistics object
+ */
+ private MemoryStatistics parseMemoryStatistics(DeviceId deviceId, JsonNode objNode) {
+ if ((deviceId == null) || (objNode == null)) {
+ return null;
+ }
+
+ JsonNode memoryNode = objNode.path(PARAM_MEMORY);
+ ObjectNode memoryObjNode = (ObjectNode) memoryNode;
+
+ // Fetch memory statistics
+ String unit = get(memoryNode, PARAM_MON_UNIT);
+ long used = memoryObjNode.path(PARAM_MEMORY_STATS_USED).asLong();
+ long free = memoryObjNode.path(PARAM_MEMORY_STATS_FREE).asLong();
+ long total = memoryObjNode.path(PARAM_MEMORY_STATS_TOTAL).asLong();
+
+ // Memory statistics builder
+ return DefaultMemoryStatistics.builder()
+ .setDeviceId(deviceId)
+ .setMemoryUsed(used)
+ .setMemoryFree(free)
+ .setMemoryTotal(total)
+ .build();
+ }
+
+ /**
* Parse the input JSON object, looking for NIC-related
* statistics. Upon success, construct and return a list
* of NIC statistics objects.
@@ -816,7 +1005,7 @@
RestServerSBDevice device = null;
try {
- device = (RestServerSBDevice) getController().getDevice(deviceId);
+ device = (RestServerSBDevice) getDevice(deviceId);
} catch (ClassCastException ccEx) {
return Collections.EMPTY_LIST;
}
@@ -832,25 +1021,25 @@
ObjectNode nicObjNode = (ObjectNode) nn;
// All the NIC attributes
- String nicName = get(nn, NIC_PARAM_NAME);
- checkArgument(!Strings.isNullOrEmpty(nicName), "NIC name is empty or NULL");
+ String nicName = get(nn, PARAM_NAME);
+ checkArgument(!Strings.isNullOrEmpty(nicName), MSG_NIC_NAME_NULL);
long portNumber = device.portNumberFromName(nicName);
- checkArgument(portNumber >= 0, "Unknown port ID " + portNumber + " for NIC " + nicName);
+ checkArgument(portNumber >= 0, MSG_NIC_PORT_NUMBER_NEGATIVE);
- long rxCount = nicObjNode.path(NIC_STATS_RX_COUNT).asLong();
- long rxBytes = nicObjNode.path(NIC_STATS_RX_BYTES).asLong();
- long rxDropped = nicObjNode.path(NIC_STATS_RX_DROPS).asLong();
- long rxErrors = nicObjNode.path(NIC_STATS_RX_ERRORS).asLong();
- long txCount = nicObjNode.path(NIC_STATS_TX_COUNT).asLong();
- long txBytes = nicObjNode.path(NIC_STATS_TX_BYTES).asLong();
- long txDropped = nicObjNode.path(NIC_STATS_TX_DROPS).asLong();
- long txErrors = nicObjNode.path(NIC_STATS_TX_ERRORS).asLong();
+ long rxCount = nicObjNode.path(PARAM_NIC_STATS_RX_COUNT).asLong();
+ long rxBytes = nicObjNode.path(PARAM_NIC_STATS_RX_BYTES).asLong();
+ long rxDropped = nicObjNode.path(PARAM_NIC_STATS_RX_DROPS).asLong();
+ long rxErrors = nicObjNode.path(PARAM_NIC_STATS_RX_ERRORS).asLong();
+ long txCount = nicObjNode.path(PARAM_NIC_STATS_TX_COUNT).asLong();
+ long txBytes = nicObjNode.path(PARAM_NIC_STATS_TX_BYTES).asLong();
+ long txDropped = nicObjNode.path(PARAM_NIC_STATS_TX_DROPS).asLong();
+ long txErrors = nicObjNode.path(PARAM_NIC_STATS_TX_ERRORS).asLong();
- // Incorporate these statistics into an object
- DefaultPortStatistics.Builder nicBuilder = DefaultPortStatistics.builder();
-
- nicBuilder.setDeviceId(deviceId)
+ // Construct a NIC statistics object and add it to the set
+ nicStats.add(
+ DefaultPortStatistics.builder()
+ .setDeviceId(deviceId)
.setPort(PortNumber.portNumber(portNumber))
.setPacketsReceived(rxCount)
.setPacketsSent(txCount)
@@ -859,10 +1048,8 @@
.setPacketsRxDropped(rxDropped)
.setPacketsRxErrors(rxErrors)
.setPacketsTxDropped(txDropped)
- .setPacketsTxErrors(txErrors);
-
- // We have statistics for this NIC
- nicStats.add(nicBuilder.build());
+ .setPacketsTxErrors(txErrors)
+ .build());
}
return nicStats;
@@ -888,40 +1075,42 @@
return getZeroTimingStatistics();
}
- DefaultTimingStatistics.Builder timingBuilder = DefaultTimingStatistics.builder();
+ DefaultTimingStatistics.Builder timingBuilder =
+ DefaultTimingStatistics.builder();
// Get timing statistics
JsonNode timingNode = objNode.path(PARAM_TIMING_STATS);
ObjectNode timingObjNode = (ObjectNode) timingNode;
// The unit of timing statistics
- String timingStatsUnit = get(timingNode, MON_PARAM_UNIT);
+ String timingStatsUnit = get(timingNode, PARAM_MON_UNIT);
if (!Strings.isNullOrEmpty(timingStatsUnit)) {
timingBuilder.setUnit(timingStatsUnit);
}
// Time (ns) to parse the controller's deployment instruction
long parsingTime = 0;
- if (timingObjNode.get(TIMING_PARAM_PARSE) != null) {
- parsingTime = timingObjNode.path(TIMING_PARAM_PARSE).asLong();
+ if (timingObjNode.get(PARAM_TIMING_PARSE) != null) {
+ parsingTime = timingObjNode.path(PARAM_TIMING_PARSE).asLong();
}
// Time (ns) to do the deployment
long launchingTime = 0;
- if (timingObjNode.get(TIMING_PARAM_LAUNCH) != null) {
- launchingTime = timingObjNode.path(TIMING_PARAM_LAUNCH).asLong();
+ if (timingObjNode.get(PARAM_TIMING_LAUNCH) != null) {
+ launchingTime = timingObjNode.path(PARAM_TIMING_LAUNCH).asLong();
}
// Deployment time (ns) equals to time to parse + time to launch
long deployTime = 0;
- if (timingObjNode.get(TIMING_PARAM_DEPLOY) != null) {
- deployTime = timingObjNode.path(TIMING_PARAM_DEPLOY).asLong();
+ if (timingObjNode.get(PARAM_TIMING_DEPLOY) != null) {
+ deployTime = timingObjNode.path(PARAM_TIMING_DEPLOY).asLong();
}
- checkArgument(deployTime == parsingTime + launchingTime, "Inconsistent timing statistics");
+ checkArgument(deployTime == parsingTime + launchingTime,
+ MSG_STATS_TIMING_DEPLOY_INCONSISTENT);
timingBuilder.setParsingTime(parsingTime)
.setLaunchingTime(launchingTime);
// Get autoscale timing statistics
- JsonNode autoscaleTimingNode = objNode.path(PARAM_TIMING_AUTOSCALE);
+ JsonNode autoscaleTimingNode = objNode.path(PARAM_TIMING_STATS_AUTOSCALE);
if (autoscaleTimingNode == null) {
return timingBuilder.build();
}
@@ -929,8 +1118,8 @@
ObjectNode autoScaleTimingObjNode = (ObjectNode) autoscaleTimingNode;
// Time (ns) to autoscale a server's load
long autoScaleTime = 0;
- if (autoScaleTimingObjNode.get(TIMING_PARAM_AUTOSCALE) != null) {
- autoScaleTime = autoScaleTimingObjNode.path(TIMING_PARAM_AUTOSCALE).asLong();
+ if (autoScaleTimingObjNode.get(PARAM_TIMING_AUTOSCALE) != null) {
+ autoScaleTime = autoScaleTimingObjNode.path(PARAM_TIMING_AUTOSCALE).asLong();
}
timingBuilder.setAutoScaleTime(autoScaleTime);
@@ -945,13 +1134,75 @@
* @return TimingStatistics object
*/
private TimingStatistics getZeroTimingStatistics() {
- DefaultTimingStatistics.Builder zeroTimingBuilder = DefaultTimingStatistics.builder();
+ return DefaultTimingStatistics.builder()
+ .setParsingTime(0)
+ .setLaunchingTime(0)
+ .setAutoScaleTime(0)
+ .build();
+ }
- zeroTimingBuilder.setParsingTime(0)
- .setLaunchingTime(0)
- .setAutoScaleTime(0);
+ /**
+ * Implements DeviceSystemStatisticsQuery behaviour.
+ */
+ @Override
+ public Optional<DeviceSystemStats> getDeviceSystemStats() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
- return zeroTimingBuilder.build();
+ // ....to retrieve monitoring statistics
+ MonitoringStatistics monStats = getGlobalMonitoringStatistics(deviceId);
+
+ Optional<DeviceCpuStats> cpuStats = getOverallCpuUsage(monStats);
+ Optional<DeviceMemoryStats> memoryStats = getOverallMemoryUsage(monStats);
+
+ if (cpuStats.isPresent() && memoryStats.isPresent()) {
+ return Optional.of(new DeviceSystemStats(memoryStats.get(), cpuStats.get()));
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ /**
+ * Get CPU usage of server device.
+ *
+ * @param monStats global monitoring statistics which contain CPU statistics
+ * @return cpuStats, device CPU usage stats if available
+ */
+ private Optional<DeviceCpuStats> getOverallCpuUsage(MonitoringStatistics monStats) {
+ if (monStats == null) {
+ return Optional.empty();
+ }
+
+ if (monStats.numberOfCpus() == 0) {
+ return Optional.of(new DeviceCpuStats());
+ }
+
+ float usedCpu = 0.0f;
+ for (CpuStatistics cpuCoreStats : monStats.cpuStatisticsAll()) {
+ if (cpuCoreStats.busy()) {
+ usedCpu += cpuCoreStats.load();
+ }
+ }
+
+ return Optional.of(new DeviceCpuStats(usedCpu / (float) monStats.numberOfCpus()));
+ }
+
+ /**
+ * Get memory usage of server device in KB.
+ *
+ * @param monStats global monitoring statistics which contain memory statistics
+ * @return memoryStats, device memory usage stats if available
+ */
+ private Optional<DeviceMemoryStats> getOverallMemoryUsage(MonitoringStatistics monStats) {
+ if (monStats == null) {
+ return Optional.empty();
+ }
+
+ MemoryStatistics memStats = monStats.memoryStatistics();
+
+ return Optional.of(
+ new DeviceMemoryStats(memStats.free(), memStats.used(), memStats.total()));
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDriversLoader.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDriversLoader.java
index 33e9e5b..45edf76 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDriversLoader.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDriversLoader.java
@@ -24,7 +24,9 @@
*/
@Component(immediate = true)
public class ServerDriversLoader extends AbstractDriverLoader {
+
public ServerDriversLoader() {
super("/server-drivers.xml");
}
+
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerHandshaker.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerHandshaker.java
new file mode 100644
index 0000000..b141533
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerHandshaker.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.device.DeviceHandshaker;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.protocol.rest.RestSBDevice;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.CompletableFuture.completedFuture;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.PARAM_CONNECTION_STATUS;
+import static org.onosproject.drivers.server.Constants.MSG_HANDLER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.URL_SRV_PROBE_CONNECT;
+import static org.onosproject.drivers.server.Constants.URL_SRV_PROBE_DISCONNECT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of device handshaker behaviour for server devices.
+ */
+public class ServerHandshaker
+ extends BasicServerDriver
+ implements DeviceHandshaker {
+
+ private final Logger log = getLogger(getClass());
+
+ public ServerHandshaker() {
+ super();
+ log.debug("Started");
+ }
+
+ @Override
+ public DriverHandler handler() {
+ return super.getHandler();
+ }
+
+ @Override
+ public void setHandler(DriverHandler handler) {
+ checkNotNull(handler, MSG_HANDLER_NULL);
+ this.handler = handler;
+ }
+
+ @Override
+ public boolean connect() throws IllegalStateException {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Create an object node
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode sendObjNode = mapper.createObjectNode();
+ sendObjNode.put(PARAM_CONNECTION_STATUS, "connect");
+
+ // Post the connect message to the server
+ int response = getController().post(
+ deviceId, URL_SRV_PROBE_CONNECT,
+ new ByteArrayInputStream(sendObjNode.toString().getBytes()), JSON);
+
+ // Upon an error, return an empty set of rules
+ if (!checkStatusCode(response)) {
+ log.error("Failed to connect to device {}", deviceId);
+ return false;
+ }
+
+ log.info("Successfully connected to device {}", deviceId);
+
+ return true;
+ }
+
+ @Override
+ public boolean hasConnection() {
+ return isReachable();
+ }
+
+ @Override
+ public void disconnect() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Create an object node
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode sendObjNode = mapper.createObjectNode();
+ sendObjNode.put(PARAM_CONNECTION_STATUS, "disconnect");
+
+ // Post the disconnect message to the server
+ int response = getController().post(
+ deviceId, URL_SRV_PROBE_DISCONNECT,
+ new ByteArrayInputStream(sendObjNode.toString().getBytes()), JSON);
+
+ if (!checkStatusCode(response)) {
+ log.error("Failed to disconnect from device {}", deviceId);
+ return;
+ }
+
+ log.info("Successfully disconnected from device {}", deviceId);
+
+ return;
+ }
+
+ @Override
+ public boolean isReachable() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Get the device
+ RestSBDevice device = super.getDevice(deviceId);
+ checkNotNull(device, MSG_DEVICE_NULL);
+
+ return deviceIsActive(device);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return isReachable();
+ }
+
+ @Override
+ public CompletableFuture<Boolean> probeReachability() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Probe the driver to ask for flow rule service
+ FlowRuleService flowService = getHandler().get(FlowRuleService.class);
+ List<TableStatisticsEntry> tableStats = Lists.newArrayList(
+ flowService.getFlowTableStatistics(deviceId));
+
+ // If no statistics fetched, the server is not reachable
+ return completedFuture(tableStats.isEmpty() ? false : true);
+ }
+
+ @Override
+ public CompletableFuture<Boolean> probeAvailability() {
+ return probeReachability();
+ }
+
+ @Override
+ public void roleChanged(MastershipRole newRole) {
+ throw new UnsupportedOperationException("Mastership operation not supported");
+ }
+
+ @Override
+ public MastershipRole getRole() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Probe the driver to ask for mastership service
+ MastershipService mastershipService = getHandler().get(MastershipService.class);
+ return mastershipService.getLocalRole(deviceId);
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerInterfaceConfig.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerInterfaceConfig.java
new file mode 100644
index 0000000..b7fd93f
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerInterfaceConfig.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onlab.packet.VlanId;
+import org.onosproject.drivers.server.devices.RestServerSBDevice;
+import org.onosproject.drivers.server.devices.nic.NicDevice;
+import org.onosproject.drivers.server.devices.nic.NicRxFilter.RxFilter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.InterfaceConfig;
+import org.onosproject.net.behaviour.PatchDescription;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.device.DefaultDeviceInterfaceDescription;
+import org.onosproject.net.device.DeviceInterfaceDescription;
+
+import org.slf4j.Logger;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.net.device.DeviceInterfaceDescription.Mode;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of interface config behaviour for server devices.
+ */
+public class ServerInterfaceConfig
+ extends BasicServerDriver
+ implements InterfaceConfig {
+
+ private final Logger log = getLogger(getClass());
+
+ private static final boolean RATE_LIMIT_STATUS = false;
+ private static final short NO_LIMIT = -1;
+
+ public ServerInterfaceConfig() {
+ super();
+ log.debug("Started");
+ }
+
+ @Override
+ public boolean addTunnelMode(String ifaceName, TunnelDescription tunnelDesc) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean removeTunnelMode(String ifaceName) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean addAccessMode(String ifaceName, VlanId vlanId) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean removeAccessMode(String ifaceName) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean addPatchMode(String ifaceName, PatchDescription patchDesc) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean removePatchMode(String ifaceName) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean addTrunkMode(String ifaceName, List<VlanId> vlanIds) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean removeTrunkMode(String ifaceName) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean addRateLimit(String ifaceName, short limit) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public boolean removeRateLimit(String ifaceName) {
+ throw new UnsupportedOperationException("Interface operation not supported");
+ }
+
+ @Override
+ public List<DeviceInterfaceDescription> getInterfaces() {
+ // Retrieve the device ID
+ DeviceId deviceId = getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // .. and the device itself
+ RestServerSBDevice device = null;
+ try {
+ device = (RestServerSBDevice) getDevice(deviceId);
+ } catch (ClassCastException ccEx) {
+ log.error("Failed to get interfaces for device {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ if (device == null) {
+ log.error("No device with ID {} is available for interface discovery", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+ if ((device.nics() == null) || (device.nics().size() == 0)) {
+ log.error("No interfaces available on {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ // List of port descriptions to return
+ List<DeviceInterfaceDescription> intfDescriptions = Lists.newArrayList();
+
+ // Sorted list of NIC ports
+ Set<NicDevice> nics = new TreeSet(device.nics());
+
+ // Iterate through the NICs of this device to populate the list
+ for (NicDevice nic : nics) {
+ List<VlanId> devVlanIds = getVlanIdListForDevice(nic);
+ Mode devMode = getDeviceMode(devVlanIds);
+
+ // Create an interface description and add it to the list
+ intfDescriptions.add(
+ new DefaultDeviceInterfaceDescription(
+ nic.name(), devMode, devVlanIds, RATE_LIMIT_STATUS, NO_LIMIT));
+ }
+
+ return ImmutableList.copyOf(intfDescriptions);
+ }
+
+ /**
+ * Returns a list of VLAN IDs associated with a NIC device.
+ *
+ * @param nic the NIC device to be queried
+ * @return a list of VLAN IDs (if any)
+ */
+ private List<VlanId> getVlanIdListForDevice(NicDevice nic) {
+ checkNotNull(nic, MSG_DEVICE_NULL);
+ List<VlanId> vlanIds = Lists.newArrayList();
+
+ short vlanIdValue = 0;
+ for (RxFilter rxFilter : nic.rxFilterMechanisms().rxFilters()) {
+ if (rxFilter == RxFilter.VLAN) {
+ vlanIds.add(VlanId.vlanId(vlanIdValue++));
+ }
+ }
+
+ return ImmutableList.copyOf(vlanIds);
+ }
+
+ /**
+ * Returns the interface mode of a NIC device, by looking at its VLAN IDs.
+ *
+ * @param vlanIds a list of VLAN IDs associated with the device
+ * @return interface mode
+ */
+ private Mode getDeviceMode(List<VlanId> vlanIds) {
+ if (vlanIds.size() == 1) {
+ return Mode.ACCESS;
+ } else if (vlanIds.size() > 1) {
+ return Mode.TRUNK;
+ }
+
+ return Mode.NORMAL;
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerPortAdmin.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerPortAdmin.java
new file mode 100644
index 0000000..4ab311c
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerPortAdmin.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onosproject.drivers.server.devices.RestServerSBDevice;
+import org.onosproject.drivers.server.devices.nic.NicDevice;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.PortAdmin;
+import org.onosproject.net.driver.DriverHandler;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import java.io.ByteArrayInputStream;
+import java.util.concurrent.CompletableFuture;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.CompletableFuture.completedFuture;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.MSG_HANDLER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_PORT;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_PORT_STATUS;
+import static org.onosproject.drivers.server.Constants.URL_NIC_PORT_ADMIN;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of port admin behaviour for server devices.
+ */
+public class ServerPortAdmin
+ extends BasicServerDriver
+ implements PortAdmin {
+
+ private final Logger log = getLogger(getClass());
+
+ public ServerPortAdmin() {
+ super();
+ log.debug("Started");
+ }
+
+ @Override
+ public DriverHandler handler() {
+ return super.getHandler();
+ }
+
+ @Override
+ public void setHandler(DriverHandler handler) {
+ checkNotNull(handler, MSG_HANDLER_NULL);
+ this.handler = handler;
+ }
+
+ @Override
+ public CompletableFuture<Boolean> enable(PortNumber number) {
+ return doEnable(number, true);
+ }
+
+ @Override
+ public CompletableFuture<Boolean> disable(PortNumber number) {
+ return doEnable(number, false);
+ }
+
+ @Override
+ public CompletableFuture<Boolean> isEnabled(PortNumber number) {
+ // Retrieve the device ID
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // ...and the device itself
+ RestServerSBDevice device = null;
+ try {
+ device = (RestServerSBDevice) getDevice(deviceId);
+ } catch (ClassCastException ccEx) {
+ log.error("Failed to discover ports for device {}", deviceId);
+ return completedFuture(false);
+ }
+
+ // Iterate server's NICs to find the correct port
+ for (NicDevice nic : device.nics()) {
+ if (nic.portNumber() == number.toLong()) {
+ return completedFuture(nic.status());
+ }
+ }
+
+ return completedFuture(false);
+ }
+
+ /**
+ * Perform a NIC port management command.
+ *
+ * @param portNumber port number to manage
+ * @param enabled management flag (true to enable, false to disable the port)
+ * @return boolean status
+ */
+ private CompletableFuture<Boolean> doEnable(PortNumber portNumber, boolean enabled) {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Create an object node with the port status
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode sendObjNode = mapper.createObjectNode();
+ sendObjNode.put(PARAM_NIC_PORT, portNumber.toLong());
+ sendObjNode.put(PARAM_NIC_PORT_STATUS, enabled ? "enable" : "disable");
+
+ // Post the connect message to the server
+ int response = getController().post(
+ deviceId, URL_NIC_PORT_ADMIN,
+ new ByteArrayInputStream(sendObjNode.toString().getBytes()), JSON);
+
+ // Upon an error, return an empty set of rules
+ if (!checkStatusCode(response)) {
+ log.error("Failed to connect to device {}", deviceId);
+ return completedFuture(false);
+ }
+
+ log.info("Successfully sent port {} command to device {}",
+ enabled ? "enable" : "disable", deviceId);
+
+ return completedFuture(true);
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerQueueConfig.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerQueueConfig.java
new file mode 100644
index 0000000..f50a169
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerQueueConfig.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onlab.util.Bandwidth;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.DefaultQueueDescription;
+import org.onosproject.net.behaviour.QueueConfigBehaviour;
+import org.onosproject.net.behaviour.QueueDescription;
+import org.onosproject.net.behaviour.QueueDescription.Type;
+import org.onosproject.net.behaviour.QueueId;
+import org.onosproject.protocol.rest.RestSBDevice;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableList;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import javax.ws.rs.ProcessingException;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.PARAM_ID;
+import static org.onosproject.drivers.server.Constants.PARAM_NICS;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_MAX_RATE;
+import static org.onosproject.drivers.server.Constants.PARAM_QUEUES;
+import static org.onosproject.drivers.server.Constants.PARAM_TYPE;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.URL_NIC_QUEUE_ADMIN;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of queue config behaviour for server devices.
+ */
+public class ServerQueueConfig
+ extends BasicServerDriver
+ implements QueueConfigBehaviour {
+
+ private final Logger log = getLogger(getClass());
+
+ public ServerQueueConfig() {
+ super();
+ log.debug("Started");
+ }
+
+ @Override
+ public Collection<QueueDescription> getQueues() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Get the device
+ RestSBDevice device = super.getDevice(deviceId);
+ checkNotNull(device, MSG_DEVICE_NULL);
+
+ // Hit the path that provides queue administration
+ InputStream response = null;
+ try {
+ response = getController().get(deviceId, URL_NIC_QUEUE_ADMIN, JSON);
+ } catch (ProcessingException pEx) {
+ log.error("Failed to get NIC queues from device: {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ // Load the JSON into object
+ ObjectMapper mapper = new ObjectMapper();
+ Map<String, Object> jsonMap = null;
+ JsonNode jsonNode = null;
+ ObjectNode objNode = null;
+ try {
+ jsonMap = mapper.readValue(response, Map.class);
+ jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
+ objNode = (ObjectNode) jsonNode;
+ } catch (IOException ioEx) {
+ log.error("Failed to get NIC queues from device: {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ if (objNode == null) {
+ log.error("Failed to get NIC queues from device: {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ Collection<QueueDescription> queueDescs = Sets.newHashSet();
+
+ // Fetch NICs' array
+ JsonNode nicsNode = objNode.path(PARAM_NICS);
+
+ for (JsonNode nn : nicsNode) {
+ ObjectNode nicObjNode = (ObjectNode) nn;
+ int nicId = nicObjNode.path(PARAM_ID).asInt();
+ JsonNode queuesNode = nicObjNode.path(PARAM_QUEUES);
+
+ // Each NIC has a set of queues
+ for (JsonNode qn : queuesNode) {
+ ObjectNode queueObjNode = (ObjectNode) qn;
+
+ // Get the attributes of a queue
+ int queueIdInt = queueObjNode.path(PARAM_ID).asInt();
+ String queueTypeStr = get(qn, PARAM_TYPE);
+ long queueRateInt = queueObjNode.path(PARAM_NIC_MAX_RATE).asLong();
+
+ QueueId queueId = QueueId.queueId("nic" + nicId + ":" + queueIdInt);
+ EnumSet<Type> queueTypes = getQueueTypesFromString(queueTypeStr);
+ Bandwidth queueRate = Bandwidth.mbps(queueRateInt);
+
+ queueDescs.add(
+ DefaultQueueDescription.builder()
+ .queueId(queueId)
+ .type(queueTypes)
+ .maxRate(queueRate)
+ .build());
+ }
+ }
+
+ log.info("[Device {}] NIC queues: {}", deviceId, queueDescs);
+
+ return ImmutableList.copyOf(queueDescs);
+ }
+
+ @Override
+ public QueueDescription getQueue(QueueDescription queueDesc) {
+ for (QueueDescription qDesc : getQueues()) {
+ if (queueDesc.queueId().equals(qDesc.queueId())) {
+ return qDesc;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean addQueue(QueueDescription queue) {
+ throw new UnsupportedOperationException("Add queue operation not supported");
+ }
+
+ @Override
+ public void deleteQueue(QueueId queueId) {
+ throw new UnsupportedOperationException("Delete queue operation not supported");
+ }
+
+ /**
+ * Convert string-based queue type into enum set.
+ *
+ * @param queueTypeStr string-based queue type
+ * @return queue types enum set
+ */
+ private EnumSet<Type> getQueueTypesFromString(String queueTypeStr) {
+ EnumSet<Type> enumSet = EnumSet.noneOf(Type.class);
+ if ((queueTypeStr == null) || (queueTypeStr.isEmpty())) {
+ return enumSet;
+ }
+
+ if (queueTypeStr.toUpperCase().equals("MIN")) {
+ enumSet.add(Type.MAX);
+ } else if (queueTypeStr.toUpperCase().equals("MAX")) {
+ enumSet.add(Type.MIN);
+ } else if (queueTypeStr.toUpperCase().equals("PRIORITY")) {
+ enumSet.add(Type.PRIORITY);
+ } else {
+ enumSet.add(Type.BURST);
+ }
+
+ return enumSet;
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerTableStatisticsDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerTableStatisticsDiscovery.java
new file mode 100644
index 0000000..f106d83
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerTableStatisticsDiscovery.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.TableStatisticsDiscovery;
+import org.onosproject.net.flow.DefaultTableStatisticsEntry;
+import org.onosproject.net.flow.IndexTableId;
+import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.protocol.rest.RestSBDevice;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.ProcessingException;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.JSON;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_TABLE_SIZE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_TABLE_INDEX_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_TABLE_COUNTER_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.PARAM_ID;
+import static org.onosproject.drivers.server.Constants.PARAM_NICS;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_TABLE;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_TABLE_ACTIVE_ENTRIES;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_TABLE_PKTS_LOOKED_UP;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_TABLE_PKTS_MATCHED;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_TABLE_MAX_SIZE;
+import static org.onosproject.drivers.server.Constants.URL_RULE_TABLE_STATS;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of table statistics discovery for server devices.
+ */
+public class ServerTableStatisticsDiscovery
+ extends BasicServerDriver
+ implements TableStatisticsDiscovery {
+
+ private final Logger log = getLogger(getClass());
+
+ public ServerTableStatisticsDiscovery() {
+ super();
+ log.debug("Started");
+ }
+
+ @Override
+ public List<TableStatisticsEntry> getTableStatistics() {
+ // Retrieve the device ID from the handler
+ DeviceId deviceId = super.getDeviceId();
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+
+ // Get the device
+ RestSBDevice device = super.getDevice(deviceId);
+ checkNotNull(device, MSG_DEVICE_NULL);
+
+ // Hit the path that provides the server's NIC table statistics
+ InputStream response = null;
+ try {
+ response = getController().get(deviceId, URL_RULE_TABLE_STATS, JSON);
+ } catch (ProcessingException pEx) {
+ log.error("Failed to get NIC table statistics from device: {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ // Load the JSON into object
+ ObjectMapper mapper = new ObjectMapper();
+ Map<String, Object> jsonMap = null;
+ JsonNode jsonNode = null;
+ ObjectNode objNode = null;
+ try {
+ jsonMap = mapper.readValue(response, Map.class);
+ jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
+ objNode = (ObjectNode) jsonNode;
+ } catch (IOException ioEx) {
+ log.error("Failed to get NIC table statistics from device: {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ if (jsonNode == null) {
+ log.error("Failed to get NIC table statistics from device: {}", deviceId);
+ return Collections.EMPTY_LIST;
+ }
+
+ List<TableStatisticsEntry> tableStats = Lists.newArrayList();
+
+ JsonNode nicNode = objNode.path(PARAM_NICS);
+
+ for (JsonNode nn : nicNode) {
+ ObjectNode nicObjNode = (ObjectNode) nn;
+
+ // The index of the NIC that hosts rules table(s)
+ long nicIndex = nicObjNode.path(Constants.PARAM_ID).asLong();
+
+ JsonNode tableNode = nicObjNode.path(PARAM_NIC_TABLE);
+ if (tableNode == null) {
+ throw new IllegalArgumentException("No tables reported for NIC " + nicIndex);
+ }
+
+ for (JsonNode tn : tableNode) {
+ ObjectNode tableObjNode = (ObjectNode) tn;
+
+ // NIC table attributes
+ int tableIndex = tableObjNode.path(PARAM_ID).asInt();
+ checkArgument(tableIndex >= 0, MSG_NIC_TABLE_INDEX_NEGATIVE);
+
+ long tableActiveEntries = tableObjNode.path(PARAM_NIC_TABLE_ACTIVE_ENTRIES).asLong();
+ checkArgument(tableActiveEntries >= 0, MSG_NIC_TABLE_COUNTER_NEGATIVE);
+
+ long tablePktsLookedUp = tableObjNode.path(PARAM_NIC_TABLE_PKTS_LOOKED_UP).asLong();
+ checkArgument(tablePktsLookedUp >= 0, MSG_NIC_TABLE_COUNTER_NEGATIVE);
+
+ long tablePktsMatched = tableObjNode.path(PARAM_NIC_TABLE_PKTS_MATCHED).asLong();
+ checkArgument(tablePktsMatched >= 0, MSG_NIC_TABLE_COUNTER_NEGATIVE);
+
+ long tableMaxsize = tableObjNode.path(PARAM_NIC_TABLE_MAX_SIZE).asLong();
+ checkArgument(tableMaxsize >= 0, MSG_NIC_TABLE_SIZE_NEGATIVE);
+
+ // Server's device ID and NIC ID compose a NIC device ID
+ DeviceId nicDeviceId = DeviceId.deviceId(
+ deviceId.toString() + ":nic" + String.valueOf(nicIndex));
+
+ TableStatisticsEntry tableStat = DefaultTableStatisticsEntry.builder()
+ .withDeviceId(nicDeviceId)
+ .withTableId(IndexTableId.of(tableIndex))
+ .withActiveFlowEntries(tableActiveEntries)
+ .withPacketsLookedUpCount(tablePktsLookedUp)
+ .withPacketsMatchedCount(tablePktsMatched)
+ .withMaxSize(tableMaxsize > 0 ? tableMaxsize : -1)
+ .build();
+
+ tableStats.add(tableStat);
+
+ log.debug("[Device {}] NIC {} with table statistics: {}",
+ deviceId, nicIndex, tableStat);
+ }
+ }
+
+ return ImmutableList.copyOf(tableStats);
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/CpuStatisticsDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/CpuStatisticsDiscovery.java
index 9d42f95..8a6c91c 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/CpuStatisticsDiscovery.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/CpuStatisticsDiscovery.java
@@ -33,4 +33,5 @@
* @return CPU statistics list
*/
Collection<CpuStatistics> discoverCpuStatistics();
+
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/MonitoringStatisticsDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/MonitoringStatisticsDiscovery.java
index ba8ea2a..7d4aa6e 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/MonitoringStatisticsDiscovery.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/behavior/MonitoringStatisticsDiscovery.java
@@ -45,4 +45,5 @@
* @return resource-specific monitoring statistics
*/
MonitoringStatistics discoverMonitoringStatistics(URI tcId);
+
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/RestServerSBDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/RestServerSBDevice.java
index 0d64248..77873aa 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/RestServerSBDevice.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/RestServerSBDevice.java
@@ -16,15 +16,19 @@
package org.onosproject.drivers.server.devices;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheHierarchyDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryHierarchyDevice;
import org.onosproject.drivers.server.devices.nic.NicDevice;
import org.onosproject.protocol.rest.RestSBDevice;
import java.util.Collection;
/**
- * Represents an abstraction of a REST server device in ONOS.
+ * Represents an abstraction of a REST server device.
*/
public interface RestServerSBDevice extends RestSBDevice {
+
/**
* Returns the set of CPUs of the server.
*
@@ -40,6 +44,41 @@
int numberOfCpus();
/**
+ * Returns the CPU cache hierarchy of the server.
+ *
+ * @return CPU cache hierarchy
+ */
+ CpuCacheHierarchyDevice caches();
+
+ /**
+ * Returns the number of CPU caches of the server.
+ *
+ * @return number of CPU caches
+ */
+ int numberOfCaches();
+
+ /**
+ * Returns the capacity of the CPU caches of the server.
+ *
+ * @return total CPU cache capacity
+ */
+ long cacheCapacity();
+
+ /**
+ * Returns the main memory hierarchy of the server.
+ *
+ * @return main memory hierarchy
+ */
+ MemoryHierarchyDevice memory();
+
+ /**
+ * Returns the capacity of the server's main memory.
+ *
+ * @return total main memory capacity
+ */
+ long memoryCapacity();
+
+ /**
* Returns the set of NICs of the server.
*
* @return set of NICs
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/ServerDeviceDescription.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/ServerDeviceDescription.java
index 02c9a11..b2e9c73 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/ServerDeviceDescription.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/ServerDeviceDescription.java
@@ -16,6 +16,9 @@
package org.onosproject.drivers.server.devices;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheHierarchyDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryHierarchyDevice;
import org.onosproject.drivers.server.devices.nic.NicDevice;
import org.onosproject.net.device.DeviceDescription;
@@ -34,6 +37,20 @@
Collection<CpuDevice> cpus();
/**
+ * The CPU cache hierarchy of the server device.
+ *
+ * @return CPU cache hierarchy of the server device
+ */
+ CpuCacheHierarchyDevice caches();
+
+ /**
+ * The memory hierarchy of the server device.
+ *
+ * @return memory hierarchy of the server device
+ */
+ MemoryHierarchyDevice memory();
+
+ /**
* The set of NICs of the server device.
*
* @return set of NICs of the server device
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/BasicCpuCacheDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/BasicCpuCacheDevice.java
new file mode 100644
index 0000000..5f2db0f
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/BasicCpuCacheDevice.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+/**
+ * Represents an abstraction of a CPU cache.
+ */
+public interface BasicCpuCacheDevice {
+
+ /**
+ * Returns the ID of this cache.
+ * A CPU cache ID is a pair of CPU cache level and type.
+ *
+ * @return cache ID
+ */
+ CpuCacheId cacheId();
+
+ /**
+ * Returns the placement policy of this cache.
+ *
+ * @return cache placement policy
+ */
+ CpuCachePlacementPolicy policy();
+
+ /**
+ * Returns the vendor of this cache.
+ * Typically, a cache is part of a CPU,
+ * therefore shares the same vendor.
+ *
+ * @return cache vendor
+ */
+ CpuVendor vendor();
+
+ /**
+ * Returns the capacity of this cache in kilo bytes.
+ *
+ * @return cache capacity in kilo bytes
+ */
+ long capacity();
+
+ /**
+ * Returns the number of sets this cache is split across.
+ *
+ * @return number of cache sets
+ */
+ int sets();
+
+ /**
+ * Returns the ways of associativity of this cache.
+ *
+ * @return ways of associativity
+ */
+ int associativityWays();
+
+ /**
+ * Returns the cache line's length in bytes.
+ *
+ * @return cache line's length in bytes
+ */
+ int lineLength();
+
+ /**
+ * Returns whether this CPU cache is shared among multiple cores
+ * or dedicated to a specific core.
+ *
+ * @return sharing status of the CPU cache
+ */
+ boolean isShared();
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheHierarchyDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheHierarchyDevice.java
new file mode 100644
index 0000000..410066c
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheHierarchyDevice.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+import java.util.Map;
+
+/**
+ * Represents an abstraction of a CPU cache hierarchy.
+ */
+public interface CpuCacheHierarchyDevice {
+
+ /**
+ * Returns the vendor of this cache hierarchy.
+ *
+ * @return cache hierarchy vendor
+ */
+ CpuVendor vendor();
+
+ /**
+ * Returns the number of the system's CPU sockets.
+ * This number affects the number of caches present in the system.
+ *
+ * @return number of CPU sockets
+ */
+ int socketsNb();
+
+ /**
+ * Returns the number of the system's CPU cores.
+ * This number affects the number of caches present in the system.
+ *
+ * @return number of CPU cores
+ */
+ int coresNb();
+
+ /**
+ * Returns the number of cache levels of this cache.
+ *
+ * @return cache level
+ */
+ int levels();
+
+ /**
+ * Returns the capacity local to each CPU core in kilo bytes.
+ *
+ * @return per CPU core local cache capacity in kilo bytes
+ */
+ long perCoreCapacity();
+
+ /**
+ * Returns the capacity of the last-level cache in kilo bytes.
+ *
+ * @return last-level cache's capacity in kilo bytes
+ */
+ long llcCapacity();
+
+ /**
+ * Returns the capacity of the entire cache hierarchy in kilo bytes.
+ *
+ * @return entire cache hierarchy's capacity in kilo bytes
+ */
+ long totalCapacity();
+
+ /**
+ * Returns the CPU cache hierarchy.
+ *
+ * @return CPU cache hierarchy
+ */
+ Map<CpuCacheId, BasicCpuCacheDevice> cacheHierarchy();
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheId.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheId.java
new file mode 100644
index 0000000..ce9fca9
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheId.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_LEVEL_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_TYPE_NULL;
+
+/**
+ * Represents a CPU cache ID.
+ * This class is immutable.
+ */
+public final class CpuCacheId {
+
+ private final CpuCacheLevel level;
+ private final CpuCacheType type;
+
+ /**
+ * Constructor from an integer value.
+ *
+ * @param value the value to use
+ */
+ private CpuCacheId(CpuCacheLevel level, CpuCacheType type) {
+ checkNotNull(level, MSG_CPU_CACHE_LEVEL_NULL);
+ checkNotNull(type, MSG_CPU_CACHE_TYPE_NULL);
+ this.level = level;
+ this.type = type;
+ }
+
+ /**
+ * Creates a builder for CpuCacheId object.
+ *
+ * @return builder object for CpuCacheId object
+ */
+ public static CpuCacheId.Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Get the level of the CPU cache.
+ *
+ * @return CPU cache level
+ */
+ public CpuCacheLevel level() {
+ return level;
+ }
+
+ /**
+ * Get the type of the CPU cache.
+ *
+ * @return CPU cache type
+ */
+ public CpuCacheType type() {
+ return type;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("level", level())
+ .add("type", type())
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(level, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof CpuCacheId)) {
+ return false;
+ }
+ CpuCacheId cacheId = (CpuCacheId) obj;
+ return this.level() == cacheId.level() &&
+ this.type() == cacheId.type();
+ }
+
+ public static final class Builder {
+
+ CpuCacheLevel level;
+ CpuCacheType type;
+
+ private Builder() {
+ }
+
+ /**
+ * Sets CPU cache level.
+ *
+ * @param levelStr CPU cache level as a string
+ * @return builder object
+ */
+ public Builder setLevel(String levelStr) {
+ if (!Strings.isNullOrEmpty(levelStr)) {
+ this.level = CpuCacheLevel.getByName(levelStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets CPU cache type.
+ *
+ * @param typeStr CPU cache type as a string
+ * @return builder object
+ */
+ public Builder setType(String typeStr) {
+ if (!Strings.isNullOrEmpty(typeStr)) {
+ this.type = CpuCacheType.getByName(typeStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Creates a CpuCacheId object.
+ *
+ * @return CpuCacheId object
+ */
+ public CpuCacheId build() {
+ return new CpuCacheId(level, type);
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheLevel.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheLevel.java
new file mode 100644
index 0000000..f4cc5c1
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheLevel.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Representation of a CPU cache's levels.
+ */
+public enum CpuCacheLevel {
+
+ /**
+ * Depending on the hardware architecture and vendor,
+ * a CPU cache hierarchy might comprise of multiple levels
+ * of CPU caches. Some hardware architectures use 3 levels
+ * of CPU caches, while others use 4. In the former case,
+ * the last-level cache (LLC) is the L3 cache, while in the
+ * latter case LLC corresponds to the cache after L3
+ * (conceptually L4).
+ */
+ REGISTER("Register"), // CPU register
+ L1("L1"), // L1 cache
+ L2("L2"), // L2 cache
+ L3("L3"), // L3 cache
+ L4("L4"), // L4 cache
+ LLC("LLC"); // Last-level cache
+
+ private String level;
+
+ // Statically maps CPU cache levels to enum types
+ private static final Map<String, CpuCacheLevel> MAP =
+ new HashMap<String, CpuCacheLevel>();
+ static {
+ for (CpuCacheLevel cl : CpuCacheLevel.values()) {
+ MAP.put(cl.toString().toLowerCase(), cl);
+ }
+ }
+
+ private CpuCacheLevel(String level) {
+ this.level = level;
+ }
+
+ public static CpuCacheLevel getByName(String cl) {
+ return MAP.get(cl.toLowerCase());
+ }
+
+ public static int toNumber(CpuCacheLevel cacheLevel) {
+ return Integer.parseInt(cacheLevel.toString().split("L")[1]);
+ }
+
+ public static boolean isLlc(CpuCacheLevel cacheLevel) {
+ return (cacheLevel == LLC);
+ }
+
+ @Override
+ public String toString() {
+ return this.level;
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCachePlacementPolicy.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCachePlacementPolicy.java
new file mode 100644
index 0000000..75cb290
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCachePlacementPolicy.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Representation of a CPU cache's placement policies.
+ */
+public enum CpuCachePlacementPolicy {
+
+ /**
+ * Direct-mapped cache: the cache is organized into multiple
+ * sets with a single cache line per set. A memory block can
+ * only occupy a single cache line. A direct-mapped cache
+ * corresponds to an 1-way set-associative cache.
+ */
+ DIRECT_MAPPED("Direct-Mapped"),
+ /**
+ * Fully-associative cache: the cache is organized into a
+ * single cache set with multiple cache lines.
+ * A memory block can occupy any of the cache lines.
+ * A fully-associative cache with m lines corresponds to an
+ * m-way set-associative cache.
+ */
+ FULLY_ASSOCIATIVE("Fully-Associative"),
+ /**
+ * Set-associative cache: the cache is organized into ‘n’
+ * sets and each set contains ‘m’ cache lines. A memory block
+ * is first mapped onto a set and then placed into any cache
+ * line of this set.
+ */
+ SET_ASSOCIATIVE("Set-Associative");
+
+ private String cachePolicy;
+
+ // Statically maps CPU cache placement policies to enum types
+ private static final Map<String, CpuCachePlacementPolicy> MAP =
+ new HashMap<String, CpuCachePlacementPolicy>();
+ static {
+ for (CpuCachePlacementPolicy cp : CpuCachePlacementPolicy.values()) {
+ MAP.put(cp.toString().toLowerCase(), cp);
+ }
+ }
+
+ private CpuCachePlacementPolicy(String cachePolicy) {
+ this.cachePolicy = cachePolicy;
+ }
+
+ public static CpuCachePlacementPolicy getByName(String cp) {
+ return MAP.get(cp.toLowerCase());
+ }
+
+ @Override
+ public String toString() {
+ return this.cachePolicy;
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheType.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheType.java
new file mode 100644
index 0000000..553cbbf
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCacheType.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Representation of a CPU cache's types.
+ */
+public enum CpuCacheType {
+
+ /**
+ * A CPU cache can store data, CPU instructions,
+ * or both (i.e., unified case).
+ */
+ DATA("Data"),
+ INSTRUCTION("Instruction"),
+ UNIFIED("Unified");
+
+ private String cacheType;
+
+ // Statically maps CPU cache types to enum types
+ private static final Map<String, CpuCacheType> MAP =
+ new HashMap<String, CpuCacheType>();
+ static {
+ for (CpuCacheType ct : CpuCacheType.values()) {
+ MAP.put(ct.toString().toLowerCase(), ct);
+ }
+ }
+
+ private CpuCacheType(String cacheType) {
+ this.cacheType = cacheType;
+ }
+
+ public static CpuCacheType getByName(String ct) {
+ return MAP.get(ct.toLowerCase());
+ }
+
+ public static boolean isData(CpuCacheType cacheType) {
+ return (cacheType == DATA);
+ }
+
+ public static boolean isInstruction(CpuCacheType cacheType) {
+ return (cacheType == INSTRUCTION);
+ }
+
+ public static boolean isUnified(CpuCacheType cacheType) {
+ return (cacheType == UNIFIED);
+ }
+
+ @Override
+ public String toString() {
+ return this.cacheType;
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCoreId.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCoreId.java
new file mode 100644
index 0000000..939172c
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuCoreId.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.cpu;
+
+import org.onlab.util.Identifier;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Represents a CPU core ID.
+ * This class is immutable.
+ */
+public final class CpuCoreId extends Identifier<Integer> {
+
+ /**
+ * A CPU core with this ID is shared.
+ */
+ private static final int SHARED = -1;
+
+ /**
+ * Upper limits of CPU core IDs and sockets in one machine.
+ */
+ public static final int MAX_CPU_CORE_NB = 512;
+ public static final int MAX_CPU_SOCKET_NB = 4;
+
+ private final int physicalId;
+
+ /**
+ * Constructor from integer values.
+ *
+ * @param logicalId the logical ID of this CPU core
+ * @param physicalId the physical ID of this CPU core
+ */
+ public CpuCoreId(int logicalId, int physicalId) {
+ super(logicalId);
+ if (logicalId >= 0) {
+ checkArgument(logicalId < MAX_CPU_CORE_NB,
+ "Logical CPU core ID must be in [0, " +
+ String.valueOf(CpuCoreId.MAX_CPU_CORE_NB - 1) + "]");
+ }
+ this.physicalId = physicalId;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * @param logicalIdStr the logical ID of this CPU core as a string
+ * @param physicalIdStr the physical ID of this CPU core as a string
+ */
+ public CpuCoreId(String logicalIdStr, String physicalIdStr) {
+ this(Integer.parseInt(logicalIdStr), Integer.parseInt(physicalIdStr));
+ }
+
+ /**
+ * Static constructor of a shared CPU core ID.
+ *
+ * @return a shared CPU core ID
+ */
+ public static CpuCoreId shared() {
+ return new CpuCoreId(SHARED, SHARED);
+ }
+
+ /**
+ * Get the logical ID of this CPU core.
+ *
+ * @return logical ID of this CPU core
+ */
+ public int logicalId() {
+ return identifier;
+ }
+
+ /**
+ * Get the physical ID of this CPU core.
+ *
+ * @return physical ID of this CPU core
+ */
+ public int physicalId() {
+ return physicalId;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("logicalId", logicalId())
+ .add("physicalId", physicalId())
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(identifier, physicalId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof CpuCoreId)) {
+ return false;
+ }
+ CpuCoreId coreId = (CpuCoreId) obj;
+ return this.logicalId() == coreId.logicalId() &&
+ this.physicalId() == coreId.physicalId();
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/CpuDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuDevice.java
similarity index 76%
rename from drivers/server/src/main/java/org/onosproject/drivers/server/devices/CpuDevice.java
rename to drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuDevice.java
index 4ddd241..96d5416 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/CpuDevice.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuDevice.java
@@ -14,21 +14,26 @@
* limitations under the License.
*/
-package org.onosproject.drivers.server.devices;
+package org.onosproject.drivers.server.devices.cpu;
/**
- * Represents an abstraction of a CPU core in ONOS.
+ * Represents an abstraction of a CPU core.
*/
public interface CpuDevice {
/**
+ * Maximum CPU core frequency in MHz.
+ */
+ static final long MAX_FREQUENCY_MHZ = 4500;
+
+ /**
* Returns the ID of this CPU.
* Typically this is the order number (0...N-1)
* of this CPU core in the socket.
*
* @return CPU core ID
*/
- int id();
+ CpuCoreId id();
/**
* Returns the vendor of this CPU core.
@@ -38,6 +43,13 @@
CpuVendor vendor();
/**
+ * Returns the socket ID of this CPU core.
+ *
+ * @return CPU core socket ID
+ */
+ int socket();
+
+ /**
* Returns the frequency of this CPU core in MHz.
*
* @return CPU core frequency in MHz
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/CpuVendor.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuVendor.java
similarity index 87%
rename from drivers/server/src/main/java/org/onosproject/drivers/server/devices/CpuVendor.java
rename to drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuVendor.java
index 289b3c3..37c2d56 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/CpuVendor.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/CpuVendor.java
@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.drivers.server.devices;
+
+package org.onosproject.drivers.server.devices.cpu;
import java.util.Map;
import java.util.HashMap;
@@ -24,7 +25,7 @@
public enum CpuVendor {
INTEL("GenuineIntel"),
- AMD("AMD");
+ AMD("AuthenticAMD");
private String vendor;
@@ -41,9 +42,8 @@
this.vendor = vendor;
}
- public static CpuVendor getByName(String pr) {
- pr = pr.toLowerCase();
- return MAP.get(pr);
+ public static CpuVendor getByName(String cv) {
+ return MAP.get(cv.toLowerCase());
}
@Override
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/package-info.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/package-info.java
new file mode 100644
index 0000000..4b6262a
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/cpu/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * API for a server's CPU devices.
+ */
+package org.onosproject.drivers.server.devices.cpu;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryHierarchyDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryHierarchyDevice.java
new file mode 100644
index 0000000..cf1bf25
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryHierarchyDevice.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.memory;
+
+import java.util.Collection;
+
+/**
+ * Represents an abstraction of a main memory hierarchy.
+ */
+public interface MemoryHierarchyDevice {
+
+ /**
+ * Returns the number of memory modules of this main memory hierarchy.
+ *
+ * @return number of main memory modules
+ */
+ int modulesNb();
+
+ /**
+ * Returns the capacity of the entire main memory hierarchy in MBytes.
+ *
+ * @return entire main memory hierarchy's capacity in Mbytes
+ */
+ long totalCapacity();
+
+ /**
+ * Returns the main memory hierarchy.
+ *
+ * @return main memory hierarchy
+ */
+ Collection<MemoryModuleDevice> memoryHierarchy();
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryModuleDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryModuleDevice.java
new file mode 100644
index 0000000..bdd3fa7
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryModuleDevice.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.memory;
+
+/**
+ * Represents an abstraction of a main memory device.
+ */
+public interface MemoryModuleDevice {
+
+ /**
+ * Maximum main memory speed in million transfers per second (MT/s).
+ */
+ static final long MAX_SPEED_MTS = 8000;
+
+ /**
+ * Returns the type of this main memory module.
+ *
+ * @return main memory type
+ */
+ MemoryType type();
+
+ /**
+ * Returns the manufacturer of this main memory module.
+ *
+ * @return main memory manufacturer
+ */
+ String manufacturer();
+
+ /**
+ * Returns the serial number of this main memory module.
+ *
+ * @return main memory serial number
+ */
+ String serialNumber();
+
+ /**
+ * Returns the data width (in bits) of this main memory module.
+ *
+ * @return data width in bits
+ */
+ int dataWidth();
+
+ /**
+ * Returns the total width (in bits) of this main memory module.
+ *
+ * @return total width in bits
+ */
+ int totalWidth();
+
+ /**
+ * Returns the capacity (in MBytes) of this main memory module.
+ *
+ * @return capacity in MBytes
+ */
+ long capacity();
+
+ /**
+ * Returns the speed of this main memory module in MT/s.
+ *
+ * @return main memory speed in MT/s
+ */
+ long speed();
+
+ /**
+ * Returns the configuted speed of this main memory in MT/s.
+ *
+ * @return configured main memory speed in MT/s
+ */
+ long configuredSpeed();
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryType.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryType.java
new file mode 100644
index 0000000..bb78129
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/MemoryType.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.devices.memory;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Representation of main memory types.
+ */
+public enum MemoryType {
+
+ /**
+ * Main memory types are divided into two main
+ * categories, i.e., RAM and ROM.
+ *
+ * RAM memories are further divided into:
+ * |-> SRAM: Static Random Access Memory
+ * |-> DRAM: Dynamic Random Access Memory
+ * |-> SDRAM: Synchronous DRAM
+ * |-> DDR-SDRAM: Double data-rate synchronous DRAM
+ * |--> DDR2: 2nd Generation DDR
+ * |--> DDR3: 3rd Generation DDR
+ * |--> DDR4: 4th Generation DDR
+ * |--> DDR5: 5th Generation DDR (coming soon)
+ * |-> CDRAM: Cached DRAM
+ * |-> EDRAM: Embedded DRAM
+ * |-> SGRAM: Synchronous Graphics RAM
+ * |-> VRAM: Video DRAM
+ *
+ * ROM memories are further divided into:
+ * |-> PROM: Programmable read-only memory
+ * |-> EPROM: Erasable Programmable read only memory
+ * |-> FEPROM: Flash Erasable Programmable Read Only Memory
+ * |-> EEPROM: Electrically erasable programmable read only memory
+ */
+ SRAM("SRAM"),
+ DRAM("DRAM"),
+ SDRAM("SDRAM"),
+ DDR("DDR"),
+ DDR2("DDR2"),
+ DDR3("DDR3"),
+ DDR4("DDR4"),
+ DDR5("DDR5"),
+ CDRAM("CDRAM"),
+ EDRAM("EDRAM"),
+ SGRAM("SGRAM"),
+ VRAM("VRAM"),
+ PROM("PROM"),
+ EPROM("EPROM"),
+ FEPROM("FEPROM"),
+ EEPROM("EEPROM");
+
+ private String memoryType;
+
+ // Statically maps main memory types to enum types
+ private static final Map<String, MemoryType> MAP =
+ new HashMap<String, MemoryType>();
+ static {
+ for (MemoryType mt : MemoryType.values()) {
+ MAP.put(mt.toString().toLowerCase(), mt);
+ }
+ }
+
+ private MemoryType(String memoryType) {
+ this.memoryType = memoryType;
+ }
+
+ public static MemoryType getByName(String mt) {
+ return MAP.get(mt.toLowerCase());
+ }
+
+ public static boolean isRam(MemoryType memoryType) {
+ return (memoryType == DRAM) || (memoryType == SRAM);
+ }
+
+ public static boolean isRom(MemoryType memoryType) {
+ return !isRam(memoryType);
+ }
+
+ @Override
+ public String toString() {
+ return this.memoryType;
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/package-info.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/package-info.java
new file mode 100644
index 0000000..fc4c577
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/memory/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * API for a server's memory devices.
+ */
+package org.onosproject.drivers.server.devices.memory;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultDpdkNicFlowRule.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultDpdkNicFlowRule.java
index 4c2b7f0..34d70ee 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultDpdkNicFlowRule.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultDpdkNicFlowRule.java
@@ -26,13 +26,14 @@
public class DefaultDpdkNicFlowRule extends DefaultNicFlowRule {
public DefaultDpdkNicFlowRule(
- FlowRule flowRule,
- String trafficClassId,
- String interfaceName,
- long interfaceNumber,
- long cpuCoreIndex,
- NicRuleScope scope) {
- super(flowRule, trafficClassId, interfaceName, interfaceNumber, cpuCoreIndex, scope);
+ FlowRule flowRule,
+ String trafficClassId,
+ String interfaceName,
+ long interfaceNumber,
+ long cpuCoreIndex,
+ NicRuleScope scope) {
+ super(flowRule, trafficClassId, interfaceName,
+ interfaceNumber, cpuCoreIndex, scope);
}
@Override
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java
index dd56570..0f2b2b9 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java
@@ -45,6 +45,11 @@
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_CORE_ID_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_IFACE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_IFACE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_SCOPE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_TC_ID_NULL;
import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_TYPE;
import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_SRC;
import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_DST;
@@ -94,29 +99,25 @@
protected Set<NicRuleAction> actions;
protected DefaultNicFlowRule(
- FlowRule flowRule,
- String trafficClassId,
- String interfaceName,
- long interfaceNumber,
- long cpuCoreIndex,
- NicRuleScope scope) {
+ FlowRule flowRule,
+ String trafficClassId,
+ String interfaceName,
+ long interfaceNumber,
+ long cpuCoreIndex,
+ NicRuleScope scope) {
super(flowRule);
- checkArgument(!Strings.isNullOrEmpty(trafficClassId),
- "NIC rule's traffic class ID is NULL or empty");
- checkNotNull(interfaceName,
- "NIC rule's interface name is NULL");
- checkArgument(interfaceNumber >= 0,
- "NIC rule's interface number must not be negative");
- checkArgument(cpuCoreIndex >= 0,
- "NIC rule's CPU core index must not be negative");
- checkNotNull(scope, "NIC rule's scope is NULL");
+ checkArgument(!Strings.isNullOrEmpty(trafficClassId), MSG_NIC_FLOW_RULE_TC_ID_NULL);
+ checkNotNull(interfaceName, MSG_NIC_FLOW_RULE_IFACE_NULL);
+ checkArgument(interfaceNumber >= 0, MSG_NIC_FLOW_RULE_IFACE_NEGATIVE);
+ checkArgument(cpuCoreIndex >= 0, MSG_NIC_FLOW_RULE_CORE_ID_NEGATIVE);
+ checkNotNull(scope, MSG_NIC_FLOW_RULE_SCOPE_NULL);
- this.trafficClassId = trafficClassId;
- this.interfaceName = interfaceName;
+ this.trafficClassId = trafficClassId;
+ this.interfaceName = interfaceName;
this.interfaceNumber = interfaceNumber;
- this.cpuCoreIndex = cpuCoreIndex;
- this.scope = scope;
+ this.cpuCoreIndex = cpuCoreIndex;
+ this.scope = scope;
this.populate();
}
@@ -124,11 +125,11 @@
protected DefaultNicFlowRule(FlowRule flowRule) {
super(flowRule);
- this.trafficClassId = Builder.DEFAULT_TRAFFIC_CLASS_ID;
- this.interfaceName = "";
+ this.trafficClassId = Builder.DEFAULT_TRAFFIC_CLASS_ID;
+ this.interfaceName = "";
this.interfaceNumber = Builder.DEFAULT_INTERFACE_NB;
- this.cpuCoreIndex = Builder.DEFAULT_CPU_CORE_INDEX;
- this.scope = Builder.DEFAULT_RULE_SCOPE;
+ this.cpuCoreIndex = Builder.DEFAULT_CPU_CORE_INDEX;
+ this.scope = Builder.DEFAULT_RULE_SCOPE;
this.populate();
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java
index c2430c0..210a1e8 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java
@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.devices.nic;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_NULL;
/**
* A flow rule-based Rx filter value.
@@ -92,8 +95,7 @@
* @param value a CPU core ID for this Rx filter
*/
private void setValue(long value) {
- checkArgument(value >= 0,
- "NIC flow Rx filter has invalid CPU core ID");
+ checkArgument(value >= 0, MSG_NIC_FLOW_FILTER_NEGATIVE);
this.value = value;
}
@@ -112,8 +114,7 @@
* @param flowRule Flow Rx filter rule as a string
*/
public void setRule(String flowRule) {
- checkNotNull(flowRule,
- "NIC flow Rx filter rule is NULL");
+ checkNotNull(flowRule, MSG_NIC_FLOW_RULE_NULL);
this.flowRule = flowRule;
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java
index 25b28bb..772ddbd 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.devices.nic;
import org.onlab.packet.MacAddress;
@@ -20,6 +21,7 @@
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_MAC_NULL;
/**
* A MAC Rx filter value.
@@ -73,7 +75,7 @@
* @param mac MAC value
*/
public void setValue(MacAddress mac) {
- checkNotNull(mac, "MAC address of Rx filter is NULL");
+ checkNotNull(mac, MSG_NIC_FLOW_FILTER_MAC_NULL);
this.mac = mac;
}
@@ -122,7 +124,7 @@
@Override
public String toString() {
- return this.value().toString();
+ return this.value().toString();
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java
index ddc1930c..5c56a73 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.devices.nic;
import org.onlab.packet.MplsLabel;
@@ -20,6 +21,7 @@
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_MPLS_NULL;
/**
* An MPLS Rx filter value.
@@ -74,7 +76,7 @@
* @param mplsLabel MPLS label value
*/
public void setValue(MplsLabel mplsLabel) {
- checkNotNull(mplsLabel, "MPLS label of Rx filter is NULL");
+ checkNotNull(mplsLabel, MSG_NIC_FLOW_FILTER_MPLS_NULL);
this.mplsLabel = mplsLabel;
}
@@ -100,7 +102,7 @@
@Override
public String toString() {
- return this.value().toString();
+ return this.value().toString();
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicDevice.java
index c3de14e..511a5fb 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicDevice.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicDevice.java
@@ -22,11 +22,16 @@
/**
* Represents an abstraction of a
- * network interface card (NIC) device in ONOS.
+ * network interface card (NIC) device.
*/
public interface NicDevice extends Comparable {
/**
+ * Maximum link speed in Mbps.
+ */
+ static final long MAX_SPEED = 400000;
+
+ /**
* Returns the name of this NIC.
*
* @return NIC name
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleAction.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleAction.java
index ff3afeb..4f86178 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleAction.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleAction.java
@@ -23,7 +23,8 @@
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_ACTION_TYPE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_ACTION_VAL_NULL;
/**
* Definition of network interface card (NIC) rule action.
@@ -37,6 +38,7 @@
* Source: https://doc.dpdk.org/guides/prog_guide/rte_flow.html
*/
public enum Action {
+
/**
* Leaves traffic up for additional processing
* by subsequent flow rules.
@@ -229,16 +231,15 @@
public static final long NO_ACTION_VALUE = (long) -1;
public NicRuleAction(Action actionType, long actionValue) {
- checkNotNull(actionType, "NIC rule action type is NULL");
- checkArgument(actionValue >= 0,
- "NIC rule action " + actionType + " requires an action value");
+ checkNotNull(actionType, MSG_NIC_FLOW_RULE_ACTION_TYPE_NULL);
+ checkArgument(actionValue >= 0, MSG_NIC_FLOW_RULE_ACTION_VAL_NULL);
this.actionType = actionType;
this.actionValue = actionValue;
}
public NicRuleAction(Action actionType) {
- checkNotNull(actionType, "NIC rule action type is NULL");
+ checkNotNull(actionType, MSG_NIC_FLOW_RULE_ACTION_TYPE_NULL);
this.actionType = actionType;
this.actionValue = NO_ACTION_VALUE;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleScope.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleScope.java
index e9a89db..7a115ef 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleScope.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRuleScope.java
@@ -19,26 +19,26 @@
import com.google.common.base.Strings;
import static com.google.common.base.Preconditions.checkArgument;
-
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_RULE_SCOPE_NULL;
/**
* Definition of network interface card's (NIC) rule's scope.
*/
public enum NicRuleScope {
+
/**
- * A NIC rules is applied to the ingress traffic.
+ * A NIC rules is applied to ingress traffic.
*/
INGRESS("ingress"),
/**
- * A NIC rules is applied to the egress traffic.
+ * A NIC rules is applied to egress traffic.
*/
EGRESS("egress");
protected String scope;
private NicRuleScope(String scope) {
- checkArgument(!Strings.isNullOrEmpty(scope),
- "NIC rule scope is NULL or empty");
+ checkArgument(!Strings.isNullOrEmpty(scope), MSG_NIC_FLOW_RULE_SCOPE_NULL);
this.scope = scope.toLowerCase();
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRxFilter.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRxFilter.java
index e2d5758..bd094ad 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRxFilter.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicRxFilter.java
@@ -25,6 +25,8 @@
import java.util.HashMap;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_MECH_NULL;
/**
* Filtering mechanisms supported by a NIC device.
@@ -35,6 +37,7 @@
* Supported Rx filters.
*/
public enum RxFilter {
+
/**
* NIC dispatches traffic according to VLAN tags.
*/
@@ -102,7 +105,7 @@
}
public NicRxFilter(RxFilter rxFilter) {
- checkNotNull(rxFilter, "NIC Rx filter is NULL");
+ checkNotNull(rxFilter, MSG_NIC_FLOW_FILTER_NULL);
if (!ArrayUtils.contains(RxFilter.values(), rxFilter)) {
throw new IllegalArgumentException(String.valueOf(rxFilter));
@@ -113,7 +116,7 @@
}
public NicRxFilter(NicRxFilter other) {
- checkNotNull(other, "NIC Rx filter mechanism is NULL");
+ checkNotNull(other, MSG_NIC_FLOW_FILTER_MECH_NULL);
this.rxFilters = new HashSet<RxFilter>(other.rxFilters);
}
@@ -132,7 +135,7 @@
* @param rxFilter an Rx filter to be added
*/
public void addRxFilter(RxFilter rxFilter) {
- checkNotNull(rxFilter, "NIC Rx filter is NULL");
+ checkNotNull(rxFilter, MSG_NIC_FLOW_FILTER_NULL);
this.rxFilters.add(rxFilter);
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java
index 2d54a81..f43a6db 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.devices.nic;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_RSS_NEGATIVE;
/**
* A Receice-Side Scaling (RSS)-based Rx filter value.
@@ -72,7 +74,7 @@
* @param rssHash the RSS hash
*/
public void setValue(int rssHash) {
- checkArgument(rssHash >= 0, "Invalid RSS Rx filter " + rssHash);
+ checkArgument(rssHash >= 0, MSG_NIC_FLOW_FILTER_RSS_NEGATIVE);
this.rssHash = rssHash;
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java
index dceff82..8033fb3 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.devices.nic;
import java.util.Objects;
@@ -22,7 +23,9 @@
*/
public abstract class RxFilterValue {
- /* CPU id of the server this tag will lead to */
+ /**
+ * CPU ID of the server this tag will lead to.
+ */
protected int cpuId;
/**
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java
index 8e16321..ba6a2eb 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.devices.nic;
import org.onlab.packet.VlanId;
@@ -20,6 +21,7 @@
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_FLOW_FILTER_VLAN_NULL;
/**
* A VLAN Rx filter value.
@@ -73,7 +75,7 @@
* @param vlanId VLAN ID value
*/
public void setValue(VlanId vlanId) {
- checkNotNull(vlanId, "VLAN ID of Rx filter is NULL");
+ checkNotNull(vlanId, MSG_NIC_FLOW_FILTER_VLAN_NULL);
this.vlanId = vlanId;
}
@@ -99,7 +101,7 @@
@Override
public String toString() {
- return this.value().toString();
+ return this.value().toString();
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/package-info.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/package-info.java
index a2e5cf7..f1e55eb 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/package-info.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/package-info.java
@@ -15,6 +15,6 @@
*/
/**
- * API for NIC server devices.
+ * API for a server's NIC devices.
*/
package org.onosproject.drivers.server.devices.nic;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/BaseViewMessageHandler.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/BaseViewMessageHandler.java
index a2a151c..753a76e 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/BaseViewMessageHandler.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/BaseViewMessageHandler.java
@@ -37,8 +37,9 @@
import java.util.Set;
import java.util.stream.IntStream;
-import static org.slf4j.LoggerFactory.getLogger;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_UI_SUBMETRIC_NULL;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Base message handler for passing server data to the Web UI.
@@ -75,6 +76,13 @@
// Device IDs
public static final String DEVICE_IDS = "deviceIds";
+ protected static final Map<Integer, String> MEM_SUBMETRIC_MAP = new HashMap<Integer, String>();
+ static {
+ MEM_SUBMETRIC_MAP.put(0, "used");
+ MEM_SUBMETRIC_MAP.put(1, "free");
+ MEM_SUBMETRIC_MAP.put(2, "total");
+ }
+
// Chart designer
protected abstract class ControlMessageRequest extends ChartRequestHandler {
@@ -89,24 +97,39 @@
protected abstract void populateChart(ChartModel cm, ObjectNode payload);
/**
- * Returns a x-axis label for a monitoring value.
+ * Returns a x-axis label for a monitoring value based on a map of submetrics.
+ *
+ * @param metric label metric
+ * @param map a map of submetrics
+ * @param index submetric index
+ * @return a data label
+ */
+ protected String getMappedLabel(MetricType metric, Map<Integer, String> map, int index) {
+ String submetric = map.get(index);
+ checkNotNull(submetric, MSG_UI_SUBMETRIC_NULL);
+ return StringUtils.lowerCase(metric.name()) + "_" + submetric;
+ }
+
+ /**
+ * Returns a x-axis label for a monitoring value based on a simple index.
*
* @param metric label metric
* @param index label index
* @return a data label
*/
- protected String getLabel(MetricType metric, int index) {
+ protected String getIndexedLabel(MetricType metric, int index) {
return StringUtils.lowerCase(metric.name()) + "_" + Integer.toString(index);
}
/**
- * Fills an array of strings acting as x-axis.
+ * Fills an array of strings acting as x-axis based on a map of submetrics.
*
* @param metric x-axis metric
+ * @param map a map of submetrics
* @param length the length of the array
* @return an array of strings
*/
- protected String[] createSeries(MetricType metric, int length) {
+ protected String[] createMappedSeries(MetricType metric, Map<Integer, String> map, int length) {
if (length <= 0) {
return null;
}
@@ -116,7 +139,30 @@
}
String[] series = IntStream.range(0, length)
- .mapToObj(i -> getLabel(metric, i))
+ .mapToObj(i -> getMappedLabel(metric, map, i))
+ .toArray(String[]::new);
+
+ return series;
+ }
+
+ /**
+ * Fills an array of strings acting as x-axis based on a simple index.
+ *
+ * @param metric x-axis metric
+ * @param length the length of the array
+ * @return an array of strings
+ */
+ protected String[] createIndexedSeries(MetricType metric, int length) {
+ if (length <= 0) {
+ return null;
+ }
+
+ if (length > MAX_COLUMNS_NB) {
+ length = MAX_COLUMNS_NB;
+ }
+
+ String[] series = IntStream.range(0, length)
+ .mapToObj(i -> getIndexedLabel(metric, i))
.toArray(String[]::new);
return series;
@@ -127,11 +173,11 @@
*
* @param deviceId the device being monitored
* @param length the length of the array
- * @return a map monitoring parameters to their load history buffers
+ * @return a map of monitoring parameters to their load history buffers
*/
protected Map<Integer, LruCache<Float>> fetchCacheForDevice(DeviceId deviceId, int length) {
if (!isValid(deviceId, length - 1)) {
- log.error("Invalid access to data history by device {} with {} cores", deviceId, length);
+ log.error("Invalid access to data history by device {} with {} metrics", deviceId, length);
return null;
}
@@ -161,7 +207,7 @@
DeviceId deviceId, int length, int index, float value) {
if (!isValid(deviceId, length - 1) ||
!isValid(deviceId, index)) {
- log.error("Invalid access to data {} history by device {} with {} cores",
+ log.error("Invalid access to data {} history by device {} with {} metrics",
index, deviceId, length);
return;
}
@@ -172,7 +218,9 @@
checkNotNull(dataMap, "Failed to add measurement in the cache");
}
- dataMap.get(index).add(value);
+ if (dataMap.get(index) != null) {
+ dataMap.get(index).add(value);
+ }
}
/**
@@ -185,7 +233,7 @@
*/
protected LruCache<Float> getDataHistory(DeviceId deviceId, int index) {
if (!isValid(deviceId, index)) {
- log.error("Invalid access to CPU {} load history by device {}", index, deviceId);
+ log.error("Invalid access to index {} history by device {}", index, deviceId);
return null;
}
@@ -204,8 +252,8 @@
* @param length the length of the array
* @return a map of monitoring parameters to their initial values
*/
- protected Map<Integer, Float> populateZeroData(DeviceId deviceId, int length) {
- Map<Integer, Float> data = initializeData(length);
+ protected Map<Integer, Float> populateZeroMapData(DeviceId deviceId, int length) {
+ Map<Integer, Float> data = initializeMapData(length);
for (int i = 0; i < length; i++) {
// Store it locally
@@ -222,8 +270,8 @@
* @param length the length of the array
* @return a map of monitoring parameters to their initial arrays of values
*/
- protected Map<Integer, Float[]> populateZeroDataHistory(DeviceId deviceId, int length) {
- Map<Integer, Float[]> data = initializeDataHistory(length);
+ protected Map<Integer, Float[]> populateZeroMapDataHistory(DeviceId deviceId, int length) {
+ Map<Integer, Float[]> data = initializeMapDataHistory(length);
for (int i = 0; i < length; i++) {
addToCache(deviceId, length, i, 0);
@@ -254,7 +302,7 @@
* @param metric a metric
* @param numberOfPoints the number of data points
*/
- protected void populateMetrics(
+ protected void populateMapMetrics(
ChartModel cm,
Map<Integer, Float[]> data,
LocalDateTime time,
@@ -264,7 +312,7 @@
Map<String, Object> local = Maps.newHashMap();
for (int j = 0; j < data.size(); j++) {
if (data.containsKey(j)) {
- local.put(getLabel(metric, j), data.get(j)[i]);
+ local.put(getIndexedLabel(metric, j), data.get(j)[i]);
}
}
@@ -293,7 +341,7 @@
* @param length the length of the array
* @return a map of metrics to their initial values
*/
- protected Map<Integer, Float> initializeData(int length) {
+ protected Map<Integer, Float> initializeMapData(int length) {
Map<Integer, Float> data = Maps.newHashMap();
for (int i = 0; i < length; i++) {
@@ -304,12 +352,12 @@
}
/**
- * Create a data structure with zero-initialized arrays of data.
+ * Create a map data structure with zero-initialized arrays of data.
*
* @param length the length of the array
* @return a map of metrics to their initial arrays of values
*/
- protected Map<Integer, Float[]> initializeDataHistory(int length) {
+ protected Map<Integer, Float[]> initializeMapDataHistory(int length) {
Map<Integer, Float[]> data = Maps.newHashMap();
for (int i = 0; i < length; i++) {
@@ -372,7 +420,7 @@
ChartModel cm, MetricType metric, int length) {
Map<String, Object> local = Maps.newHashMap();
for (int i = 0; i < length; i++) {
- local.put(getLabel(metric, i), new Float(0));
+ local.put(getIndexedLabel(metric, i), new Float(0));
}
local.put(LABEL, "No Servers");
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/CpuViewMessageHandler.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/CpuViewMessageHandler.java
index 87be684..c0cc6b2 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/CpuViewMessageHandler.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/CpuViewMessageHandler.java
@@ -43,9 +43,10 @@
import java.util.Map;
import java.util.Set;
-import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.drivers.server.gui.MetricType.CPU;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_UI_DATA_CPU_NULL;
+import static org.onosproject.drivers.server.gui.MetricType.CPU;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Message handler for passing CPU load data to the Web UI.
@@ -63,7 +64,8 @@
return ImmutableSet.of(new CpuMessageRequest());
}
- private final class CpuMessageRequest extends BaseViewMessageHandler.ControlMessageRequest {
+ private final class CpuMessageRequest
+ extends BaseViewMessageHandler.ControlMessageRequest {
private CpuMessageRequest() {
super(CPU_DATA_REQ, CPU_DATA_RESP, CPUS_LABEL);
@@ -71,7 +73,7 @@
@Override
protected String[] getSeries() {
- return createSeries(CPU, MAX_COLUMNS_NB);
+ return createIndexedSeries(CPU, MAX_COLUMNS_NB);
}
@Override
@@ -96,15 +98,15 @@
cpuStats = new ArrayList(serverDriver.getCpuStatistics(deviceId));
data = populateCpuDataHistory(deviceId, serverDev.numberOfCpus(), cpuStats);
} catch (Exception ex) {
- data = populateZeroDataHistory(deviceId, MAX_COLUMNS_NB);
+ data = populateZeroMapDataHistory(deviceId, MAX_COLUMNS_NB);
}
- checkNotNull(data, "No CPU data history to visualize");
+ checkNotNull(data, MSG_UI_DATA_CPU_NULL);
// Generate a timestamp
LocalDateTime ldt = new LocalDateTime(timestamp);
// Project the data
- populateMetrics(cm, data, ldt, CPU, NUM_OF_DATA_POINTS);
+ populateMapMetrics(cm, data, ldt, CPU, NUM_OF_DATA_POINTS);
Set<DeviceId> deviceIds = Sets.newHashSet();
for (Device device : ds.getAvailableDevices()) {
@@ -133,14 +135,14 @@
cpuStats = new ArrayList(serverDriver.getCpuStatistics(deviceId));
data = populateCpuData(deviceId, serverDev.numberOfCpus(), cpuStats);
} catch (Exception ex) {
- data = populateZeroData(deviceId, MAX_COLUMNS_NB);
+ data = populateZeroMapData(deviceId, MAX_COLUMNS_NB);
}
- checkNotNull(data, "No CPU data to visualize");
+ checkNotNull(data, MSG_UI_DATA_CPU_NULL);
// Map them to the CPU cores
Map<String, Object> local = Maps.newHashMap();
for (int i = 0; i < data.size(); i++) {
- local.put(getLabel(CPU, i), data.get(i));
+ local.put(getIndexedLabel(CPU, i), data.get(i));
}
// Last piece of data is the device ID
@@ -166,7 +168,7 @@
*/
private Map<Integer, Float> populateCpuData(
DeviceId deviceId, int length, List<CpuStatistics> cpuStats) {
- Map<Integer, Float> data = initializeData(MAX_COLUMNS_NB);
+ Map<Integer, Float> data = initializeMapData(MAX_COLUMNS_NB);
for (CpuStatistics stats : cpuStats) {
int index = stats.id();
@@ -195,7 +197,7 @@
*/
private Map<Integer, Float[]> populateCpuDataHistory(
DeviceId deviceId, int length, List<CpuStatistics> cpuStats) {
- Map<Integer, Float[]> data = initializeDataHistory(MAX_COLUMNS_NB);
+ Map<Integer, Float[]> data = initializeMapDataHistory(MAX_COLUMNS_NB);
for (CpuStatistics stats : cpuStats) {
int index = stats.id();
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/LatencyViewMessageHandler.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/LatencyViewMessageHandler.java
index c76c97d..a1c29c3 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/LatencyViewMessageHandler.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/LatencyViewMessageHandler.java
@@ -43,9 +43,10 @@
import java.util.Map;
import java.util.Set;
-import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.drivers.server.gui.MetricType.LATENCY;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_UI_DATA_LATENCY_NULL;
+import static org.onosproject.drivers.server.gui.MetricType.LATENCY;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Message handler for passing latency data to the Web UI.
@@ -63,7 +64,8 @@
return ImmutableSet.of(new LatencyMessageRequest());
}
- private final class LatencyMessageRequest extends BaseViewMessageHandler.ControlMessageRequest {
+ private final class LatencyMessageRequest
+ extends BaseViewMessageHandler.ControlMessageRequest {
private LatencyMessageRequest() {
super(LATENCY_DATA_REQ, LATENCY_DATA_RESP, LATENCY_LABEL);
@@ -71,7 +73,7 @@
@Override
protected String[] getSeries() {
- return createSeries(LATENCY, MAX_COLUMNS_NB);
+ return createIndexedSeries(LATENCY, MAX_COLUMNS_NB);
}
@Override
@@ -93,17 +95,17 @@
Map<Integer, Float[]> data = null;
MonitoringStatistics monStats = serverDriver.getGlobalMonitoringStatistics(deviceId);
if (monStats == null) {
- data = populateZeroDataHistory(deviceId, MAX_COLUMNS_NB);
+ data = populateZeroMapDataHistory(deviceId, MAX_COLUMNS_NB);
} else {
data = populateLatencyDataHistory(deviceId, serverDev.numberOfCpus(), monStats);
}
- checkNotNull(data, "No latency data history to visualize");
+ checkNotNull(data, MSG_UI_DATA_LATENCY_NULL);
// Generate a timestamp
LocalDateTime ldt = new LocalDateTime(timestamp);
// Project the data
- populateMetrics(cm, data, ldt, LATENCY, NUM_OF_DATA_POINTS);
+ populateMapMetrics(cm, data, ldt, LATENCY, NUM_OF_DATA_POINTS);
Set<DeviceId> deviceIds = Sets.newHashSet();
for (Device device : ds.getAvailableDevices()) {
@@ -129,16 +131,16 @@
Map<Integer, Float> data = null;
MonitoringStatistics monStats = serverDriver.getGlobalMonitoringStatistics(deviceId);
if (monStats == null) {
- data = populateZeroData(deviceId, MAX_COLUMNS_NB);
+ data = populateZeroMapData(deviceId, MAX_COLUMNS_NB);
} else {
data = populateLatencyData(deviceId, serverDev.numberOfCpus(), monStats);
}
- checkNotNull(data, "No latency data to visualize");
+ checkNotNull(data, MSG_UI_DATA_LATENCY_NULL);
// Map them to the CPU cores
Map<String, Object> local = Maps.newHashMap();
for (int i = 0; i < data.size(); i++) {
- local.put(getLabel(LATENCY, i), data.get(i));
+ local.put(getIndexedLabel(LATENCY, i), data.get(i));
}
// Last piece of data is the device ID
@@ -164,7 +166,7 @@
*/
private Map<Integer, Float> populateLatencyData(
DeviceId deviceId, int length, MonitoringStatistics monStats) {
- Map<Integer, Float> data = initializeData(MAX_COLUMNS_NB);
+ Map<Integer, Float> data = initializeMapData(MAX_COLUMNS_NB);
for (CpuStatistics stats : monStats.cpuStatisticsAll()) {
int index = stats.id();
@@ -207,7 +209,7 @@
*/
private Map<Integer, Float[]> populateLatencyDataHistory(
DeviceId deviceId, int length, MonitoringStatistics monStats) {
- Map<Integer, Float[]> data = initializeDataHistory(MAX_COLUMNS_NB);
+ Map<Integer, Float[]> data = initializeMapDataHistory(MAX_COLUMNS_NB);
for (CpuStatistics stats : monStats.cpuStatisticsAll()) {
int index = stats.id();
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MemoryUI.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MemoryUI.java
new file mode 100644
index 0000000..7765b92
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MemoryUI.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.gui;
+
+import org.onosproject.ui.UiExtension;
+import org.onosproject.ui.UiExtensionService;
+import org.onosproject.ui.UiMessageHandlerFactory;
+import org.onosproject.ui.UiView;
+
+import com.google.common.collect.ImmutableList;
+
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+import static org.onosproject.ui.UiView.Category.NETWORK;
+import static org.onosproject.ui.GlyphConstants.ENDSTATION;
+
+/**
+ * Mechanism to stream main memory data to the GUI.
+ */
+@Component(immediate = true, service = MemoryUI.class)
+public class MemoryUI {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * GUI Information.
+ */
+ private static final String MEMORY_ID = "memory";
+ private static final String MEMORY_TEXT = "Servers-Memory";
+ private static final String RES_PATH = "gui";
+ private static final ClassLoader CL = MemoryUI.class.getClassLoader();
+
+ // Factory for UI message handlers
+ private final UiMessageHandlerFactory messageHandlerFactory =
+ () -> ImmutableList.of(new MemoryViewMessageHandler());
+
+ // List of application views
+ private final List<UiView> views = ImmutableList.of(
+ new UiView(NETWORK, MEMORY_ID, MEMORY_TEXT, ENDSTATION)
+ );
+
+ // Application UI extension
+ private final UiExtension uiExtension =
+ new UiExtension.Builder(CL, views)
+ .messageHandlerFactory(messageHandlerFactory)
+ .resourcePath(RES_PATH)
+ .build();
+
+ /**
+ * Interact with ONOS.
+ */
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected UiExtensionService uiExtensionService;
+
+ @Activate
+ protected void activate() {
+ uiExtensionService.register(uiExtension);
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ uiExtensionService.unregister(uiExtension);
+ log.info("Stopped");
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MemoryViewMessageHandler.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MemoryViewMessageHandler.java
new file mode 100644
index 0000000..6bd8b2c
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MemoryViewMessageHandler.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.gui;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.primitives.Floats;
+
+import org.onosproject.drivers.server.behavior.MonitoringStatisticsDiscovery;
+import org.onosproject.drivers.server.devices.RestServerSBDevice;
+import org.onosproject.drivers.server.stats.MemoryStatistics;
+import org.onosproject.drivers.server.stats.MonitoringStatistics;
+import org.onosproject.drivers.server.stats.MonitoringUnit.CapacityUnit;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.chart.ChartModel;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.joda.time.LocalDateTime;
+import org.slf4j.Logger;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_UI_DATA_MEMORY_NULL;
+import static org.onosproject.drivers.server.gui.MetricType.MEMORY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Message handler for passing memory data to the Web UI.
+ */
+public class MemoryViewMessageHandler extends BaseViewMessageHandler {
+
+ private static final Logger log = getLogger(MemoryViewMessageHandler.class);
+
+ private static final String MEMORY_DATA_REQ = "memoryDataRequest";
+ private static final String MEMORY_DATA_RESP = "memoryDataResponse";
+ private static final String MEMORY_LABEL = "memorys";
+
+ @Override
+ protected Collection<RequestHandler> createRequestHandlers() {
+ return ImmutableSet.of(new MemoryMessageRequest());
+ }
+
+ private final class MemoryMessageRequest
+ extends BaseViewMessageHandler.ControlMessageRequest {
+
+ // Memory UI has 3 columns (used, free, and total memory)
+ public static final int MEM_COLUMNS_NB = 3;
+
+ private MemoryMessageRequest() {
+ super(MEMORY_DATA_REQ, MEMORY_DATA_RESP, MEMORY_LABEL);
+ }
+
+ @Override
+ protected String[] getSeries() {
+ return createMappedSeries(MEMORY, MEM_SUBMETRIC_MAP, MEM_COLUMNS_NB);
+ }
+
+ @Override
+ protected void populateChart(ChartModel cm, ObjectNode payload) {
+ DeviceService ds = get(DeviceService.class);
+ if ((ds == null) || (ds.getAvailableDeviceCount() == 0)) {
+ fillDataWhenNoDevicePresent(cm, MEMORY, MEM_COLUMNS_NB);
+ return;
+ }
+
+ String uri = string(payload, "devId");
+
+ // Project only one device over time
+ if (!Strings.isNullOrEmpty(uri)) {
+ DeviceId deviceId = DeviceId.deviceId(uri);
+ RestServerSBDevice serverDev =
+ (RestServerSBDevice) basicDriver.getController().getDevice(deviceId);
+
+ Map<Integer, Float[]> data = null;
+ MonitoringStatistics monStats = serverDriver.getGlobalMonitoringStatistics(deviceId);
+ if (monStats == null) {
+ data = populateZeroMapDataHistory(deviceId, MEM_COLUMNS_NB);
+ } else {
+ data = populateMemoryDataHistory(deviceId, MEM_COLUMNS_NB, monStats);
+ }
+ checkNotNull(data, MSG_UI_DATA_MEMORY_NULL);
+
+ // Generate a timestamp
+ LocalDateTime ldt = new LocalDateTime(timestamp);
+
+ // Project the data
+ populateMapMetrics(cm, data, ldt, MEMORY, NUM_OF_DATA_POINTS);
+
+ Set<DeviceId> deviceIds = Sets.newHashSet();
+ for (Device device : ds.getAvailableDevices()) {
+ // Only devices that support this type of monitoring behaviour are considered
+ if (device.is(MonitoringStatisticsDiscovery.class) && serverDev.isActive()) {
+ deviceIds.add(device.id());
+ }
+ }
+
+ // Drop down list to select devices
+ attachDeviceList(cm, deviceIds);
+ } else {
+ for (Device device : ds.getAvailableDevices()) {
+ // Only devices that support this type of monitoring behaviour are considered
+ if (!device.is(MonitoringStatisticsDiscovery.class)) {
+ continue;
+ }
+
+ DeviceId deviceId = device.id();
+ RestServerSBDevice serverDev =
+ (RestServerSBDevice) basicDriver.getController().getDevice(deviceId);
+
+ Map<Integer, Float> data = null;
+ MonitoringStatistics monStats = serverDriver.getGlobalMonitoringStatistics(deviceId);
+ if (monStats == null) {
+ data = populateZeroMapData(deviceId, MEM_COLUMNS_NB);
+ } else {
+ data = populateMemoryData(deviceId, MEM_COLUMNS_NB, monStats);
+ }
+ checkNotNull(data, MSG_UI_DATA_MEMORY_NULL);
+
+ // Map them to the memory submetrics
+ Map<String, Object> local = Maps.newHashMap();
+ for (int i = 0; i < data.size(); i++) {
+ local.put(getMappedLabel(MEMORY, MEM_SUBMETRIC_MAP, i), data.get(i));
+ }
+
+ // Last piece of data is the device ID
+ if (serverDev.isActive()) {
+ local.put(LABEL, deviceId);
+ populateMetric(cm.addDataPoint(deviceId), local);
+ } else {
+ local.put(LABEL, "");
+ populateMetric(cm.addDataPoint(""), local);
+ }
+ }
+ }
+ }
+
+ /**
+ * Turn the current monitoring data into a data
+ * structure that can feed the Memory UI memory.
+ *
+ * @param deviceId the device ID being monitored
+ * @param length the length of the array
+ * @param monStats a MonitoringStatistics object
+ * @return a map of memory metrics to their values
+ */
+ private Map<Integer, Float> populateMemoryData(
+ DeviceId deviceId, int length, MonitoringStatistics monStats) {
+ Map<Integer, Float> data = initializeMapData(MEM_COLUMNS_NB);
+
+ MemoryStatistics memStats = monStats.memoryStatistics();
+
+ CapacityUnit capacityUnit = (CapacityUnit) memStats.unit();
+ Float used = new Float(memStats.used());
+ Float free = new Float(memStats.free());
+ Float total = new Float(memStats.total());
+
+ // Unit conversions
+ used = CapacityUnit.toGigaBytes(used, capacityUnit);
+ free = CapacityUnit.toGigaBytes(free, capacityUnit);
+ total = CapacityUnit.toGigaBytes(total, capacityUnit);
+
+ // Store them locally
+ addToCache(deviceId, length, 0, used);
+ addToCache(deviceId, length, 1, free);
+ addToCache(deviceId, length, 2, total);
+
+ // And into the map
+ data.put(0, used);
+ data.put(1, free);
+ data.put(2, total);
+
+ return data;
+ }
+
+ /**
+ * Turn the monitoring data history into a
+ * data structure that can feed the Memory UI memory.
+ *
+ * @param deviceId the device ID being monitored
+ * @param length the length of the array
+ * @param monStats a MonitoringStatistics object
+ * @return a map of memory metrics to their arrays of values
+ */
+ private Map<Integer, Float[]> populateMemoryDataHistory(
+ DeviceId deviceId, int length, MonitoringStatistics monStats) {
+ Map<Integer, Float[]> data = initializeMapDataHistory(MEM_COLUMNS_NB);
+
+ MemoryStatistics memStats = monStats.memoryStatistics();
+
+ CapacityUnit capacityUnit = (CapacityUnit) memStats.unit();
+ Float used = new Float(memStats.used());
+ Float free = new Float(memStats.free());
+ Float total = new Float(memStats.total());
+
+ // Unit conversions
+ used = CapacityUnit.toGigaBytes(used, capacityUnit);
+ free = CapacityUnit.toGigaBytes(free, capacityUnit);
+ total = CapacityUnit.toGigaBytes(total, capacityUnit);
+
+ // Store them locally
+ addToCache(deviceId, length, 0, used);
+ addToCache(deviceId, length, 1, free);
+ addToCache(deviceId, length, 2, total);
+
+ for (int i = 0; i < length; i++) {
+ LruCache<Float> loadCache = getDataHistory(deviceId, i);
+ if (loadCache == null) {
+ continue;
+ }
+ float[] floatArray = Floats.toArray(Arrays.asList(loadCache.values().toArray(new Float[0])));
+
+ // Fill the missing points
+ float[] filledLoadArray = fillData(floatArray, NUM_OF_DATA_POINTS);
+
+ // Set the data
+ data.put(i, ArrayUtils.toObject(filledLoadArray));
+ }
+
+ // Keep a timestamp
+ timestamp = System.currentTimeMillis();
+
+ return data;
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MetricType.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MetricType.java
index 841b83e..69a3cd8 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MetricType.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/MetricType.java
@@ -22,11 +22,16 @@
public enum MetricType {
/**
- * CPU cores of a commodity server.
+ * A commodity server's CPU cores.
*/
CPU,
/**
+ * A commodity server's main memory.
+ */
+ MEMORY,
+
+ /**
* Per core latency.
*/
LATENCY,
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/ThroughputViewMessageHandler.java b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/ThroughputViewMessageHandler.java
index 91105e9..512aa95 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/gui/ThroughputViewMessageHandler.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/gui/ThroughputViewMessageHandler.java
@@ -43,9 +43,10 @@
import java.util.Map;
import java.util.Set;
-import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.drivers.server.gui.MetricType.THROUGHPUT;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_UI_DATA_THROUGHPUT_NULL;
+import static org.onosproject.drivers.server.gui.MetricType.THROUGHPUT;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Message handler for passing throughput data to the Web UI.
@@ -63,7 +64,8 @@
return ImmutableSet.of(new ThroughputMessageRequest());
}
- private final class ThroughputMessageRequest extends BaseViewMessageHandler.ControlMessageRequest {
+ private final class ThroughputMessageRequest
+ extends BaseViewMessageHandler.ControlMessageRequest {
private ThroughputMessageRequest() {
super(THROUGHPUT_DATA_REQ, THROUGHPUT_DATA_RESP, THROUGHPUT_LABEL);
@@ -71,7 +73,7 @@
@Override
protected String[] getSeries() {
- return createSeries(THROUGHPUT, MAX_COLUMNS_NB);
+ return createIndexedSeries(THROUGHPUT, MAX_COLUMNS_NB);
}
@Override
@@ -93,17 +95,17 @@
Map<Integer, Float[]> data = null;
MonitoringStatistics monStats = serverDriver.getGlobalMonitoringStatistics(deviceId);
if (monStats == null) {
- data = populateZeroDataHistory(deviceId, MAX_COLUMNS_NB);
+ data = populateZeroMapDataHistory(deviceId, MAX_COLUMNS_NB);
} else {
data = populateThroughputDataHistory(deviceId, serverDev.numberOfCpus(), monStats);
}
- checkNotNull(data, "No throughput data history to visualize");
+ checkNotNull(data, MSG_UI_DATA_THROUGHPUT_NULL);
// Generate a timestamp
LocalDateTime ldt = new LocalDateTime(timestamp);
// Project the data
- populateMetrics(cm, data, ldt, THROUGHPUT, NUM_OF_DATA_POINTS);
+ populateMapMetrics(cm, data, ldt, THROUGHPUT, NUM_OF_DATA_POINTS);
Set<DeviceId> deviceIds = Sets.newHashSet();
for (Device device : ds.getAvailableDevices()) {
@@ -129,16 +131,16 @@
Map<Integer, Float> data = null;
MonitoringStatistics monStats = serverDriver.getGlobalMonitoringStatistics(deviceId);
if (monStats == null) {
- data = populateZeroData(deviceId, MAX_COLUMNS_NB);
+ data = populateZeroMapData(deviceId, MAX_COLUMNS_NB);
} else {
data = populateThroughputData(deviceId, serverDev.numberOfCpus(), monStats);
}
- checkNotNull(data, "No throughput data to visualize");
+ checkNotNull(data, MSG_UI_DATA_THROUGHPUT_NULL);
// Map them to the CPU cores
Map<String, Object> local = Maps.newHashMap();
for (int i = 0; i < data.size(); i++) {
- local.put(getLabel(THROUGHPUT, i), data.get(i));
+ local.put(getIndexedLabel(THROUGHPUT, i), data.get(i));
}
// Last piece of data is the device ID
@@ -164,7 +166,7 @@
*/
private Map<Integer, Float> populateThroughputData(
DeviceId deviceId, int length, MonitoringStatistics monStats) {
- Map<Integer, Float> data = initializeData(MAX_COLUMNS_NB);
+ Map<Integer, Float> data = initializeMapData(MAX_COLUMNS_NB);
for (CpuStatistics stats : monStats.cpuStatisticsAll()) {
int index = stats.id();
@@ -206,7 +208,7 @@
*/
private Map<Integer, Float[]> populateThroughputDataHistory(
DeviceId deviceId, int length, MonitoringStatistics monStats) {
- Map<Integer, Float[]> data = initializeDataHistory(MAX_COLUMNS_NB);
+ Map<Integer, Float[]> data = initializeMapDataHistory(MAX_COLUMNS_NB);
for (CpuStatistics stats : monStats.cpuStatisticsAll()) {
int index = stats.id();
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultBasicCpuCacheDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultBasicCpuCacheDevice.java
new file mode 100644
index 0000000..b6dcb70
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultBasicCpuCacheDevice.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.cpu.BasicCpuCacheDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheId;
+import org.onosproject.drivers.server.devices.cpu.CpuCachePlacementPolicy;
+import org.onosproject.drivers.server.devices.cpu.CpuVendor;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_CAPACITY_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_LINE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_POLICY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_SETS_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_WAYS_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_VENDOR_NULL;
+
+/**
+ * Default implementation for basic CPU cache devices.
+ */
+public final class DefaultBasicCpuCacheDevice implements BasicCpuCacheDevice {
+
+ private final CpuCacheId cacheId;
+ private final CpuCachePlacementPolicy policy;
+ private final CpuVendor vendor;
+ private final long capacity;
+ private final int sets;
+ private final int lineLength;
+ private final int ways;
+ private final boolean isShared;
+
+ private DefaultBasicCpuCacheDevice(CpuCacheId cacheId,
+ CpuCachePlacementPolicy policy,
+ CpuVendor vendor,
+ long capacity,
+ int sets,
+ int ways,
+ int lineLength,
+ boolean isShared) {
+ checkNotNull(cacheId, MSG_CPU_CACHE_ID_NULL);
+ checkNotNull(policy, MSG_CPU_CACHE_POLICY_NULL);
+ checkNotNull(vendor, MSG_CPU_VENDOR_NULL);
+ checkArgument(capacity > 0, MSG_CPU_CACHE_CAPACITY_NEGATIVE);
+ checkArgument(sets > 0, MSG_CPU_CACHE_SETS_NEGATIVE);
+ checkArgument(lineLength > 0, MSG_CPU_CACHE_LINE_NEGATIVE);
+ checkArgument(ways > 0, MSG_CPU_CACHE_WAYS_NEGATIVE);
+
+ this.cacheId = cacheId;
+ this.policy = policy;
+ this.vendor = vendor;
+ this.capacity = capacity;
+ this.sets = sets;
+ this.ways = ways;
+ this.lineLength = lineLength;
+ this.isShared = isShared;
+ }
+
+ /**
+ * Creates a builder for DefaultBasicCpuCacheDevice object.
+ *
+ * @return builder object for DefaultBasicCpuCacheDevice object
+ */
+ public static DefaultBasicCpuCacheDevice.Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public CpuCacheId cacheId() {
+ return cacheId;
+ }
+
+ @Override
+ public CpuCachePlacementPolicy policy() {
+ return policy;
+ }
+
+ @Override
+ public CpuVendor vendor() {
+ return vendor;
+ }
+
+ @Override
+ public long capacity() {
+ return capacity;
+ }
+
+ @Override
+ public int sets() {
+ return sets;
+ }
+
+ @Override
+ public int associativityWays() {
+ return ways;
+ }
+
+ @Override
+ public int lineLength() {
+ return lineLength;
+ }
+
+ @Override
+ public boolean isShared() {
+ return isShared;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("cacheId", cacheId())
+ .add("policy", policy())
+ .add("vendor", vendor())
+ .add("capacity", capacity())
+ .add("sets", sets())
+ .add("ways", associativityWays())
+ .add("lineLength", lineLength())
+ .add("isShared", isShared())
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof BasicCpuCacheDevice)) {
+ return false;
+ }
+ BasicCpuCacheDevice device = (BasicCpuCacheDevice) obj;
+ return this.cacheId() == device.cacheId() &&
+ this.policy() == device.policy() &&
+ this.vendor() == device.vendor() &&
+ this.capacity() == device.capacity() &&
+ this.sets() == device.sets() &&
+ this.associativityWays() == device.associativityWays() &&
+ this.lineLength() == device.lineLength() &&
+ this.isShared() == device.isShared();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(cacheId, policy, vendor, capacity, sets, ways, lineLength, isShared);
+ }
+
+ public static final class Builder {
+
+ CpuCacheId cacheId = null;
+ CpuCachePlacementPolicy policy = null;
+ CpuVendor vendor = null;
+ long capacity = -1;
+ int sets = -1;
+ int ways = -1;
+ int lineLength = -1;
+ boolean isShared = false;
+
+ private Builder() {
+
+ }
+
+ /**
+ * Sets CPU cache vendor.
+ *
+ * @param vendorStr CPU cache vendor as a string
+ * @return builder object
+ */
+ public Builder setVendor(String vendorStr) {
+ if (!Strings.isNullOrEmpty(vendorStr)) {
+ this.vendor = CpuVendor.getByName(vendorStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets CPU cache ID.
+ *
+ * @param levelStr CPU cache level as a string
+ * @param typeStr CPU cache type as a string
+ * @return builder object
+ */
+ public Builder setCacheId(String levelStr, String typeStr) {
+ if (!Strings.isNullOrEmpty(levelStr) && !Strings.isNullOrEmpty(typeStr)) {
+ this.cacheId = CpuCacheId.builder()
+ .setLevel(levelStr)
+ .setType(typeStr)
+ .build();
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets CPU cache policy.
+ *
+ * @param policyStr CPU cache policy as a string
+ * @return builder object
+ */
+ public Builder setPolicy(String policyStr) {
+ if (!Strings.isNullOrEmpty(policyStr)) {
+ this.policy = CpuCachePlacementPolicy.getByName(policyStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the CPU cache capacity.
+ *
+ * @param capacity CPU cache capacity
+ * @return builder object
+ */
+ public Builder setCapacity(long capacity) {
+ this.capacity = capacity;
+ return this;
+ }
+
+ /**
+ * Sets the CPU cache sets.
+ *
+ * @param sets CPU cache sets
+ * @return builder object
+ */
+ public Builder setNumberOfSets(int sets) {
+ this.sets = sets;
+ return this;
+ }
+
+ /**
+ * Sets the associativity ways of the CPU cache.
+ *
+ * @param ways CPU cache ways
+ * @return builder object
+ */
+ public Builder setNumberOfWays(int ways) {
+ this.ways = ways;
+ return this;
+ }
+
+ /**
+ * Sets the length of the CPU cache line.
+ *
+ * @param lineLength CPU cache line length
+ * @return builder object
+ */
+ public Builder setLineLength(int lineLength) {
+ this.lineLength = lineLength;
+ return this;
+ }
+
+ /**
+ * Sets whether this CPU cache is shared or not.
+ *
+ * @param isShared CPU cache sharing status
+ * @return builder object
+ */
+ public Builder isShared(boolean isShared) {
+ this.isShared = isShared;
+ return this;
+ }
+
+ /**
+ * Creates a DefaultBasicCpuCacheDevice object.
+ *
+ * @return DefaultBasicCpuCacheDevice object
+ */
+ public DefaultBasicCpuCacheDevice build() {
+ return new DefaultBasicCpuCacheDevice(
+ cacheId, policy, vendor, capacity,
+ sets, ways, lineLength, isShared);
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuCacheHierarchyDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuCacheHierarchyDevice.java
new file mode 100644
index 0000000..7782dfa
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuCacheHierarchyDevice.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.cpu.BasicCpuCacheDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheHierarchyDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheId;
+import org.onosproject.drivers.server.devices.cpu.CpuCoreId;
+import org.onosproject.drivers.server.devices.cpu.CpuVendor;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_CAPACITY_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_CAPACITY_CORE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_CAPACITY_LLC_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_CAPACITY_TOTAL_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_HIERARCHY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_INSERTION_FAILED;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_LEVELS_EXCEEDED;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_LEVELS_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CORES_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_SOCKETS_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_VENDOR_NULL;
+
+/**
+ * Default implementation for a CPU cache hierarchy.
+ */
+public final class DefaultCpuCacheHierarchyDevice implements CpuCacheHierarchyDevice {
+
+ private final CpuVendor vendor;
+ private final int socketsNb;
+ private final int coresNb;
+ private final int levels;
+ private final long perCoreCapacity;
+ private final long llcCapacity;
+ private final long totalCapacity;
+ private Map<CpuCacheId, BasicCpuCacheDevice> cacheHierarchy;
+
+ /**
+ * Maximum number of CPU cache levels.
+ */
+ public static final int MAX_CPU_CACHE_LEVELS = 4;
+
+ private DefaultCpuCacheHierarchyDevice(
+ CpuVendor vendor,
+ int socketsNb,
+ int coresNb,
+ int levels,
+ long perCoreCapacity,
+ long llcCapacity,
+ Map<CpuCacheId, BasicCpuCacheDevice> cacheHierarchy) {
+ checkNotNull(vendor, MSG_CPU_VENDOR_NULL);
+ checkArgument(socketsNb > 0, MSG_CPU_SOCKETS_NEGATIVE);
+ checkArgument((coresNb > 0) && (coresNb < CpuCoreId.MAX_CPU_CORE_NB),
+ MSG_CPU_CORES_NEGATIVE);
+ checkArgument((levels > 0) && (levels <= MAX_CPU_CACHE_LEVELS),
+ MSG_CPU_CACHE_LEVELS_NEGATIVE);
+ checkArgument(perCoreCapacity > 0, MSG_CPU_CACHE_CAPACITY_CORE_NEGATIVE);
+ checkArgument(llcCapacity > 0, MSG_CPU_CACHE_CAPACITY_LLC_NEGATIVE);
+ checkNotNull(cacheHierarchy, MSG_CPU_CACHE_HIERARCHY_NULL);
+
+ this.vendor = vendor;
+ this.socketsNb = socketsNb;
+ this.coresNb = coresNb;
+ this.levels = levels;
+ this.perCoreCapacity = perCoreCapacity;
+ this.llcCapacity = llcCapacity;
+
+ // The total capacity is the sum of the (shared) socket-level and the per-core capacities
+ this.totalCapacity = (socketsNb * llcCapacity) + (coresNb * perCoreCapacity);
+ checkArgument((this.totalCapacity > this.perCoreCapacity) &&
+ (this.totalCapacity > this.llcCapacity),
+ MSG_CPU_CACHE_CAPACITY_TOTAL_NEGATIVE);
+ this.cacheHierarchy = cacheHierarchy;
+ }
+
+ /**
+ * Creates a builder for DefaultCpuCacheHierarchyDevice object.
+ *
+ * @return builder object for DefaultCpuCacheHierarchyDevice object
+ */
+ public static DefaultCpuCacheHierarchyDevice.Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public CpuVendor vendor() {
+ return this.vendor;
+ }
+
+ @Override
+ public int socketsNb() {
+ return this.socketsNb;
+ }
+
+ @Override
+ public int coresNb() {
+ return this.coresNb;
+ }
+
+ @Override
+ public int levels() {
+ return this.levels;
+ }
+
+ @Override
+ public long perCoreCapacity() {
+ return this.perCoreCapacity;
+ }
+
+ @Override
+ public long llcCapacity() {
+ return this.llcCapacity;
+ }
+
+ @Override
+ public long totalCapacity() {
+ return this.totalCapacity;
+ }
+
+ @Override
+ public Map<CpuCacheId, BasicCpuCacheDevice> cacheHierarchy() {
+ return cacheHierarchy;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("vendor", vendor())
+ .add("socketsNb", socketsNb())
+ .add("coresNb", coresNb())
+ .add("levels", levels())
+ .add("perCoreCapacity", perCoreCapacity())
+ .add("llcCapacity", llcCapacity())
+ .add("totalCapacity", totalCapacity())
+ .add("cacheHierarchy", cacheHierarchy())
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof CpuCacheHierarchyDevice)) {
+ return false;
+ }
+ CpuCacheHierarchyDevice device = (CpuCacheHierarchyDevice) obj;
+ return this.vendor() == device.vendor() &&
+ this.socketsNb() == device.socketsNb() &&
+ this.coresNb() == device.coresNb() &&
+ this.levels() == device.levels() &&
+ this.perCoreCapacity() == device.perCoreCapacity() &&
+ this.llcCapacity() == device.llcCapacity() &&
+ this.totalCapacity() == device.totalCapacity() &&
+ this.cacheHierarchy() == device.cacheHierarchy();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(vendor, socketsNb, coresNb, levels, perCoreCapacity,
+ llcCapacity, totalCapacity, cacheHierarchy);
+ }
+
+ public static final class Builder {
+
+ CpuVendor vendor = null;
+ int socketsNb = -1;
+ int coresNb = -1;
+ int levels = -1;
+ long perCoreCapacity = 0;
+ long llcCapacity = 0;
+ Map<CpuCacheId, BasicCpuCacheDevice> cacheHierarchy =
+ new HashMap<CpuCacheId, BasicCpuCacheDevice>();
+
+ private Builder() {
+
+ }
+
+ /**
+ * Sets the number of CPU sockets.
+ *
+ * @param socketsNb number of CPU sockets
+ * @return builder object
+ */
+ public Builder setSocketsNumber(int socketsNb) {
+ this.socketsNb = socketsNb;
+ return this;
+ }
+
+ /**
+ * Sets the number of CPU cores.
+ *
+ * @param coresNb number of CPU cores
+ * @return builder object
+ */
+ public Builder setCoresNumber(int coresNb) {
+ this.coresNb = coresNb;
+ return this;
+ }
+
+ /**
+ * Sets the number of CPU cache levels.
+ *
+ * @param levels number of CPU cache levels
+ * @return builder object
+ */
+ public Builder setLevels(int levels) {
+ this.levels = levels;
+ return this;
+ }
+
+ /**
+ * Add a basic CPU cache device into this hierarchy.
+ *
+ * @param cacheDev a new basic CPU cache device
+ * @return builder object
+ */
+ public Builder addBasicCpuCacheDevice(BasicCpuCacheDevice cacheDev) {
+ checkNotNull(cacheDev, "Basic CPU cache device is null");
+ int currentSize = this.cacheHierarchy.size();
+ this.cacheHierarchy.put(cacheDev.cacheId(), cacheDev);
+ checkArgument(this.cacheHierarchy.size() == currentSize + 1,
+ MSG_CPU_CACHE_INSERTION_FAILED);
+ checkArgument(this.cacheHierarchy.size() <= MAX_CPU_CACHE_LEVELS,
+ MSG_CPU_CACHE_LEVELS_EXCEEDED);
+
+ if (this.vendor == null) {
+ this.vendor = cacheDev.vendor();
+ }
+
+ long capacity = cacheDev.capacity();
+ checkArgument(capacity > 0, MSG_CPU_CACHE_CAPACITY_NEGATIVE);
+ if (cacheDev.isShared()) {
+ this.llcCapacity = capacity;
+ } else {
+ this.perCoreCapacity += capacity;
+ }
+
+ return this;
+ }
+
+ /**
+ * Creates a DefaultCpuCacheHierarchyDevice object.
+ *
+ * @return DefaultCpuCacheHierarchyDevice object
+ */
+ public DefaultCpuCacheHierarchyDevice build() {
+ return new DefaultCpuCacheHierarchyDevice(
+ vendor, socketsNb, coresNb, levels,
+ perCoreCapacity, llcCapacity, cacheHierarchy);
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java
index 79712fc..9b1caaa 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java
@@ -16,53 +16,57 @@
package org.onosproject.drivers.server.impl.devices;
-import org.onosproject.drivers.server.devices.CpuDevice;
-import org.onosproject.drivers.server.devices.CpuVendor;
-
-import org.onosproject.drivers.server.impl.stats.DefaultCpuStatistics;
+import org.onosproject.drivers.server.devices.cpu.CpuCoreId;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuVendor;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+
+import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.Objects;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CORE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_FREQUENCY_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_SOCKET_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_VENDOR_NULL;
/**
* Default implementation for CPU core devices.
*/
-public class DefaultCpuDevice implements CpuDevice {
+public final class DefaultCpuDevice implements CpuDevice {
- private final int id;
+ private final CpuCoreId id;
private final CpuVendor vendor;
- private final long frequency;
+ private final int socket;
+ private final long frequency;
- // Maximum CPU core frequency in MHz
- public static final long MAX_FREQUENCY_MHZ = 4500;
+ private DefaultCpuDevice(CpuCoreId id, CpuVendor vendor, int socket, long frequency) {
+ checkNotNull(id, MSG_CPU_CORE_ID_NULL);
+ checkNotNull(vendor, MSG_CPU_VENDOR_NULL);
+ checkArgument((socket >= 0) && (socket < CpuCoreId.MAX_CPU_SOCKET_NB),
+ MSG_CPU_SOCKET_NEGATIVE);
+ checkArgument((frequency > 0) && (frequency <= CpuDevice.MAX_FREQUENCY_MHZ),
+ MSG_CPU_FREQUENCY_NEGATIVE);
- public DefaultCpuDevice(int id, CpuVendor vendor, long frequency) {
- checkArgument(
- (id >= 0) && (id < DefaultCpuStatistics.MAX_CPU_NB),
- "CPU core ID must be in [0, " +
- String.valueOf(DefaultCpuStatistics.MAX_CPU_NB - 1) + "]"
- );
- checkNotNull(
- vendor,
- "CPU core vendor cannot be null"
- );
- checkArgument(
- (frequency > 0) && (frequency <= MAX_FREQUENCY_MHZ),
- "CPU core frequency (MHz) must be positive and less or equal than " +
- MAX_FREQUENCY_MHZ + " MHz"
- );
-
- this.id = id;
- this.vendor = vendor;
+ this.id = id;
+ this.vendor = vendor;
+ this.socket = socket;
this.frequency = frequency;
}
+ /**
+ * Creates a builder for DefaultCpuDevice object.
+ *
+ * @return builder object for DefaultCpuDevice object
+ */
+ public static DefaultCpuDevice.Builder builder() {
+ return new Builder();
+ }
+
@Override
- public int id() {
+ public CpuCoreId id() {
return this.id;
}
@@ -72,6 +76,11 @@
}
@Override
+ public int socket() {
+ return this.socket;
+ }
+
+ @Override
public long frequency() {
return this.frequency;
}
@@ -82,6 +91,7 @@
.omitNullValues()
.add("id", id())
.add("vendor", vendor())
+ .add("socket", socket())
.add("frequency", frequency())
.toString();
}
@@ -97,12 +107,85 @@
CpuDevice device = (CpuDevice) obj;
return this.id() == device.id() &&
this.vendor() == device.vendor() &&
+ this.socket() == device.socket() &&
this.frequency() == device.frequency();
}
@Override
public int hashCode() {
- return Objects.hash(id, vendor, frequency);
+ return Objects.hash(id, vendor, socket, frequency);
+ }
+
+ public static final class Builder {
+ CpuCoreId id = null;
+ CpuVendor vendor = null;
+ int socket = -1;
+ long frequency = -1;
+
+ private Builder() {
+
+ }
+
+ /**
+ * Sets the CPU core ID of this CPU.
+ *
+ * @param logicalCoreId logical CPU core ID
+ * @param physicalCoreId physical CPU core ID
+ * @return builder object
+ */
+ public Builder setCoreId(int logicalCoreId, int physicalCoreId) {
+ this.id = new CpuCoreId(logicalCoreId, physicalCoreId);
+
+ return this;
+ }
+
+ /**
+ * Sets the CPU vendor of this CPU.
+ *
+ * @param vendorStr CPU vendor as a string
+ * @return builder object
+ */
+ public Builder setVendor(String vendorStr) {
+ if (!Strings.isNullOrEmpty(vendorStr)) {
+ this.vendor = CpuVendor.getByName(vendorStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the CPU socket of this CPU.
+ *
+ * @param socket CPU socket
+ * @return builder object
+ */
+ public Builder setSocket(int socket) {
+ this.socket = socket;
+
+ return this;
+ }
+
+ /**
+ * Sets the frequency of this CPU.
+ *
+ * @param frequency CPU frequency
+ * @return builder object
+ */
+ public Builder setFrequency(long frequency) {
+ this.frequency = frequency;
+
+ return this;
+ }
+
+ /**
+ * Creates a DefaultCpuDevice object.
+ *
+ * @return DefaultCpuDevice object
+ */
+ public DefaultCpuDevice build() {
+ return new DefaultCpuDevice(id, vendor, socket, frequency);
+ }
+
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultMemoryHierarchyDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultMemoryHierarchyDevice.java
new file mode 100644
index 0000000..e467856
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultMemoryHierarchyDevice.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.memory.MemoryHierarchyDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryModuleDevice;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Sets;
+
+import java.util.Collection;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_HIERARCHY_EMPTY;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_MODULE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_CAPACITY_NEGATIVE;
+
+/**
+ * Default implementation for main memory hierarchy devices.
+ */
+public final class DefaultMemoryHierarchyDevice implements MemoryHierarchyDevice {
+
+ private final long totalCapacity;
+ private Collection<MemoryModuleDevice> memoryHierarchy = null;
+
+ private DefaultMemoryHierarchyDevice(long totalCapacity,
+ Collection<MemoryModuleDevice> memoryHierarchy) {
+ checkArgument(totalCapacity > 0, MSG_MEM_CAPACITY_NEGATIVE);
+ checkArgument(!memoryHierarchy.isEmpty(), MSG_MEM_HIERARCHY_EMPTY);
+
+ this.totalCapacity = totalCapacity;
+ this.memoryHierarchy = memoryHierarchy;
+ }
+
+ /**
+ * Creates a builder for DefaultMemoryHierarchyDevice object.
+ *
+ * @return builder object for DefaultMemoryHierarchyDevice object
+ */
+ public static DefaultMemoryHierarchyDevice.Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public int modulesNb() {
+ return this.memoryHierarchy.size();
+ }
+
+ @Override
+ public long totalCapacity() {
+ return this.totalCapacity;
+ }
+
+ @Override
+ public Collection<MemoryModuleDevice> memoryHierarchy() {
+ return this.memoryHierarchy;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("modulesNb", modulesNb())
+ .add("totalCapacity", totalCapacity())
+ .add("memoryHierarchy", memoryHierarchy())
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof MemoryHierarchyDevice)) {
+ return false;
+ }
+ MemoryHierarchyDevice device = (MemoryHierarchyDevice) obj;
+ return this.modulesNb() == device.modulesNb() &&
+ this.totalCapacity() == device.totalCapacity() &&
+ this.memoryHierarchy() == device.memoryHierarchy();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(totalCapacity, memoryHierarchy);
+ }
+
+ public static final class Builder {
+ long totalCapacity = 0;
+ Collection<MemoryModuleDevice> memoryHierarchy = Sets.newHashSet();
+
+ private Builder() {
+
+ }
+
+ /**
+ * Adds a new memory module into the hierarchy.
+ *
+ * @param moduleDev a memory module to add into the hierarchy
+ * @return builder object
+ */
+ public Builder addMemoryModule(MemoryModuleDevice moduleDev) {
+ checkNotNull(moduleDev, MSG_MEM_MODULE_NULL);
+ this.memoryHierarchy.add(moduleDev);
+ this.totalCapacity += moduleDev.capacity();
+
+ return this;
+ }
+
+ /**
+ * Creates a DefaultMemoryHierarchyDevice object.
+ *
+ * @return DefaultMemoryHierarchyDevice object
+ */
+ public DefaultMemoryHierarchyDevice build() {
+ return new DefaultMemoryHierarchyDevice(totalCapacity, memoryHierarchy);
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultMemoryModuleDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultMemoryModuleDevice.java
new file mode 100644
index 0000000..2ab5fde
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultMemoryModuleDevice.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.memory.MemoryModuleDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryType;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_MANUFACTURER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_SERIAL_NB_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_SIZE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_SPEED_CONF_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_SPEED_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_TYPE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_WIDTH_DATA_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_WIDTH_TOTAL_NEGATIVE;
+import static org.onosproject.drivers.server.devices.memory.MemoryModuleDevice.MAX_SPEED_MTS;
+
+/**
+ * Default implementation for main memory module devices.
+ */
+public final class DefaultMemoryModuleDevice implements MemoryModuleDevice {
+
+ private final MemoryType type;
+ private final String manufacturer;
+ private final String serialNumber;
+ private final int dataWidth;
+ private final int totalWidth;
+ private final long capacity;
+ private final long speed;
+ private final long configuredSpeed;
+
+ private DefaultMemoryModuleDevice(MemoryType type,
+ String manufacturer,
+ String serialNumber,
+ int dataWidth,
+ int totalWidth,
+ long capacity,
+ long speed,
+ long configuredSpeed) {
+ checkNotNull(type, MSG_MEM_TYPE_NULL);
+ checkNotNull(manufacturer, MSG_MEM_MANUFACTURER_NULL);
+ checkNotNull(serialNumber, MSG_MEM_SERIAL_NB_NULL);
+ checkArgument(dataWidth > 0, MSG_MEM_WIDTH_DATA_NEGATIVE);
+ checkArgument(totalWidth > 0, MSG_MEM_WIDTH_TOTAL_NEGATIVE);
+ checkArgument(capacity > 0, MSG_MEM_SIZE_NEGATIVE);
+ checkArgument((speed > 0) && (speed <= MAX_SPEED_MTS), MSG_MEM_SPEED_NEGATIVE);
+ checkArgument((configuredSpeed > 0) && (configuredSpeed <= speed), MSG_MEM_SPEED_CONF_NEGATIVE);
+
+ this.type = type;
+ this.manufacturer = manufacturer;
+ this.serialNumber = serialNumber;
+ this.dataWidth = dataWidth;
+ this.totalWidth = totalWidth;
+ this.capacity = capacity;
+ this.speed = speed;
+ this.configuredSpeed = configuredSpeed;
+ }
+
+ /**
+ * Creates a builder for DefaultMemoryModuleDevice object.
+ *
+ * @return builder object for DefaultMemoryModuleDevice object
+ */
+ public static DefaultMemoryModuleDevice.Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public MemoryType type() {
+ return this.type;
+ }
+
+ @Override
+ public String manufacturer() {
+ return this.manufacturer;
+ }
+
+ @Override
+ public String serialNumber() {
+ return this.serialNumber;
+ }
+
+ @Override
+ public int dataWidth() {
+ return this.dataWidth;
+ }
+
+ @Override
+ public int totalWidth() {
+ return this.totalWidth;
+ }
+
+ @Override
+ public long capacity() {
+ return this.capacity;
+ }
+
+ @Override
+ public long speed() {
+ return this.speed;
+ }
+
+ @Override
+ public long configuredSpeed() {
+ return this.configuredSpeed;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("type", type())
+ .add("manufacturer", manufacturer())
+ .add("serialNumber", serialNumber())
+ .add("dataWidth", dataWidth())
+ .add("totalWidth", totalWidth())
+ .add("capacity", capacity())
+ .add("speed", speed())
+ .add("configuredSpeed", configuredSpeed())
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof MemoryModuleDevice)) {
+ return false;
+ }
+ MemoryModuleDevice device = (MemoryModuleDevice) obj;
+ return this.type() == device.type() &&
+ this.manufacturer() == device.manufacturer() &&
+ this.serialNumber() == device.serialNumber() &&
+ this.dataWidth() == device.dataWidth() &&
+ this.totalWidth() == device.totalWidth() &&
+ this.capacity() == device.capacity() &&
+ this.speed() == device.speed() &&
+ this.configuredSpeed() == device.configuredSpeed();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, manufacturer, serialNumber,
+ dataWidth, totalWidth, capacity, speed, configuredSpeed);
+ }
+
+ public static final class Builder {
+ MemoryType type = null;
+ String manufacturer = null;
+ String serialNumber = null;
+ int dataWidth = -1;
+ int totalWidth = -1;
+ long capacity = -1;
+ long speed = -1;
+ long configuredSpeed = -1;
+
+ private Builder() {
+
+ }
+
+ /**
+ * Sets the type of this memory module.
+ *
+ * @param typeStr memory module's type
+ * @return builder object
+ */
+ public Builder setType(String typeStr) {
+ if (!Strings.isNullOrEmpty(typeStr)) {
+ this.type = MemoryType.getByName(typeStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the manufacturer of this memory module.
+ *
+ * @param manufacturer memory module's manufacturer
+ * @return builder object
+ */
+ public Builder setManufacturer(String manufacturer) {
+ if (!Strings.isNullOrEmpty(manufacturer)) {
+ this.manufacturer = manufacturer;
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the serial number of this memory module.
+ *
+ * @param serialNumber memory module's serial number
+ * @return builder object
+ */
+ public Builder setSerialNumber(String serialNumber) {
+ if (!Strings.isNullOrEmpty(serialNumber)) {
+ this.serialNumber = serialNumber;
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets this memory module's data width.
+ *
+ * @param dataWidth memory's data width
+ * @return builder object
+ */
+ public Builder setDataWidth(int dataWidth) {
+ this.dataWidth = dataWidth;
+
+ return this;
+ }
+
+ /**
+ * Sets this memory module's total width.
+ *
+ * @param totalWidth memory's total width
+ * @return builder object
+ */
+ public Builder setTotalWidth(int totalWidth) {
+ this.totalWidth = totalWidth;
+
+ return this;
+ }
+
+ /**
+ * Sets this memory module's capacity in MBytes.
+ *
+ * @param capacity memory's capacity
+ * @return builder object
+ */
+ public Builder setCapacity(long capacity) {
+ this.capacity = capacity;
+
+ return this;
+ }
+
+ /**
+ * Sets the speed of this memory module.
+ *
+ * @param speed memory speed
+ * @return builder object
+ */
+ public Builder setSpeed(long speed) {
+ this.speed = speed;
+
+ return this;
+ }
+
+ /**
+ * Sets the configured speed of this memory module.
+ *
+ * @param configuredSpeed memory's configured speed
+ * @return builder object
+ */
+ public Builder setConfiguredSpeed(long configuredSpeed) {
+ this.configuredSpeed = configuredSpeed;
+
+ return this;
+ }
+
+ /**
+ * Creates a DefaultMemoryModuleDevice object.
+ *
+ * @return DefaultMemoryModuleDevice object
+ */
+ public DefaultMemoryModuleDevice build() {
+ return new DefaultMemoryModuleDevice(
+ type, manufacturer, serialNumber,
+ dataWidth, totalWidth, capacity,
+ speed, configuredSpeed);
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java
index 9f782d8..a8270f5 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java
@@ -18,49 +18,61 @@
import org.onosproject.drivers.server.devices.nic.NicDevice;
import org.onosproject.drivers.server.devices.nic.NicRxFilter;
+import org.onosproject.drivers.server.devices.nic.NicRxFilter.RxFilter;
+import org.onosproject.net.Port;
import org.onlab.packet.MacAddress;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Objects;
import static org.onosproject.net.Port.Type;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_NAME_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_MAC_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_PORT_NUMBER_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_PORT_TYPE_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_RX_FILTER_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_RX_FILTERS_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_SPEED_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_PORT_TYPE_COPPER;
+import static org.onosproject.drivers.server.Constants.PARAM_NIC_PORT_TYPE_FIBER;
/**
* Default implementation for NIC devices.
*/
-public class DefaultNicDevice implements NicDevice, Comparable {
+public final class DefaultNicDevice implements NicDevice, Comparable {
private final String name;
private final long portNumber;
- private final long speed;
private final Type portType;
+ private final long speed;
private boolean status;
private final MacAddress macAddress;
private NicRxFilter rxFilterMechanisms;
- // 200 Gbps or 200.000 Mbps
- public static final long MAX_SPEED = 200000;
-
- public DefaultNicDevice(
+ private DefaultNicDevice(
String name,
long portNumber,
Type portType,
long speed,
boolean status,
- String macStr,
+ MacAddress mac,
NicRxFilter rxFilterMechanisms) {
- checkArgument(!Strings.isNullOrEmpty(name), "NIC name cannot be empty or NULL");
- checkArgument(portNumber >= 0, "NIC port number must be non-negative");
- checkNotNull(portType, "NIC port type cannot be null");
- checkArgument((speed >= 0) && (speed <= MAX_SPEED),
- "NIC speed must be positive and less or equal than " + MAX_SPEED + " Mbps");
- checkNotNull(macStr, "NIC MAC address cannot be null");
- checkNotNull(rxFilterMechanisms, "NIC Rx filter mechanisms cannot be null");
+ checkArgument(!Strings.isNullOrEmpty(name), MSG_NIC_NAME_NULL);
+ checkArgument(portNumber >= 0, MSG_NIC_PORT_NUMBER_NEGATIVE);
+ checkNotNull(portType, MSG_NIC_PORT_TYPE_NULL);
+ checkArgument((speed >= 0) && (speed <= NicDevice.MAX_SPEED),
+ MSG_NIC_SPEED_NEGATIVE);
+ checkNotNull(mac, MSG_NIC_MAC_NULL);
+ checkNotNull(rxFilterMechanisms, MSG_NIC_RX_FILTERS_NULL);
// Implies a problem
if (speed == 0) {
@@ -72,8 +84,17 @@
this.speed = speed;
this.portType = portType;
this.status = status;
- this.macAddress = MacAddress.valueOf(macStr);
- this.rxFilterMechanisms = rxFilterMechanisms;
+ this.macAddress = mac;
+ this.rxFilterMechanisms = rxFilterMechanisms;
+ }
+
+ /**
+ * Creates a builder for DefaultNicDevice object.
+ *
+ * @return builder object for DefaultNicDevice object
+ */
+ public static DefaultNicDevice.Builder builder() {
+ return new Builder();
}
@Override
@@ -123,7 +144,7 @@
}
@Override
- public void addRxFilterMechanism(NicRxFilter.RxFilter rxFilter) {
+ public void addRxFilterMechanism(RxFilter rxFilter) {
this.rxFilterMechanisms.addRxFilter(rxFilter);
}
@@ -186,4 +207,137 @@
return -1;
}
+ public static final class Builder {
+ String name;
+ long portNumber = -1;
+ Type portType = Type.FIBER;
+ long speed = -1;
+ boolean status = false;
+ MacAddress macAddress = MacAddress.ZERO;
+ NicRxFilter rxFilterMechanisms = new NicRxFilter();
+
+ /**
+ * Port types that usually appear in commodity servers.
+ */
+ static final Map<String, Port.Type> PORT_TYPE_MAP =
+ Collections.unmodifiableMap(
+ new HashMap<String, Port.Type>() {
+ {
+ put(PARAM_NIC_PORT_TYPE_COPPER, Port.Type.COPPER);
+ put(PARAM_NIC_PORT_TYPE_FIBER, Port.Type.FIBER);
+ }
+ }
+ );
+
+ private Builder() {
+
+ }
+
+ /**
+ * Sets the name of this NIC.
+ *
+ * @param name NIC name
+ * @return builder object
+ */
+ public Builder setName(String name) {
+ this.name = name;
+
+ return this;
+ }
+
+ /**
+ * Sets the NIC's port number.
+ *
+ * @param portNumber NIC's port number
+ * @return builder object
+ */
+ public Builder setPortNumber(long portNumber) {
+ this.portNumber = portNumber;
+
+ return this;
+ }
+
+ /**
+ * Sets the NIC's port type as a string.
+ *
+ * @param portTypeStr NIC's port type
+ * @return builder object
+ */
+ public Builder setPortType(String portTypeStr) {
+ portType = PORT_TYPE_MAP.get(portTypeStr);
+ if (portType == null) {
+ throw new IllegalArgumentException(
+ portTypeStr + " is not a valid NIC port type");
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the NIC's speed.
+ *
+ * @param speed NIC's speed
+ * @return builder object
+ */
+ public Builder setSpeed(long speed) {
+ this.speed = speed;
+
+ return this;
+ }
+
+ /**
+ * Sets the NIC's status.
+ *
+ * @param status NIC's status
+ * @return builder object
+ */
+ public Builder setStatus(boolean status) {
+ this.status = status;
+
+ return this;
+ }
+
+ /**
+ * Sets the NIC's MAC address.
+ *
+ * @param macAddressStr NIC's MAC address
+ * @return builder object
+ */
+ public Builder setMacAddress(String macAddressStr) {
+ this.macAddress = MacAddress.valueOf(macAddressStr);
+
+ return this;
+ }
+
+ /**
+ * Sets the NIC's list of Rx filters as strings.
+ *
+ * @param rxFilters NIC's list of Rx filters
+ * @return builder object
+ */
+ public Builder setRxFilters(List<String> rxFilters) {
+ checkNotNull(rxFilters, MSG_NIC_RX_FILTERS_NULL);
+ for (String s : rxFilters) {
+ // Verify that this is a valid Rx filter
+ RxFilter rf = RxFilter.getByName(s);
+ checkNotNull(rf, MSG_NIC_RX_FILTER_NULL);
+ this.rxFilterMechanisms.addRxFilter(rf);
+ }
+
+ return this;
+ }
+
+ /**
+ * Creates a DefaultNicDevice object.
+ *
+ * @return DefaultNicDevice object
+ */
+ public DefaultNicDevice build() {
+ return new DefaultNicDevice(
+ name, portNumber, portType, speed,
+ status, macAddress, rxFilterMechanisms);
+ }
+
+ }
+
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java
index b43c2ec..781afc5 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java
@@ -16,7 +16,9 @@
package org.onosproject.drivers.server.impl.devices;
-import org.onosproject.drivers.server.devices.CpuDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheHierarchyDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryHierarchyDevice;
import org.onosproject.drivers.server.devices.nic.NicDevice;
import org.onosproject.drivers.server.devices.RestServerSBDevice;
@@ -26,12 +28,15 @@
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import java.util.Objects;
import java.util.Collection;
+import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_HIERARCHY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_LIST_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_HIERARCHY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_LIST_NULL;
/**
* Default implementation for REST server devices.
@@ -39,35 +44,46 @@
public class DefaultRestServerSBDevice
extends DefaultRestSBDevice implements RestServerSBDevice {
- private Collection<CpuDevice> cpus = Lists.newArrayList();
- private Collection<NicDevice> nics = Lists.newArrayList();
+ private Collection<CpuDevice> cpus = null;
+ private CpuCacheHierarchyDevice caches = null;
+ private MemoryHierarchyDevice memory = null;
+ private Collection<NicDevice> nics = null;
+
+ /**
+ * Indicates an invalid port.
+ */
+ private static final long INVALID_PORT = (long) -1;
+ private static final String INVALID_PORT_STR = "";
public DefaultRestServerSBDevice(
IpAddress ip, int port, String name, String password,
String protocol, String url, boolean isActive,
- Collection<CpuDevice> cpus, Collection<NicDevice> nics) {
- this(
- ip, port, name, password, protocol, url, isActive,
- "", "", "", "", AuthenticationScheme.BASIC, "", cpus, nics
- );
+ Collection<CpuDevice> cpus,
+ CpuCacheHierarchyDevice caches,
+ MemoryHierarchyDevice memory,
+ Collection<NicDevice> nics) {
+ this(ip, port, name, password, protocol, url, isActive,
+ "", "", "", "", cpus, caches, memory, nics);
}
public DefaultRestServerSBDevice(
IpAddress ip, int port, String name, String password,
String protocol, String url, boolean isActive, String testUrl,
String manufacturer, String hwVersion, String swVersion,
- AuthenticationScheme authenticationScheme, String token,
- Collection<CpuDevice> cpus, Collection<NicDevice> nics) {
- super(
- ip, port, name, password, protocol, url, isActive,
- testUrl, manufacturer, hwVersion, swVersion,
- authenticationScheme, token
- );
+ Collection<CpuDevice> cpus, CpuCacheHierarchyDevice caches,
+ MemoryHierarchyDevice memory, Collection<NicDevice> nics) {
+ super(ip, port, name, password, protocol, url, isActive,
+ testUrl, manufacturer, hwVersion, swVersion,
+ AuthenticationScheme.BASIC, "");
- checkNotNull(cpus, "Device's set of CPUs cannot be null");
- checkNotNull(nics, "Device's set of NICs cannot be null");
+ checkNotNull(cpus, MSG_CPU_LIST_NULL);
+ checkNotNull(caches, MSG_CPU_CACHE_HIERARCHY_NULL);
+ checkNotNull(memory, MSG_MEM_HIERARCHY_NULL);
+ checkNotNull(nics, MSG_NIC_LIST_NULL);
this.cpus = cpus;
+ this.caches = caches;
+ this.memory = memory;
this.nics = nics;
}
@@ -82,6 +98,31 @@
}
@Override
+ public CpuCacheHierarchyDevice caches() {
+ return this.caches;
+ }
+
+ @Override
+ public int numberOfCaches() {
+ return this.caches.levels();
+ }
+
+ @Override
+ public long cacheCapacity() {
+ return this.caches.totalCapacity();
+ }
+
+ @Override
+ public MemoryHierarchyDevice memory() {
+ return this.memory;
+ }
+
+ @Override
+ public long memoryCapacity() {
+ return this.memory.totalCapacity();
+ }
+
+ @Override
public Collection<NicDevice> nics() {
return this.nics;
}
@@ -94,7 +135,7 @@
@Override
public long portNumberFromName(String portName) {
if (Strings.isNullOrEmpty(portName)) {
- return -1;
+ return INVALID_PORT;
}
for (NicDevice nic : this.nics) {
@@ -103,13 +144,13 @@
}
}
- return -1;
+ return INVALID_PORT;
}
@Override
public String portNameFromNumber(long portNumber) {
if (portNumber < 0) {
- return "";
+ return INVALID_PORT_STR;
}
for (NicDevice nic : this.nics) {
@@ -118,7 +159,7 @@
}
}
- return "";
+ return INVALID_PORT_STR;
}
@Override
@@ -135,9 +176,10 @@
.add("hwVersion", hwVersion().orElse(null))
.add("swVersion", swVersion().orElse(null))
.add("cpus", cpus())
+ .add("cpuCaches", caches())
+ .add("memory", memory())
.add("nics", nics())
.toString();
-
}
@Override
@@ -148,16 +190,21 @@
if (!(obj instanceof RestServerSBDevice)) {
return false;
}
- RestServerSBDevice device = (RestServerSBDevice) obj;
- return this.username().equals(device.username()) &&
+ RestServerSBDevice device = (RestServerSBDevice) obj;
+ return this.protocol().equals(device.protocol()) &&
+ this.username().equals(device.username()) &&
this.ip().equals(device.ip()) &&
- this.port() == device.port();
+ this.port() == device.port() &&
+ this.cpus() == device.cpus() &&
+ this.caches() == device.caches() &&
+ this.memory() == device.memory() &&
+ this.nics() == device.nics();
}
@Override
public int hashCode() {
- return Objects.hash(ip(), port(), cpus(), nics());
+ return Objects.hash(ip(), port(), cpus(), caches(), memory(), nics());
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java
index c5ac09a..eff32eb 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java
@@ -16,12 +16,15 @@
package org.onosproject.drivers.server.impl.devices;
-import org.onosproject.drivers.server.devices.CpuDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuCacheHierarchyDevice;
+import org.onosproject.drivers.server.devices.cpu.CpuDevice;
+import org.onosproject.drivers.server.devices.memory.MemoryHierarchyDevice;
import org.onosproject.drivers.server.devices.nic.NicDevice;
import org.onosproject.drivers.server.devices.ServerDeviceDescription;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.SparseAnnotations;
+
import org.onlab.packet.ChassisId;
import com.google.common.base.Objects;
@@ -31,6 +34,10 @@
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CACHE_HIERARCHY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_LIST_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_MEM_HIERARCHY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_NIC_LIST_NULL;
import static org.onosproject.net.Device.Type;
/**
@@ -40,6 +47,8 @@
implements ServerDeviceDescription {
private final Collection<CpuDevice> cpus;
+ private final CpuCacheHierarchyDevice caches;
+ private final MemoryHierarchyDevice memory;
private final Collection<NicDevice> nics;
/**
@@ -53,6 +62,8 @@
* @param serialNumber device serial number
* @param chassis chassis id
* @param cpus set of CPUs
+ * @param caches CPU cache hierarchy
+ * @param memory memory hierarchy
* @param nics set of network interface cards (NICs)
* @param annotations optional key/value annotations map
*/
@@ -60,10 +71,11 @@
URI uri, Type type, String manufacturer,
String hwVersion, String swVersion,
String serialNumber, ChassisId chassis,
- Collection<CpuDevice> cpus, Collection<NicDevice> nics,
+ Collection<CpuDevice> cpus, CpuCacheHierarchyDevice caches,
+ MemoryHierarchyDevice memory, Collection<NicDevice> nics,
SparseAnnotations... annotations) {
this(uri, type, manufacturer, hwVersion, swVersion, serialNumber,
- chassis, true, cpus, nics, annotations);
+ chassis, true, cpus, caches, memory, nics, annotations);
}
/**
@@ -77,6 +89,8 @@
* @param serialNumber device serial number
* @param chassis chassis id
* @param cpus set of CPUs
+ * @param caches CPU cache hierarchy
+ * @param memory memory hierarchy
* @param nics set of network interface cards (NICs)
* @param defaultAvailable optional whether device is by default available
* @param annotations optional key/value annotations map
@@ -86,31 +100,36 @@
String hwVersion, String swVersion,
String serialNumber, ChassisId chassis,
boolean defaultAvailable,
- Collection<CpuDevice> cpus, Collection<NicDevice> nics,
+ Collection<CpuDevice> cpus, CpuCacheHierarchyDevice caches,
+ MemoryHierarchyDevice memory, Collection<NicDevice> nics,
SparseAnnotations... annotations) {
super(
uri, type, manufacturer, hwVersion, swVersion,
serialNumber, chassis, defaultAvailable, annotations
);
- checkNotNull(cpus, "Device's set of CPUs cannot be null");
- checkNotNull(nics, "Device's set of NICs cannot be null");
+ checkNotNull(cpus, MSG_CPU_LIST_NULL);
+ checkNotNull(caches, MSG_CPU_CACHE_HIERARCHY_NULL);
+ checkNotNull(memory, MSG_MEM_HIERARCHY_NULL);
+ checkNotNull(nics, MSG_NIC_LIST_NULL);
this.cpus = cpus;
+ this.caches = caches;
+ this.memory = memory;
this.nics = nics;
}
/**
* Creates a server device description using the supplied information.
* @param base ServerDeviceDescription to basic information
- * @param annotations Annotations to use.
+ * @param annotations Annotations to use
*/
public DefaultServerDeviceDescription(ServerDeviceDescription base,
SparseAnnotations... annotations) {
this(base.deviceUri(), base.type(), base.manufacturer(),
base.hwVersion(), base.swVersion(), base.serialNumber(),
base.chassisId(), base.isDefaultAvailable(),
- base.cpus(), base.nics(),
+ base.cpus(), base.caches(), base.memory(), base.nics(),
annotations);
}
@@ -118,7 +137,7 @@
* Creates a device description using the supplied information.
* @param base ServerDeviceDescription to basic information (except for type)
* @param type device type
- * @param annotations Annotations to use.
+ * @param annotations Annotations to use
*/
public DefaultServerDeviceDescription(
ServerDeviceDescription base, Type type,
@@ -126,7 +145,7 @@
this(base.deviceUri(), type, base.manufacturer(),
base.hwVersion(), base.swVersion(), base.serialNumber(),
base.chassisId(), base.isDefaultAvailable(),
- base.cpus(), base.nics(),
+ base.cpus(), base.caches(), base.memory(), base.nics(),
annotations);
}
@@ -135,7 +154,7 @@
*
* @param base ServerDeviceDescription to basic information (except for defaultAvailable)
* @param defaultAvailable whether device should be made available by default
- * @param annotations Annotations to use.
+ * @param annotations Annotations to use
*/
public DefaultServerDeviceDescription(
ServerDeviceDescription base,
@@ -144,7 +163,7 @@
this(base.deviceUri(), base.type(), base.manufacturer(),
base.hwVersion(), base.swVersion(), base.serialNumber(),
base.chassisId(), defaultAvailable,
- base.cpus(), base.nics(),
+ base.cpus(), base.caches(), base.memory(), base.nics(),
annotations);
}
@@ -154,6 +173,16 @@
}
@Override
+ public CpuCacheHierarchyDevice caches() {
+ return this.caches;
+ }
+
+ @Override
+ public MemoryHierarchyDevice memory() {
+ return this.memory;
+ }
+
+ @Override
public Collection<NicDevice> nics() {
return this.nics;
}
@@ -168,6 +197,8 @@
.add("swVersion", swVersion())
.add("serial", serialNumber())
.add("cpus", cpus)
+ .add("cpuCaches", caches)
+ .add("memory", memory)
.add("nics", nics)
.add("annotations", annotations())
.toString();
@@ -175,7 +206,7 @@
@Override
public int hashCode() {
- return Objects.hashCode(super.hashCode(), cpus, nics);
+ return Objects.hashCode(super.hashCode(), cpus, caches, memory, nics);
}
@Override
@@ -193,6 +224,8 @@
&& Objects.equal(this.serialNumber(), that.serialNumber())
&& Objects.equal(this.chassisId(), that.chassisId())
&& Objects.equal(this.cpus(), that.cpus())
+ && Objects.equal(this.caches(), that.caches())
+ && Objects.equal(this.memory(), that.memory())
&& Objects.equal(this.nics(), that.nics())
&& Objects.equal(this.isDefaultAvailable(), that.isDefaultAvailable());
}
@@ -203,6 +236,9 @@
DefaultServerDeviceDescription() {
super(null, null, null, null, null, null, null, (SparseAnnotations[]) null);
this.cpus = null;
+ this.caches = null;
+ this.memory = null;
this.nics = null;
}
+
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
index f2b6968..6296cc1 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
@@ -16,10 +16,12 @@
package org.onosproject.drivers.server.impl.stats;
+import org.onosproject.drivers.server.devices.cpu.CpuCoreId;
import org.onosproject.drivers.server.stats.CpuStatistics;
import org.onosproject.drivers.server.stats.MonitoringUnit;
import org.onosproject.net.DeviceId;
+
import com.google.common.base.MoreObjects;
import java.util.Optional;
@@ -28,21 +30,18 @@
import static org.onosproject.drivers.server.stats.MonitoringUnit.ThroughputUnit;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CORE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_LOAD_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
/**
* Default implementation for CPU statistics.
*/
public final class DefaultCpuStatistics implements CpuStatistics {
- private static final float MIN_CPU_LOAD = (float) 0.0;
- private static final float MAX_CPU_LOAD = (float) 1.0;
-
private static final LatencyUnit DEF_LATENCY_UNIT = LatencyUnit.NANO_SECOND;
private static final ThroughputUnit DEF_THROUGHPUT_UNIT = ThroughputUnit.MBPS;
- // Upper limit of CPU cores in one machine
- public static final int MAX_CPU_NB = 512;
-
private final DeviceId deviceId;
private final int id;
@@ -63,16 +62,15 @@
private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, int busySince,
MonitoringUnit throughputUnit, float averageThroughput, MonitoringUnit latencyUnit,
float minLatency, float averageLatency, float maxLatency) {
- checkNotNull(deviceId, "Device ID is NULL");
- checkArgument((id >= 0) && (id < MAX_CPU_NB),
- "Invalid CPU core ID " + String.valueOf(id) + ", not in [0, " + String.valueOf(MAX_CPU_NB - 1) + "]");
- checkArgument((load >= MIN_CPU_LOAD) && (load <= MAX_CPU_LOAD),
- "Invalid CPU load " + Float.toString(load) + ", not in [" + MIN_CPU_LOAD + ", " + MAX_CPU_LOAD + "]");
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+ checkArgument((id >= 0) && (id < CpuCoreId.MAX_CPU_CORE_NB), MSG_CPU_CORE_NEGATIVE);
+ checkArgument((load >= CpuStatistics.MIN_CPU_LOAD) &&
+ (load <= CpuStatistics.MAX_CPU_LOAD), MSG_CPU_LOAD_NEGATIVE);
- this.deviceId = deviceId;
- this.id = id;
- this.load = load;
- this.queue = queue;
+ this.deviceId = deviceId;
+ this.id = id;
+ this.load = load;
+ this.queue = queue;
this.busySince = busySince;
this.throughputUnit = (throughputUnit == null) ?
@@ -91,10 +89,10 @@
// Constructor for serializer
private DefaultCpuStatistics() {
- this.deviceId = null;
- this.id = 0;
- this.load = 0;
- this.queue = 0;
+ this.deviceId = null;
+ this.id = 0;
+ this.load = 0;
+ this.queue = 0;
this.busySince = -1;
this.throughputUnit = null;
@@ -349,6 +347,7 @@
throughputUnit, averageThroughput,
latencyUnit, minLatency, averageLatency, maxLatency);
}
+
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMemoryStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMemoryStatistics.java
new file mode 100644
index 0000000..fda4942
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMemoryStatistics.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.impl.stats;
+
+import org.onosproject.drivers.server.stats.MemoryStatistics;
+import org.onosproject.drivers.server.stats.MonitoringUnit;
+
+import org.onosproject.net.DeviceId;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_MEMORY_FREE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_MEMORY_TOTAL_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_MEMORY_USED_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_UNIT_NULL;
+import static org.onosproject.drivers.server.stats.MonitoringUnit.CapacityUnit;
+
+/**
+ * Default implementation for main memory statistics.
+ */
+public final class DefaultMemoryStatistics implements MemoryStatistics {
+
+ private static final CapacityUnit DEF_MEM_UNIT = CapacityUnit.KILOBYTES;
+
+ private final DeviceId deviceId;
+ private final MonitoringUnit unit;
+ private long used;
+ private long free;
+ private long total;
+
+ private DefaultMemoryStatistics(DeviceId deviceId, MonitoringUnit unit,
+ long used, long free, long total) {
+ checkNotNull(unit, MSG_STATS_UNIT_NULL);
+ checkArgument(used >= 0, MSG_STATS_MEMORY_USED_NEGATIVE);
+ checkArgument(free >= 0, MSG_STATS_MEMORY_FREE_NEGATIVE);
+ checkArgument((total >= 0) &&
+ (used + free == total), MSG_STATS_MEMORY_TOTAL_NEGATIVE);
+
+ this.deviceId = deviceId;
+ this.unit = unit;
+ this.used = used;
+ this.free = free;
+ this.total = total;
+ }
+
+ // Constructor for serializer
+ private DefaultMemoryStatistics() {
+ this.deviceId = null;
+ this.unit = null;
+ this.used = 0;
+ this.free = 0;
+ this.total = 0;
+ }
+
+ /**
+ * Creates a builder for DefaultMemoryStatistics object.
+ *
+ * @return builder object for DefaultMemoryStatistics object
+ */
+ public static DefaultMemoryStatistics.Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public MonitoringUnit unit() {
+ return this.unit;
+ }
+
+ @Override
+ public long used() {
+ return this.used;
+ }
+
+ @Override
+ public long free() {
+ return this.free;
+ }
+
+ @Override
+ public long total() {
+ return this.total;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .omitNullValues()
+ .add("device", deviceId)
+ .add("unit", this.unit())
+ .add("used", this.used())
+ .add("free", this.free())
+ .add("total", this.total())
+ .toString();
+ }
+
+ public static final class Builder {
+
+ DeviceId deviceId;
+ MonitoringUnit unit = DEF_MEM_UNIT;
+ long used;
+ long free;
+ long total;
+
+ private Builder() {
+
+ }
+
+ /**
+ * Sets the device identifier.
+ *
+ * @param deviceId device identifier
+ * @return builder object
+ */
+ public Builder setDeviceId(DeviceId deviceId) {
+ this.deviceId = deviceId;
+
+ return this;
+ }
+
+ /**
+ * Sets memory statistics unit.
+ *
+ * @param unitStr memory statistics unit as a string
+ * @return builder object
+ */
+ public Builder setUnit(String unitStr) {
+ if (!Strings.isNullOrEmpty(unitStr)) {
+ this.unit = CapacityUnit.getByName(unitStr);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the amount of used main memory.
+ *
+ * @param used used main memory
+ * @return builder object
+ */
+ public Builder setMemoryUsed(long used) {
+ this.used = used;
+ return this;
+ }
+
+ /**
+ * Sets the amount of free main memory.
+ *
+ * @param free free main memory
+ * @return builder object
+ */
+ public Builder setMemoryFree(long free) {
+ this.free = free;
+ return this;
+ }
+
+ /**
+ * Sets the total amount of main memory.
+ *
+ * @param total total main memory
+ * @return builder object
+ */
+ public Builder setMemoryTotal(long total) {
+ this.total = total;
+ return this;
+ }
+
+ /**
+ * Creates a DefaultMemoryStatistics object.
+ *
+ * @return DefaultMemoryStatistics object
+ */
+ public DefaultMemoryStatistics build() {
+ return new DefaultMemoryStatistics(
+ deviceId, unit, used, free, total);
+ }
+
+ }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java
index c05687f..6a4e0de 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java
@@ -16,7 +16,9 @@
package org.onosproject.drivers.server.impl.stats;
+import org.onosproject.drivers.server.devices.cpu.CpuCoreId;
import org.onosproject.drivers.server.stats.CpuStatistics;
+import org.onosproject.drivers.server.stats.MemoryStatistics;
import org.onosproject.drivers.server.stats.MonitoringStatistics;
import org.onosproject.drivers.server.stats.TimingStatistics;
@@ -29,10 +31,16 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.drivers.server.Constants.MSG_CPU_CORE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_CPU_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_MEMORY_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_NIC_NULL;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_TIMING_NULL;
/**
* Default monitoring statistics for server devices.
- * Includes CPU, NIC, and timing statistics.
+ * Includes CPU, main memory, NIC, and timing statistics.
*/
public final class DefaultMonitoringStatistics implements MonitoringStatistics {
@@ -40,30 +48,35 @@
private final TimingStatistics timingStatistics;
private final Collection<CpuStatistics> cpuStatistics;
+ private final MemoryStatistics memoryStatistics;
private final Collection<PortStatistics> nicStatistics;
private DefaultMonitoringStatistics(
DeviceId deviceId,
TimingStatistics timingStatistics,
Collection<CpuStatistics> cpuStatistics,
+ MemoryStatistics memoryStatistics,
Collection<PortStatistics> nicStatistics) {
- checkNotNull(deviceId, "Device ID is NULL");
- checkNotNull(timingStatistics, "Timing statistics are NULL");
- checkNotNull(cpuStatistics, "CPU statistics are NULL");
- checkNotNull(nicStatistics, "NIC statistics are NULL");
+ checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
+ checkNotNull(timingStatistics, MSG_STATS_TIMING_NULL);
+ checkNotNull(cpuStatistics, MSG_STATS_CPU_NULL);
+ checkNotNull(memoryStatistics, MSG_STATS_MEMORY_NULL);
+ checkNotNull(nicStatistics, MSG_STATS_NIC_NULL);
- this.deviceId = deviceId;
+ this.deviceId = deviceId;
this.timingStatistics = timingStatistics;
- this.cpuStatistics = cpuStatistics;
- this.nicStatistics = nicStatistics;
+ this.cpuStatistics = cpuStatistics;
+ this.memoryStatistics = memoryStatistics;
+ this.nicStatistics = nicStatistics;
}
// Constructor for serializer
private DefaultMonitoringStatistics() {
- this.deviceId = null;
+ this.deviceId = null;
this.timingStatistics = null;
- this.cpuStatistics = null;
- this.nicStatistics = null;
+ this.cpuStatistics = null;
+ this.memoryStatistics = null;
+ this.nicStatistics = null;
}
/**
@@ -87,11 +100,8 @@
@Override
public CpuStatistics cpuStatistics(int cpuId) {
- checkArgument(
- (cpuId >= 0) && (cpuId < DefaultCpuStatistics.MAX_CPU_NB),
- "CPU core ID must be in [0, " +
- String.valueOf(DefaultCpuStatistics.MAX_CPU_NB - 1) + "]"
- );
+ checkArgument((cpuId >= 0) && (cpuId < CpuCoreId.MAX_CPU_CORE_NB),
+ MSG_CPU_CORE_NEGATIVE);
for (CpuStatistics cs : this.cpuStatistics) {
if (cs.id() == cpuId) {
return cs;
@@ -101,6 +111,11 @@
}
@Override
+ public MemoryStatistics memoryStatistics() {
+ return this.memoryStatistics;
+ }
+
+ @Override
public Collection<PortStatistics> nicStatisticsAll() {
return this.nicStatistics;
}
@@ -132,6 +147,7 @@
.omitNullValues()
.add("timingStatistics", timingStatistics())
.add("cpuStatistics", cpuStatisticsAll())
+ .add("memoryStatistics", memoryStatistics())
.add("nicStatistics", nicStatisticsAll())
.toString();
}
@@ -141,6 +157,7 @@
DeviceId deviceId;
TimingStatistics timingStatistics;
Collection<CpuStatistics> cpuStatistics;
+ MemoryStatistics memoryStatistics;
Collection<PortStatistics> nicStatistics;
private Builder() {
@@ -184,6 +201,18 @@
}
/**
+ * Sets memory statistics.
+ *
+ * @param memoryStatistics memory statistics
+ * @return builder object
+ */
+ public Builder setMemoryStatistics(MemoryStatistics memoryStatistics) {
+ this.memoryStatistics = memoryStatistics;
+
+ return this;
+ }
+
+ /**
* Sets NIC statistics.
*
* @param nicStatistics NIC statistics
@@ -202,11 +231,8 @@
*/
public DefaultMonitoringStatistics build() {
return new DefaultMonitoringStatistics(
- deviceId,
- timingStatistics,
- cpuStatistics,
- nicStatistics
- );
+ deviceId, timingStatistics, cpuStatistics,
+ memoryStatistics, nicStatistics);
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
index 6c4f86f..3e72eb6 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
@@ -24,6 +24,10 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_TIMING_AUTO_SCALE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_TIMING_LAUNCH_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_TIMING_PARSE_NEGATIVE;
+import static org.onosproject.drivers.server.Constants.MSG_STATS_UNIT_NULL;
import static org.onosproject.drivers.server.stats.MonitoringUnit.LatencyUnit;
/**
@@ -31,25 +35,25 @@
*/
public final class DefaultTimingStatistics implements TimingStatistics {
- private static final LatencyUnit DEF_UNIT = LatencyUnit.NANO_SECOND;
+ private static final LatencyUnit DEF_TIME_UNIT = LatencyUnit.NANO_SECOND;
private final MonitoringUnit unit;
private final long deployCommandParsingTime;
private final long deployCommandLaunchingTime;
- private long autoScaleTime;
+ private final long autoScaleTime;
private DefaultTimingStatistics(
MonitoringUnit unit,
long parsingTime,
long launchingTime,
long autoScaleTime) {
- checkNotNull(unit, "Time statistics unit is null");
- checkArgument(parsingTime >= 0, "Parsing time is negative");
- checkArgument(launchingTime >= 0, "Launching time is negative");
- checkArgument(autoScaleTime >= 0, "Auto-scale time is negative");
+ checkNotNull(unit, MSG_STATS_UNIT_NULL);
+ checkArgument(parsingTime >= 0, MSG_STATS_TIMING_PARSE_NEGATIVE);
+ checkArgument(launchingTime >= 0, MSG_STATS_TIMING_LAUNCH_NEGATIVE);
+ checkArgument(autoScaleTime >= 0, MSG_STATS_TIMING_AUTO_SCALE_NEGATIVE);
this.unit = unit;
- this.deployCommandParsingTime = parsingTime;
+ this.deployCommandParsingTime = parsingTime;
this.deployCommandLaunchingTime = launchingTime;
this.autoScaleTime = autoScaleTime;
}
@@ -57,7 +61,7 @@
// Constructor for serializer
private DefaultTimingStatistics() {
this.unit = null;
- this.deployCommandParsingTime = 0;
+ this.deployCommandParsingTime = 0;
this.deployCommandLaunchingTime = 0;
this.autoScaleTime = 0;
}
@@ -100,7 +104,7 @@
public String toString() {
return MoreObjects.toStringHelper(this)
.omitNullValues()
- .add("unit", this.unit().toString())
+ .add("unit", this.unit())
.add("parsingTime", this.deployCommandParsingTime())
.add("launchingTime", this.deployCommandLaunchingTime())
.add("deploymentTime", this.totalDeploymentTime())
@@ -110,7 +114,7 @@
public static final class Builder {
- MonitoringUnit unit = DEF_UNIT;
+ MonitoringUnit unit = DEF_TIME_UNIT;
long deployCommandParsingTime;
long deployCommandLaunchingTime;
long autoScaleTime;
@@ -179,6 +183,7 @@
unit, deployCommandParsingTime,
deployCommandLaunchingTime, autoScaleTime);
}
+
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
index 5296d57..fcd0aab 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
@@ -24,6 +24,12 @@
public interface CpuStatistics {
/**
+ * Minimum and maximum CPU load values.
+ */
+ static final float MIN_CPU_LOAD = (float) 0.0;
+ static final float MAX_CPU_LOAD = (float) 1.0;
+
+ /**
* Returns the ID of a CPU core.
*
* @return CPU core identifier
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MemoryStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MemoryStatistics.java
new file mode 100644
index 0000000..4ff34e2
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MemoryStatistics.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.server.stats;
+
+/**
+ * Main memory statistics API.
+ */
+public interface MemoryStatistics {
+
+ /**
+ * Returns the unit of main memory statistics.
+ *
+ * @return main memory statistics' unit
+ */
+ MonitoringUnit unit();
+
+ /**
+ * Returns the amount of main memory being used.
+ *
+ * @return used main memory
+ */
+ long used();
+
+ /**
+ * Returns the amount of main memory being free.
+ *
+ * @return free main memory
+ */
+ long free();
+
+ /**
+ * Returns the total amount of main memory.
+ *
+ * @return total main memory
+ */
+ long total();
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringStatistics.java
index c713d01..e41fe11 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringStatistics.java
@@ -51,6 +51,13 @@
CpuStatistics cpuStatistics(int cpuId);
/**
+ * Returns main memory statistics of a server device.
+ *
+ * @return main memory statistics
+ */
+ MemoryStatistics memoryStatistics();
+
+ /**
* Returns the NIC statistics of a server device.
* Includes the statistics of all NICs.
*
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java
index 33d8763..b55ce70 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java
@@ -13,11 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.drivers.server.stats;
import java.util.Map;
import java.util.HashMap;
+import static org.onosproject.drivers.server.Constants.MSG_CONVERSION_TO_BITS;
+import static org.onosproject.drivers.server.Constants.MSG_CONVERSION_TO_BYTES;
+
/**
* Representation of a monitoring unit.
*/
@@ -129,6 +133,155 @@
};
+ /**
+ * Capacity-related monitoring units.
+ */
+ public enum CapacityUnit implements MonitoringUnit {
+
+ BITS("Bits"),
+ KILOBITS("kBits"),
+ MEGABITS("MBits"),
+ GIGABITS("GBits"),
+ BYTES("Bytes"),
+ KILOBYTES("kBytes"),
+ MEGABYTES("MBytes"),
+ GIGABYTES("GBytes");
+
+ private String capacityUnit;
+
+ // Statically maps capacity monitoring units to enum types
+ private static final Map<String, MonitoringUnit> MAP =
+ new HashMap<String, MonitoringUnit>();
+ static {
+ for (CapacityUnit cu : CapacityUnit.values()) {
+ MAP.put(cu.toString().toLowerCase(), (MonitoringUnit) cu);
+ }
+ }
+
+ private CapacityUnit(String capacityUnit) {
+ this.capacityUnit = capacityUnit;
+ }
+
+ public static MonitoringUnit getByName(String cu) {
+ cu = cu.toLowerCase();
+ return MAP.get(cu);
+ }
+
+ public static float toBits(float value, CapacityUnit fromUnit) {
+ if (value == 0) {
+ return value;
+ }
+
+ if (fromUnit == BITS) {
+ return value;
+ } else if (fromUnit == KILOBITS) {
+ return (value * 1000);
+ } else if (fromUnit == MEGABITS) {
+ return (value * 1000000);
+ } else if (fromUnit == GIGABITS) {
+ return (value * 1000000000);
+ } else if (fromUnit == BYTES) {
+ return value * 8;
+ } else if (fromUnit == KILOBYTES) {
+ return (value * 1000) * 8;
+ } else if (fromUnit == MEGABYTES) {
+ return (value * 1000000) * 8;
+ } else if (fromUnit == GIGABYTES) {
+ return (value * 1000000000) * 8;
+ }
+
+ throw new IllegalArgumentException(MSG_CONVERSION_TO_BITS);
+ }
+
+ public static float toKiloBits(float value, CapacityUnit fromUnit) {
+ return toBits(value, fromUnit) / 1000;
+ }
+
+ public static float toMegaBits(float value, CapacityUnit fromUnit) {
+ return toBits(value, fromUnit) / 1000000;
+ }
+
+ public static float toGigaBits(float value, CapacityUnit fromUnit) {
+ return toBits(value, fromUnit) / 1000000000;
+ }
+
+ public static float toBytes(float value, CapacityUnit fromUnit) {
+ if (value == 0) {
+ return value;
+ }
+
+ if (fromUnit == BITS) {
+ return value / 8;
+ } else if (fromUnit == KILOBITS) {
+ return (value * 1000) / 8;
+ } else if (fromUnit == MEGABITS) {
+ return (value * 1000000) / 8;
+ } else if (fromUnit == GIGABITS) {
+ return (value * 1000000000) / 8;
+ } else if (fromUnit == BYTES) {
+ return value;
+ } else if (fromUnit == KILOBYTES) {
+ return value * 1000;
+ } else if (fromUnit == MEGABYTES) {
+ return value * 1000000;
+ } else if (fromUnit == GIGABYTES) {
+ return value * 1000000000;
+ }
+
+ throw new IllegalArgumentException(MSG_CONVERSION_TO_BYTES);
+ }
+
+ public static float toKiloBytes(float value, CapacityUnit fromUnit) {
+ return toBytes(value, fromUnit) / 1000;
+ }
+
+ public static float toMegaBytes(float value, CapacityUnit fromUnit) {
+ return toBytes(value, fromUnit) / 1000000;
+ }
+
+ public static float toGigaBytes(float value, CapacityUnit fromUnit) {
+ return toBytes(value, fromUnit) / 1000000000;
+ }
+
+ @Override
+ public String toString() {
+ return this.capacityUnit;
+ }
+
+ };
+
+ /**
+ * Percentage-related monitoring unit.
+ */
+ public enum PercentageUnit implements MonitoringUnit {
+
+ PERCENTAGE("percentage");
+
+ private String percentageUnit;
+
+ // Statically maps percentage monitoring units to enum types
+ private static final Map<String, MonitoringUnit> MAP =
+ new HashMap<String, MonitoringUnit>();
+ static {
+ MAP.put(PERCENTAGE.toString().toLowerCase(), (MonitoringUnit) PERCENTAGE);
+ }
+
+ private PercentageUnit(String percentageUnit) {
+ this.percentageUnit = percentageUnit;
+ }
+
+ public static MonitoringUnit getByName(String pu) {
+ pu = pu.toLowerCase();
+ return MAP.get(pu);
+ }
+
+ @Override
+ public String toString() {
+ return this.percentageUnit;
+ }
+
+ };
+
String toString();
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java
index 23215ce..d45d065 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java
@@ -29,32 +29,32 @@
MonitoringUnit unit();
/**
- * Time (ns) to parse the controller's deployment instruction.
+ * Time (default is ns) to parse the controller's deployment instruction.
*
- * @return time in nanoseconds to parse a 'deploy' command
+ * @return time to parse a 'deploy' command
*/
long deployCommandParsingTime();
/**
- * Time (ns) to launch a slave process in the dataplane.
+ * Time (default is ns) to launch a slave process in the dataplane.
*
- * @return time in nanoseconds to launch a 'deploy' command
+ * @return time to launch a 'deploy' command
*/
long deployCommandLaunchingTime();
/**
- * Time (ns) to parse + launch the controller's deployment instruction.
+ * Time (default is ns) to parse + launch the controller's deployment instruction.
* This is the sum of the above two timers.
*
- * @return time in nanoseconds to parse + launch a 'deploy' command
+ * @return time to parse + launch a 'deploy' command
*/
long totalDeploymentTime();
/**
- * Time (ns) to perform a local reconfiguration.
+ * Time (default is ns) to perform a local reconfiguration.
* (i.e., the agent auto-scales the number of CPUs).
*
- * @return time in nanoseconds to auto scale
+ * @return time to auto scale
*/
long autoScaleTime();
diff --git a/drivers/server/src/main/resources/app/view/memory/memory.css b/drivers/server/src/main/resources/app/view/memory/memory.css
new file mode 100644
index 0000000..243f3e5
--- /dev/null
+++ b/drivers/server/src/main/resources/app/view/memory/memory.css
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Memory UI -- CSS file
+ */
+
+#ov-memory {
+ padding: 20px;
+ position: relative;
+}
+
+.light #ov-memory {
+ color: navy;
+}
+.dark #ov-memory {
+ color: #88f;
+}
+
+#ov-memory .button-panel {
+ margin: 10px;
+ width: 200px;
+}
+
+.light #ov-memory .button-panel {
+ background-color: #ccf;
+}
+.dark #ov-memory .button-panel {
+ background-color: #444;
+}
+
+#ov-memory #chart-loader {
+ position: absolute;
+ width: 200px;
+ height: 50px;
+ margin-left: -100px;
+ margin-top: -25px;
+ z-index: 900;
+ top: 50%;
+ text-align: center;
+ left: 50%;
+ font-size: 25px;
+ font-weight: bold;
+ color: #ccc;
+}
\ No newline at end of file
diff --git a/drivers/server/src/main/resources/app/view/memory/memory.html b/drivers/server/src/main/resources/app/view/memory/memory.html
new file mode 100644
index 0000000..398a9fa
--- /dev/null
+++ b/drivers/server/src/main/resources/app/view/memory/memory.html
@@ -0,0 +1,27 @@
+<!-- partial HTML -->
+<div id="ov-memory">
+ <div id="chart-loader" ng-show="!devId && showLoader">
+ No Servers
+ </div>
+ <div ng-show="!devId">
+ <canvas id="bar" class="chart chart-bar" chart-data="data"
+ chart-labels="labels" chart-legend="true" chart-click="onClick"
+ chart-series="series" chart-options="options" height="100%">
+ </canvas>
+ </div>
+ <div ng-show="devId">
+ <h2>
+ Chart for Device {{devId || "(No device selected)"}}
+ </h2>
+ <div class="ctrl-btns">
+ <select ng-options="deviceId as deviceId for deviceId in deviceIds"
+ ng-model="selectedItem" ng-change="onChange(selectedItem)">
+ <option value="">-- select a device --</option>
+ </select>
+ </div>
+ <canvas id="line" class="chart chart-line" chart-data="data"
+ chart-labels="labels" chart-legend="true"
+ chart-series="series" chart-options="options" height="100%">
+ </canvas>
+ </div>
+</div>
diff --git a/drivers/server/src/main/resources/app/view/memory/memory.js b/drivers/server/src/main/resources/app/view/memory/memory.js
new file mode 100644
index 0000000..37c2eee
--- /dev/null
+++ b/drivers/server/src/main/resources/app/view/memory/memory.js
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Memory View Module
+ */
+(function () {
+ 'use strict';
+
+ // injected references
+ var $log, $scope, $location, ks, fs, cbs, ns;
+
+ var hasDeviceId;
+ var barsNb = 3;
+
+ var labels = new Array(1);
+ var data = new Array(barsNb);
+ for (var i = 0; i < barsNb; i++) {
+ data[i] = new Array(1);
+ data[i][0] = 0;
+ }
+
+ angular.module('ovMemory', ["chart.js"])
+ .controller('OvMemoryCtrl',
+ ['$log', '$scope', '$location', 'FnService', 'ChartBuilderService', 'NavService',
+
+ function (_$log_, _$scope_, _$location_, _fs_, _cbs_, _ns_) {
+ var params;
+ $log = _$log_;
+ $scope = _$scope_;
+ $location = _$location_;
+ fs = _fs_;
+ cbs = _cbs_;
+ ns = _ns_;
+
+ params = $location.search();
+
+ if (params.hasOwnProperty('devId')) {
+ $scope.devId = params['devId'];
+ hasDeviceId = true;
+ } else {
+ hasDeviceId = false;
+ }
+
+ cbs.buildChart({
+ scope: $scope,
+ tag: 'memory',
+ query: params
+ });
+
+ $scope.$watch('chartData', function () {
+ if (!fs.isEmptyObject($scope.chartData)) {
+ $scope.showLoader = false;
+ var length = $scope.chartData.length;
+ labels = new Array(length);
+ for (var i = 0; i < barsNb; i++) {
+ data[i] = new Array(length);
+ }
+
+ $scope.chartData.forEach(
+ function (cm, idx) {
+ data[0][idx] = cm.memory_used;
+ data[1][idx] = cm.memory_free;
+ data[2][idx] = cm.memory_total;
+
+ labels[idx] = cm.label;
+ }
+ );
+ }
+
+ $scope.labels = labels;
+ $scope.data = data;
+
+ $scope.options = {
+ scales: {
+ yAxes: [{
+ type: 'linear',
+ position: 'left',
+ id: 'y-axis-memory',
+ ticks: {
+ beginAtZero: true,
+ fontSize: 28,
+ },
+ scaleLabel: {
+ display: true,
+ labelString: 'Memory Utilization (GBytes)',
+ fontSize: 28,
+ }
+ }],
+ xAxes: [{
+ id: 'x-axis-servers',
+ ticks: {
+ fontSize: 28,
+ },
+ scaleLabel: {
+ display: false,
+ fontSize: 28,
+ }
+ }]
+ }
+ };
+
+ $scope.onClick = function (points, evt) {
+ var label = labels[points[0]._index];
+ if (label) {
+ ns.navTo('memory', { devId: label });
+ $log.log(label);
+ }
+ };
+
+ if (!fs.isEmptyObject($scope.annots)) {
+ $scope.deviceIds = JSON.parse($scope.annots.deviceIds);
+ }
+
+ $scope.onChange = function (deviceId) {
+ ns.navTo('memory', { devId: deviceId });
+ };
+ });
+
+ $scope.series = new Array(barsNb);
+ $scope.series[0] = 'Memory - Used';
+ $scope.series[1] = 'Memory - Free';
+ $scope.series[2] = 'Memory - Total';
+
+ $scope.labels = labels;
+ $scope.data = data;
+
+ $scope.showLoader = true;
+
+ $log.log('OvMemoryCtrl has been created');
+ }]);
+
+}());
diff --git a/drivers/server/src/main/resources/gui/css.html b/drivers/server/src/main/resources/gui/css.html
index 8eca7d4..b1cf4e5 100644
--- a/drivers/server/src/main/resources/gui/css.html
+++ b/drivers/server/src/main/resources/gui/css.html
@@ -1,3 +1,4 @@
<link rel="stylesheet" href="app/view/cpu/cpu.css">
+<link rel="stylesheet" href="app/view/memory/memory.css">
<link rel="stylesheet" href="app/view/latency/latency.css">
<link rel="stylesheet" href="app/view/throughput/throughput.css">
diff --git a/drivers/server/src/main/resources/gui/js.html b/drivers/server/src/main/resources/gui/js.html
index 99a84e8..94ec76b 100644
--- a/drivers/server/src/main/resources/gui/js.html
+++ b/drivers/server/src/main/resources/gui/js.html
@@ -1,3 +1,4 @@
<script src="app/view/cpu/cpu.js"></script>
+<script src="app/view/memory/memory.js"></script>
<script src="app/view/latency/latency.js"></script>
<script src="app/view/throughput/throughput.js"></script>
diff --git a/drivers/server/src/main/resources/server-drivers.xml b/drivers/server/src/main/resources/server-drivers.xml
index 11c75d1..a8a07cd 100644
--- a/drivers/server/src/main/resources/server-drivers.xml
+++ b/drivers/server/src/main/resources/server-drivers.xml
@@ -15,7 +15,13 @@
~ limitations under the License.
-->
<drivers>
- <driver name="restServer" extends="default" manufacturer="GenuineIntel" hwVersion="Intel(R) Xeon(R) CPU E5-2667 v3 @ 3.20GHz" swVersion="Click 2.1">
+ <driver name="rest-server" manufacturer="Unknown" hwVersion="Unknown" swVersion="Unknown" extends="default">
+ <behaviour api="org.onosproject.net.behaviour.BasicSystemOperations"
+ impl="org.onosproject.drivers.server.ServerBasicSystemOperations"/>
+
+ <behaviour api="org.onosproject.net.device.DeviceHandshaker"
+ impl="org.onosproject.drivers.server.ServerHandshaker"/>
+
<behaviour api="org.onosproject.net.behaviour.DevicesDiscovery"
impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
@@ -28,16 +34,38 @@
<behaviour api="org.onosproject.net.device.PortStatisticsDiscovery"
impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
+ <behaviour api="org.onosproject.net.behaviour.PortAdmin"
+ impl="org.onosproject.drivers.server.ServerPortAdmin"/>
+
+ <behaviour api="org.onosproject.net.behaviour.InterfaceConfig"
+ impl="org.onosproject.drivers.server.ServerInterfaceConfig"/>
+
<behaviour api="org.onosproject.drivers.server.behavior.CpuStatisticsDiscovery"
impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
<behaviour api="org.onosproject.drivers.server.behavior.MonitoringStatisticsDiscovery"
impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
+ <behaviour api="org.onosproject.net.behaviour.DeviceSystemStatisticsQuery"
+ impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
+
<behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
impl="org.onosproject.drivers.server.FlowRuleProgrammableServerImpl"/>
+
+ <behaviour api="org.onosproject.net.behaviour.TableStatisticsDiscovery"
+ impl="org.onosproject.drivers.server.ServerTableStatisticsDiscovery"/>
+
+ <behaviour api="org.onosproject.net.behaviour.QueueConfigBehaviour"
+ impl="org.onosproject.drivers.server.ServerQueueConfig"/>
+
<property name="ruleDeleteBatchSize">500</property>
</driver>
+
+ <driver name="rest-server-intel" manufacturer="GenuineIntel" hwVersion="Unknown" swVersion="Click 2.1" extends="rest-server">
+ </driver>
+
+ <driver name="rest-server-amd" manufacturer="AuthenticAMD" hwVersion="Unknown" swVersion="Click 2.1" extends="rest-server">
+ </driver>
</drivers>
diff --git a/drivers/server/src/test/java/org/onosproject/drivers/server/RestSBControllerMock.java b/drivers/server/src/test/java/org/onosproject/drivers/server/RestSBControllerMock.java
index 265432b..6e8df34 100644
--- a/drivers/server/src/test/java/org/onosproject/drivers/server/RestSBControllerMock.java
+++ b/drivers/server/src/test/java/org/onosproject/drivers/server/RestSBControllerMock.java
@@ -40,6 +40,10 @@
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL_IP;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL_PORT;
+import static org.onosproject.drivers.server.Constants.PARAM_CTRL_TYPE;
/**
* Test class for REST SB controller.
@@ -57,14 +61,6 @@
private RestSBDevice restDevice1;
private static List<ControllerInfo> controllers;
- /**
- * Parameters to be exchanged with the server's agent.
- */
- private static final String PARAM_CTRL = "controllers";
- private static final String PARAM_CTRL_IP = "ip";
- private static final String PARAM_CTRL_PORT = "port";
- private static final String PARAM_CTRL_TYPE = "type";
-
public RestSBControllerMock() {
restDeviceId1 = TestConfig.REST_DEV_ID1;
assertThat(restDeviceId1, notNullValue());
@@ -190,4 +186,5 @@
public int cancelServerSentEvents(DeviceId deviceId) {
return 200;
}
+
}
\ No newline at end of file
diff --git a/drivers/server/src/test/java/org/onosproject/drivers/server/ServerControllerConfigTest.java b/drivers/server/src/test/java/org/onosproject/drivers/server/ServerControllerConfigTest.java
index add6e03..54e6196 100644
--- a/drivers/server/src/test/java/org/onosproject/drivers/server/ServerControllerConfigTest.java
+++ b/drivers/server/src/test/java/org/onosproject/drivers/server/ServerControllerConfigTest.java
@@ -44,15 +44,7 @@
*/
public class ServerControllerConfigTest {
- // Device information used during the tests
- private static final String REST_SCHEME = "rest";
- private static final String REST_DEV_TEST_IP_1 = "10.0.0.1";
- private static final int REST_TEST_PORT = 80;
-
// Controller information used during the tests
- private static final String REST_CTRL_TEST_IP_1 = "10.0.0.253";
- private static final String REST_CTRL_TEST_IP_2 = "10.0.0.254";
- private static final String REST_CTRL_TEST_TYPE = "tcp";
private static List<ControllerInfo> controllers;
// Device used during the tests