Cherry pick gNMI and Stratum related changes to this branch
Cherry picked commits:
20211 Update gNMI version and build script
20247 [ONOS-7829] Implement AbstractGrpcClient and AbstractGrpcClientControl
20233 [ONOS-7141][ONOS-7142] Add GnmiClient and GnmiController
20234 Refactor OpenConfig gNMI device description descovery
20260 [ONOS-7831] Implement GnmiHandshaker
20270 Add Stratum driver
Change-Id: I81ad8bce45251af5909cfcac0edbcfd11c8ebf1d
diff --git a/drivers/gnmi/BUILD b/drivers/gnmi/BUILD
index 4a4c100..efc3f08 100644
--- a/drivers/gnmi/BUILD
+++ b/drivers/gnmi/BUILD
@@ -28,7 +28,6 @@
included_bundles = BUNDLES,
required_apps = [
"org.onosproject.generaldeviceprovider",
- "org.onosproject.protocols.grpc",
"org.onosproject.protocols.gnmi",
],
title = "gNMI Drivers",
diff --git a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/AbstractGnmiHandlerBehaviour.java b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/AbstractGnmiHandlerBehaviour.java
index e6d8b16..3bfca46 100644
--- a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/AbstractGnmiHandlerBehaviour.java
+++ b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/AbstractGnmiHandlerBehaviour.java
@@ -41,9 +41,8 @@
private static final String DEVICE_REQ_TIMEOUT = "deviceRequestTimeout";
private static final int DEFAULT_DEVICE_REQ_TIMEOUT = 60;
- public static final String GNMI_SERVER_ADDR_KEY = "gnmi_ip";
- public static final String GNMI_SERVER_PORT_KEY = "gnmi_port";
- private static final String GNMI_SERVICE_NAME = "gnmi";
+ private static final String GNMI_SERVER_ADDR_KEY = "gnmi_ip";
+ private static final String GNMI_SERVER_PORT_KEY = "gnmi_port";
protected final Logger log = LoggerFactory.getLogger(getClass());
protected DeviceId deviceId;
@@ -66,7 +65,7 @@
return true;
}
- protected GnmiClient createClient() {
+ GnmiClient createClient() {
deviceId = handler().data().deviceId();
controller = handler().get(GnmiController.class);
@@ -74,7 +73,7 @@
final String serverPortString = this.data().value(GNMI_SERVER_PORT_KEY);
if (serverAddr == null || serverPortString == null) {
- log.warn("Unable to create client for {}, missing driver data key (required is {}, {}, and {})",
+ log.warn("Unable to create client for {}, missing driver data key (required is {} and {})",
deviceId, GNMI_SERVER_ADDR_KEY, GNMI_SERVER_PORT_KEY);
return null;
}
@@ -83,11 +82,10 @@
try {
serverPort = Integer.parseUnsignedInt(serverPortString);
} catch (NumberFormatException e) {
- log.error("{} is not a valid gNMI port number", serverPortString);
+ log.error("{} is not a valid port number", serverPortString);
return null;
}
- GnmiClientKey clientKey =
- new GnmiClientKey(GNMI_SERVICE_NAME, deviceId, serverAddr, serverPort);
+ GnmiClientKey clientKey = new GnmiClientKey(deviceId, serverAddr, serverPort);
if (!controller.createClient(clientKey)) {
log.warn("Unable to create client for {}, aborting operation", deviceId);
return null;
diff --git a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/GnmiHandshaker.java b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/GnmiHandshaker.java
index d1ee1b8..c443460 100644
--- a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/GnmiHandshaker.java
+++ b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/GnmiHandshaker.java
@@ -77,7 +77,9 @@
return false;
}
- return getFutureWithDeadline(client.isServiceAvailable(), "getting availability", false);
+ return getFutureWithDeadline(
+ client.isServiceAvailable(),
+ "checking if gNMI service is available", false);
}
@Override
diff --git a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java
index f9d2236..526c333 100644
--- a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java
+++ b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java
@@ -30,13 +30,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import static gnmi.Gnmi.Path;
import static gnmi.Gnmi.PathElem;
@@ -50,8 +46,6 @@
extends AbstractGnmiHandlerBehaviour
implements DeviceDescriptionDiscovery {
- private static final int REQUEST_TIMEOUT_SECONDS = 5;
-
private static final Logger log = LoggerFactory
.getLogger(OpenConfigGnmiDeviceDescriptionDiscovery.class);
@@ -67,18 +61,12 @@
}
log.debug("Discovering port details on device {}", handler().data().deviceId());
- GetResponse response;
- try {
- response = client.get(buildPortStateRequest())
- .get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- log.warn("Unable to discover ports from {}: {}", deviceId, e.getMessage());
- log.debug("{}", e);
- return Collections.emptyList();
- }
+ final GetResponse response = getFutureWithDeadline(
+ client.get(buildPortStateRequest()),
+ "getting port details", GetResponse.getDefaultInstance());
- Map<String, DefaultPortDescription.Builder> ports = Maps.newHashMap();
- Map<String, DefaultAnnotations.Builder> annotations = Maps.newHashMap();
+ final Map<String, DefaultPortDescription.Builder> ports = Maps.newHashMap();
+ final Map<String, DefaultAnnotations.Builder> annotations = Maps.newHashMap();
// Creates port descriptions with port name and port number
response.getNotificationList()
@@ -86,19 +74,18 @@
.flatMap(notification -> notification.getUpdateList().stream())
.forEach(update -> {
// /interfaces/interface[name=ifName]/state/...
- String ifName = update.getPath().getElem(1).getKeyMap().get("name");
+ final String ifName = update.getPath().getElem(1)
+ .getKeyMap().get("name");
if (!ports.containsKey(ifName)) {
ports.put(ifName, DefaultPortDescription.builder());
annotations.put(ifName, DefaultAnnotations.builder());
}
-
-
- DefaultPortDescription.Builder builder = ports.get(ifName);
- DefaultAnnotations.Builder annotationsBuilder = annotations.get(ifName);
+ final DefaultPortDescription.Builder builder = ports.get(ifName);
+ final DefaultAnnotations.Builder annotationsBuilder = annotations.get(ifName);
parseInterfaceInfo(update, ifName, builder, annotationsBuilder);
});
- List<PortDescription> portDescriptionList = Lists.newArrayList();
+ final List<PortDescription> portDescriptionList = Lists.newArrayList();
ports.forEach((key, value) -> {
DefaultAnnotations annotation = annotations.get(key).build();
portDescriptionList.add(value.annotations(annotation).build());
@@ -122,7 +109,7 @@
/**
* Parses the interface information.
*
- * @param update the update received
+ * @param update the update received
*/
private void parseInterfaceInfo(Update update,
String ifName,
@@ -130,45 +117,32 @@
DefaultAnnotations.Builder annotationsBuilder) {
- Path path = update.getPath();
- List<PathElem> elems = path.getElemList();
- Gnmi.TypedValue val = update.getVal();
+ final Path path = update.getPath();
+ final List<PathElem> elems = path.getElemList();
+ final Gnmi.TypedValue val = update.getVal();
if (elems.size() == 4) {
// /interfaces/interface/state/ifindex
// /interfaces/interface/state/oper-status
- String pathElemName = elems.get(3).getName();
+ final String pathElemName = elems.get(3).getName();
switch (pathElemName) {
case "ifindex": // port number
builder.withPortNumber(PortNumber.portNumber(val.getUintVal(), ifName));
- break;
+ return;
case "oper-status":
builder.isEnabled(parseOperStatus(val.getStringVal()));
- break;
+ return;
default:
- String valueString = val.toByteString().toString(Charset.defaultCharset()).trim();
- if (!valueString.isEmpty()) {
- annotationsBuilder.set(pathElemName, valueString);
- }
- log.debug("Unknown path: {}", path);
break;
}
- }
- if (elems.size() == 5) {
+ } else if (elems.size() == 5) {
// /interfaces/interface/ethernet/config/port-speed
- String pathElemName = elems.get(4).getName();
- switch (pathElemName) {
- case "port-speed":
- builder.portSpeed(parsePortSpeed(val.getStringVal()));
- break;
- default:
- String valueString = val.toByteString().toString(Charset.defaultCharset()).trim();
- if (!valueString.isEmpty()) {
- annotationsBuilder.set(pathElemName, valueString);
- }
- log.debug("Unknown path: {}", path);
- break;
+ final String pathElemName = elems.get(4).getName();
+ if (pathElemName.equals("port-speed")) {
+ builder.portSpeed(parsePortSpeed(val.getStringVal()));
+ return;
}
}
+ log.debug("Unknown path when parsing interface info: {}", path);
}
private boolean parseOperStatus(String operStatus) {
@@ -201,6 +175,7 @@
case "SPEED_100GB":
return 100000;
default:
+ log.warn("Unrecognized port speed string '{}'", speed);
return 1000;
}
}
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/AbstractP4RuntimeHandlerBehaviour.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/AbstractP4RuntimeHandlerBehaviour.java
index 90e7a31..7f9c8c6 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/AbstractP4RuntimeHandlerBehaviour.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/AbstractP4RuntimeHandlerBehaviour.java
@@ -48,9 +48,9 @@
private static final String DEVICE_REQ_TIMEOUT = "deviceRequestTimeout";
private static final int DEFAULT_DEVICE_REQ_TIMEOUT = 60;
- public static final String P4RUNTIME_SERVER_ADDR_KEY = "p4runtime_ip";
- public static final String P4RUNTIME_SERVER_PORT_KEY = "p4runtime_port";
- public static final String P4RUNTIME_DEVICE_ID_KEY = "p4runtime_deviceId";
+ private static final String P4RUNTIME_SERVER_ADDR_KEY = "p4runtime_ip";
+ private static final String P4RUNTIME_SERVER_PORT_KEY = "p4runtime_port";
+ private static final String P4RUNTIME_DEVICE_ID_KEY = "p4runtime_deviceId";
protected final Logger log = LoggerFactory.getLogger(getClass());
@@ -61,7 +61,7 @@
protected P4RuntimeController controller;
protected PiPipeconf pipeconf;
protected P4RuntimeClient client;
- protected PiTranslationService piTranslationService;
+ protected PiTranslationService translationService;
/**
* Initializes this behaviour attributes. Returns true if the operation was
@@ -102,7 +102,7 @@
}
pipeconf = piPipeconfService.getPipeconf(pipeconfId).get();
- piTranslationService = handler().get(PiTranslationService.class);
+ translationService = handler().get(PiTranslationService.class);
return true;
}
@@ -158,8 +158,8 @@
return null;
}
- P4RuntimeClientKey clientKey = new
- P4RuntimeClientKey(deviceId, serverAddr, serverPort, p4DeviceId);
+ final P4RuntimeClientKey clientKey = new P4RuntimeClientKey(
+ deviceId, serverAddr, serverPort, p4DeviceId);
if (!controller.createClient(clientKey)) {
log.warn("Unable to create client for {}, aborting operation", deviceId);
return null;
@@ -176,7 +176,7 @@
* @param defaultVal default value
* @return boolean
*/
- protected boolean driverBoolProperty(String propName, boolean defaultVal) {
+ boolean driverBoolProperty(String propName, boolean defaultVal) {
checkNotNull(propName);
if (handler().driver().getProperty(propName) == null) {
return defaultVal;
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeActionGroupProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeActionGroupProgrammable.java
index 45be79e..c20c899 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeActionGroupProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeActionGroupProgrammable.java
@@ -96,7 +96,7 @@
groupMirror = this.handler().get(P4RuntimeGroupMirror.class);
memberMirror = this.handler().get(P4RuntimeActionProfileMemberMirror.class);
groupStore = handler().get(GroupStore.class);
- groupTranslator = piTranslationService.groupTranslator();
+ groupTranslator = translationService.groupTranslator();
return true;
}
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
index 5a233ef..693353f 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
@@ -118,7 +118,7 @@
pipelineModel = pipeconf.pipelineModel();
tableMirror = handler().get(P4RuntimeTableMirror.class);
- translator = piTranslationService.flowRuleTranslator();
+ translator = translationService.flowRuleTranslator();
return true;
}
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java
index 39ed84d..f2dff80 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java
@@ -74,7 +74,7 @@
return false;
}
- translator = piTranslationService.meterTranslator();
+ translator = translationService.meterTranslator();
meterMirror = handler().get(P4RuntimeMeterMirror.class);
pipelineModel = pipeconf.pipelineModel();
return true;
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMulticastGroupProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMulticastGroupProgrammable.java
index a5c3538..ecdda08 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMulticastGroupProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMulticastGroupProgrammable.java
@@ -66,7 +66,7 @@
}
mcGroupMirror = this.handler().get(P4RuntimeMulticastGroupMirror.class);
groupStore = handler().get(GroupStore.class);
- mcGroupTranslator = piTranslationService.multicastGroupTranslator();
+ mcGroupTranslator = translationService.multicastGroupTranslator();
return true;
}
diff --git a/drivers/stratum/BUILD b/drivers/stratum/BUILD
new file mode 100644
index 0000000..41db9f1
--- /dev/null
+++ b/drivers/stratum/BUILD
@@ -0,0 +1,25 @@
+COMPILE_DEPS = CORE_DEPS + KRYO + JACKSON + [
+ "@io_grpc_grpc_java//core",
+ "//drivers/p4runtime:onos-drivers-p4runtime",
+ "//drivers/gnmi:onos-drivers-gnmi",
+ "//pipelines/basic:onos-pipelines-basic",
+]
+
+osgi_jar(
+ resources = glob(["src/main/resources/**"]),
+ resources_root = "src/main/resources",
+ deps = COMPILE_DEPS,
+)
+
+onos_app(
+ app_name = "org.onosproject.drivers.stratum",
+ category = "Drivers",
+ description = "Adds support for Stratum-based devices",
+ required_apps = [
+ "org.onosproject.generaldeviceprovider",
+ "org.onosproject.drivers.gnmi",
+ "org.onosproject.drivers.p4runtime",
+ ],
+ title = "Stratum Drivers",
+ url = "http://onosproject.org",
+)
diff --git a/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/StratumDriversLoader.java b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/StratumDriversLoader.java
new file mode 100644
index 0000000..a68729a
--- /dev/null
+++ b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/StratumDriversLoader.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018-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.stratum;
+
+import org.onosproject.net.driver.AbstractDriverLoader;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * Loader for Stratum Switch device drivers.
+ */
+@Component(immediate = true)
+public class StratumDriversLoader extends AbstractDriverLoader {
+
+ public StratumDriversLoader() {
+ super("/stratum-drivers.xml");
+ }
+}
diff --git a/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/StratumHandshaker.java b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/StratumHandshaker.java
new file mode 100644
index 0000000..4e169a5
--- /dev/null
+++ b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/StratumHandshaker.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018-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.stratum;
+
+import io.grpc.StatusRuntimeException;
+import org.onosproject.drivers.gnmi.GnmiHandshaker;
+import org.onosproject.drivers.p4runtime.P4RuntimeHandshaker;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.device.DeviceAgentListener;
+import org.onosproject.net.device.DeviceHandshaker;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Implementation of DeviceHandshaker for Stratum device.
+ */
+public class StratumHandshaker extends AbstractHandlerBehaviour implements DeviceHandshaker {
+
+ private static final Logger log = LoggerFactory.getLogger(StratumHandshaker.class);
+ private static final int DEFAULT_DEVICE_REQ_TIMEOUT = 10;
+
+ private P4RuntimeHandshaker p4RuntimeHandshaker;
+ private GnmiHandshaker gnmiHandshaker;
+ private DeviceId deviceId;
+
+ public StratumHandshaker() {
+ p4RuntimeHandshaker = new P4RuntimeHandshaker();
+ gnmiHandshaker = new GnmiHandshaker();
+ }
+
+ @Override
+ public void setHandler(DriverHandler handler) {
+ super.setHandler(handler);
+ p4RuntimeHandshaker.setHandler(handler);
+ gnmiHandshaker.setHandler(handler);
+ }
+
+ @Override
+ public void setData(DriverData data) {
+ super.setData(data);
+ p4RuntimeHandshaker.setData(data);
+ gnmiHandshaker.setData(data);
+ deviceId = data.deviceId();
+ }
+
+ @Override
+ public CompletableFuture<Boolean> isReachable() {
+ return p4RuntimeHandshaker.isReachable()
+ .thenCombine(gnmiHandshaker.isReachable(), Boolean::logicalAnd);
+ }
+
+ @Override
+ public void roleChanged(MastershipRole newRole) {
+ p4RuntimeHandshaker.roleChanged(newRole);
+ // gNMI doesn't support mastership handling.
+ }
+
+ @Override
+ public MastershipRole getRole() {
+ return p4RuntimeHandshaker.getRole();
+ }
+
+ @Override
+ public void addDeviceAgentListener(ProviderId providerId, DeviceAgentListener listener) {
+ p4RuntimeHandshaker.addDeviceAgentListener(providerId, listener);
+ }
+
+ @Override
+ public void removeDeviceAgentListener(ProviderId providerId) {
+ p4RuntimeHandshaker.removeDeviceAgentListener(providerId);
+ }
+
+ @Override
+ public CompletableFuture<Boolean> connect() {
+ return p4RuntimeHandshaker.connect()
+ .thenCombine(gnmiHandshaker.connect(), Boolean::logicalAnd);
+ }
+
+ @Override
+ public boolean isConnected() {
+ final CompletableFuture<Boolean> p4runtimeConnected =
+ CompletableFuture.supplyAsync(p4RuntimeHandshaker::isConnected);
+ final CompletableFuture<Boolean> gnmiConnected =
+ CompletableFuture.supplyAsync(gnmiHandshaker::isConnected);
+
+ try {
+ return p4runtimeConnected
+ .thenCombine(gnmiConnected, Boolean::logicalAnd)
+ .get(DEFAULT_DEVICE_REQ_TIMEOUT, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ log.error("Exception while checking connectivity on {}", data().deviceId());
+ } catch (ExecutionException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof StatusRuntimeException) {
+ final StatusRuntimeException grpcError = (StatusRuntimeException) cause;
+ log.warn("Error while checking connectivity on {}: {}", deviceId, grpcError.getMessage());
+ } else {
+ log.error("Exception while checking connectivity on {}", deviceId, e.getCause());
+ }
+ } catch (TimeoutException e) {
+ log.error("Operation TIMEOUT while checking connectivity on {}", deviceId);
+ }
+ return false;
+ }
+
+ @Override
+ public CompletableFuture<Boolean> disconnect() {
+ return p4RuntimeHandshaker.disconnect()
+ .thenCombine(gnmiHandshaker.disconnect(), Boolean::logicalAnd);
+ }
+}
diff --git a/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/dummy/StratumDummyPipelineProgrammable.java b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/dummy/StratumDummyPipelineProgrammable.java
new file mode 100644
index 0000000..e07e3b3
--- /dev/null
+++ b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/dummy/StratumDummyPipelineProgrammable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018-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.stratum.dummy;
+
+import org.onosproject.drivers.p4runtime.AbstractP4RuntimePipelineProgrammable;
+import org.onosproject.net.behaviour.PiPipelineProgrammable;
+import org.onosproject.net.pi.model.PiPipeconf;
+import org.onosproject.pipelines.basic.PipeconfLoader;
+
+import java.nio.ByteBuffer;
+import java.util.Optional;
+
+/**
+ * Implementation of the PiPipelineProgrammable behavior for Dummy Stratum Switch.
+ */
+public class StratumDummyPipelineProgrammable
+ extends AbstractP4RuntimePipelineProgrammable
+ implements PiPipelineProgrammable {
+
+ @Override
+ public ByteBuffer createDeviceDataBuffer(PiPipeconf pipeconf) {
+ // No pipeline binary needed
+ return ByteBuffer.allocate(1);
+ }
+
+ @Override
+ public Optional<PiPipeconf> getDefaultPipeconf() {
+ return Optional.of(PipeconfLoader.BASIC_PIPECONF);
+ }
+}
diff --git a/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/dummy/package-info.java b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/dummy/package-info.java
new file mode 100644
index 0000000..7633706
--- /dev/null
+++ b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/dummy/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2018-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.
+ */
+
+/**
+ * Behaviours for Dummy Stratum Device.
+ */
+
+package org.onosproject.drivers.stratum.dummy;
diff --git a/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/package-info.java b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/package-info.java
new file mode 100644
index 0000000..145022a
--- /dev/null
+++ b/drivers/stratum/src/main/java/org/onosproject/drivers/stratum/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-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.
+ */
+
+/**
+ * Driver for Stratum devices.
+ */
+package org.onosproject.drivers.stratum;
diff --git a/drivers/stratum/src/main/resources/stratum-drivers.xml b/drivers/stratum/src/main/resources/stratum-drivers.xml
new file mode 100644
index 0000000..83fea1d
--- /dev/null
+++ b/drivers/stratum/src/main/resources/stratum-drivers.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2017-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.
+ -->
+<drivers>
+ <driver name="stratum" manufacturer="Open Networking Foundation"
+ hwVersion="master" swVersion="Stratum" extends="p4runtime,gnmi">
+ <behaviour api="org.onosproject.net.device.DeviceHandshaker"
+ impl="org.onosproject.drivers.stratum.StratumHandshaker"/>
+ </driver>
+
+ <driver name="stratum-dummy" manufacturer="Open Networking Foundation"
+ hwVersion="Dummy" swVersion="Stratum" extends="stratum">
+ <behaviour api="org.onosproject.net.behaviour.PiPipelineProgrammable"
+ impl="org.onosproject.drivers.stratum.dummy.StratumDummyPipelineProgrammable"/>
+ <property name="tableReadFromMirror">true</property>
+ <property name="actionGroupReadFromMirror">true</property>
+ </driver>
+</drivers>
+
diff --git a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClient.java b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClient.java
index 242bc94..5beb238 100644
--- a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClient.java
+++ b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClient.java
@@ -17,10 +17,9 @@
package org.onosproject.gnmi.api;
import com.google.common.annotations.Beta;
-
import gnmi.Gnmi.CapabilityResponse;
-import gnmi.Gnmi.GetResponse;
import gnmi.Gnmi.GetRequest;
+import gnmi.Gnmi.GetResponse;
import gnmi.Gnmi.SetRequest;
import gnmi.Gnmi.SetResponse;
import org.onosproject.grpc.api.GrpcClient;
@@ -34,15 +33,14 @@
public interface GnmiClient extends GrpcClient {
/**
- * Gets capability from a target. This allows device driver behavior
- * to validate the service version and models which gNMI device supported.
+ * Gets capability from a target.
*
* @return the capability response
*/
CompletableFuture<CapabilityResponse> capability();
/**
- * Retrieve a snapshot of data from the device.
+ * Retrieves a snapshot of data from the device.
*
* @param request the get request
* @return the snapshot of data from the device
diff --git a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java
index 26ce113..bc18b9a 100644
--- a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java
+++ b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java
@@ -26,15 +26,16 @@
@Beta
public class GnmiClientKey extends GrpcClientKey {
+ private static final String GNMI = "gnmi";
+
/**
* Creates a new gNMI client key.
*
- * @param serviceName gNMI service name of the client
* @param deviceId ONOS device ID
* @param serverAddr gNMI server address
* @param serverPort gNMI server port
*/
- public GnmiClientKey(String serviceName, DeviceId deviceId, String serverAddr, int serverPort) {
- super(serviceName, deviceId, serverAddr, serverPort);
+ public GnmiClientKey(DeviceId deviceId, String serverAddr, int serverPort) {
+ super(GNMI, deviceId, serverAddr, serverPort);
}
}
diff --git a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java
index b8179a9..22b226b 100644
--- a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java
+++ b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java
@@ -27,10 +27,10 @@
import io.grpc.ManagedChannel;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
+import org.onosproject.gnmi.api.GnmiClient;
import org.onosproject.gnmi.api.GnmiClientKey;
import org.onosproject.grpc.ctl.AbstractGrpcClient;
import org.slf4j.Logger;
-import org.onosproject.gnmi.api.GnmiClient;
import java.util.concurrent.CompletableFuture;
@@ -46,8 +46,8 @@
private final Logger log = getLogger(getClass());
private final gNMIGrpc.gNMIBlockingStub blockingStub;
- public GnmiClientImpl(GnmiClientKey clientKey, ManagedChannel managedChannel) {
- super(clientKey, managedChannel);
+ GnmiClientImpl(GnmiClientKey clientKey, ManagedChannel managedChannel) {
+ super(clientKey);
this.blockingStub = gNMIGrpc.newBlockingStub(managedChannel);
}
@@ -101,8 +101,7 @@
private boolean doServiceAvailable() {
try {
- blockingStub.get(DUMMY_REQUEST);
- return true;
+ return blockingStub.get(DUMMY_REQUEST) != null;
} catch (StatusRuntimeException e) {
// This gRPC call should throw INVALID_ARGUMENT status exception
// since "/onos-gnmi-test" path does not exists in any config model
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcClientController.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcClientController.java
index 2e3ea5d..3cdbcd1 100644
--- a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcClientController.java
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcClientController.java
@@ -20,8 +20,8 @@
import org.onosproject.net.DeviceId;
/**
- * Abstraction of a gRPC controller which controls specific gRPC
- * client {@link C} with specific client key {@link K}.
+ * Abstraction of a gRPC controller which controls specific gRPC client {@link
+ * C} with specific client key {@link K}.
*
* @param <K> the gRPC client key
* @param <C> the gRPC client type
@@ -30,19 +30,19 @@
public interface GrpcClientController<K extends GrpcClientKey, C extends GrpcClient> {
/**
- * Instantiates a new client to operate on a gRPC server identified by
- * the given information. As a result of this method, a client can be later
+ * Instantiates a new client to operate on a gRPC server identified by the
+ * given information. As a result of this method, a client can be later
* obtained by invoking {@link #getClient(DeviceId)}.
- *
- * Only one client can exist for the same device ID. Calls to this method are
- * idempotent fot the same client key, i.e. returns true
- * if such client already exists but a new one is not created.
- * If there exists a client with same device ID but different address and port,
- * removes old one and recreate new one.
+ * <p>
+ * Only one client can exist for the same device ID. Calls to this method
+ * are idempotent fot the same client key, i.e. returns true if such client
+ * already exists but a new one is not created. If there exists a client
+ * with same device ID but different address and port, removes old one and
+ * recreate new one.
*
* @param clientKey the client key
- * @return true if the client was created and the channel to the server is open;
- * false otherwise
+ * @return true if the client was created and the channel to the server is
+ * open; false otherwise
*/
boolean createClient(K clientKey);
@@ -55,8 +55,8 @@
C getClient(DeviceId deviceId);
/**
- * Removes the gRPC client for the given device. If no client
- * exists for the given device, the result is a no-op.
+ * Removes the gRPC client for the given device. If no client exists for the
+ * given device, the result is a no-op.
*
* @param deviceId the device identifier
*/
@@ -64,15 +64,15 @@
/**
* Check reachability of the gRPC server running on the given device.
- * Reachability can be tested only if a client is previously created
- * using {@link #createClient(GrpcClientKey)}.
- * Note that this only checks the reachability instead of checking service
- * availability, different gRPC client checks service availability with
+ * Reachability can be tested only if a client is previously created using
+ * {@link #createClient(GrpcClientKey)}. Note that this only checks the
+ * reachability instead of checking service availability, different
+ * service-specific gRPC clients might check service availability in a
* different way.
*
* @param deviceId the device identifier
- * @return true if client was created and is able to contact the gNMI server;
- * false otherwise
+ * @return true if client was created and is able to contact the gNMI
+ * server; false otherwise
*/
boolean isReachable(DeviceId deviceId);
}
diff --git a/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClient.java b/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClient.java
index 4764a56..05e2978 100644
--- a/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClient.java
+++ b/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClient.java
@@ -17,7 +17,6 @@
package org.onosproject.grpc.ctl;
import io.grpc.Context;
-import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;
import org.onlab.util.SharedExecutors;
import org.onosproject.grpc.api.GrpcClient;
@@ -25,7 +24,6 @@
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
-
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@@ -45,26 +43,24 @@
public abstract class AbstractGrpcClient implements GrpcClient {
// Timeout in seconds to obtain the request lock.
- protected static final int LOCK_TIMEOUT = 60;
+ private static final int LOCK_TIMEOUT = 60;
private static final int DEFAULT_THREAD_POOL_SIZE = 10;
protected final Logger log = getLogger(getClass());
- protected final Lock requestLock = new ReentrantLock();
- protected final Context.CancellableContext cancellableContext =
+ private final Lock requestLock = new ReentrantLock();
+ private final Context.CancellableContext cancellableContext =
Context.current().withCancellation();
+ private final Executor contextExecutor;
+
protected final ExecutorService executorService;
- protected final Executor contextExecutor;
+ protected final DeviceId deviceId;
- protected ManagedChannel channel;
- protected DeviceId deviceId;
-
- protected AbstractGrpcClient(GrpcClientKey clientKey, ManagedChannel channel) {
+ protected AbstractGrpcClient(GrpcClientKey clientKey) {
this.deviceId = clientKey.deviceId();
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE, groupedThreads(
"onos-grpc-" + clientKey.serviceName() + "-client-" + deviceId.toString(), "%d"));
this.contextExecutor = this.cancellableContext.fixedContextExecutor(executorService);
- this.channel = channel;
}
@Override
@@ -112,7 +108,7 @@
* @param executor the executor to execute this supplier
* @return CompletableFuture includes the result of supplier
*/
- protected <U> CompletableFuture<U> supplyWithExecutor(
+ private <U> CompletableFuture<U> supplyWithExecutor(
Supplier<U> supplier, String opDescription, Executor executor) {
return CompletableFuture.supplyAsync(() -> {
// TODO: explore a more relaxed locking strategy.
diff --git a/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClientController.java b/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClientController.java
index 36e453c..bf2bbf1 100644
--- a/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClientController.java
+++ b/protocols/grpc/ctl/src/main/java/org/onosproject/grpc/ctl/AbstractGrpcClientController.java
@@ -21,7 +21,6 @@
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.netty.NettyChannelBuilder;
-
import org.onosproject.event.AbstractListenerManager;
import org.onosproject.event.Event;
import org.onosproject.event.EventListener;
@@ -152,7 +151,7 @@
return withDeviceLock(() -> doGetClient(deviceId), deviceId);
}
- protected C doGetClient(DeviceId deviceId) {
+ private C doGetClient(DeviceId deviceId) {
if (!clientKeys.containsKey(deviceId)) {
return null;
}
@@ -183,7 +182,7 @@
return withDeviceLock(() -> doIsReachable(deviceId), deviceId);
}
- protected boolean doIsReachable(DeviceId deviceId) {
+ private boolean doIsReachable(DeviceId deviceId) {
// Default behaviour checks only the gRPC channel, should
// check according to different gRPC service
if (!clientKeys.containsKey(deviceId)) {
diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
index 53f7668..d5080ae 100644
--- a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
+++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
@@ -138,7 +138,7 @@
P4RuntimeClientImpl(P4RuntimeClientKey clientKey, ManagedChannel channel,
P4RuntimeControllerImpl controller) {
- super(clientKey, channel);
+ super(clientKey);
this.p4DeviceId = clientKey.p4DeviceId();
this.controller = controller;
diff --git a/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java b/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java
index 4374089..3ca56ee 100644
--- a/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java
+++ b/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java
@@ -106,7 +106,12 @@
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.device.DeviceEvent.Type;
-import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.*;
+import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.OP_TIMEOUT_SHORT;
+import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.OP_TIMEOUT_SHORT_DEFAULT;
+import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.PROBE_FREQUENCY;
+import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.PROBE_FREQUENCY_DEFAULT;
+import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.STATS_POLL_FREQUENCY;
+import static org.onosproject.provider.general.device.impl.OsgiPropertyConstants.STATS_POLL_FREQUENCY_DEFAULT;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -498,13 +503,16 @@
// Get one from driver or forge.
final DeviceDescriptionDiscovery deviceDiscovery = getBehaviour(
deviceId, DeviceDescriptionDiscovery.class);
- if (deviceDiscovery != null) {
- // Enforce defaultAvailable flag over the one obtained from driver.
- final DeviceDescription d = deviceDiscovery.discoverDeviceDetails();
- return new DefaultDeviceDescription(d, defaultAvailable, d.annotations());
- } else {
+ if (deviceDiscovery == null) {
return forgeDeviceDescription(deviceId, defaultAvailable);
}
+
+ final DeviceDescription d = deviceDiscovery.discoverDeviceDetails();
+ if (d == null) {
+ return forgeDeviceDescription(deviceId, defaultAvailable);
+ }
+ // Enforce defaultAvailable flag over the one obtained from driver.
+ return new DefaultDeviceDescription(d, defaultAvailable, d.annotations());
}
private List<PortDescription> getPortDetails(DeviceId deviceId) {
diff --git a/tools/build/bazel/modules.bzl b/tools/build/bazel/modules.bzl
index 330d9fd..12a54e9 100644
--- a/tools/build/bazel/modules.bzl
+++ b/tools/build/bazel/modules.bzl
@@ -109,6 +109,7 @@
"//drivers/polatis/netconf:onos-drivers-polatis-netconf-oar",
"//drivers/polatis/openflow:onos-drivers-polatis-openflow-oar",
"//drivers/odtn-driver:onos-drivers-odtn-driver-oar",
+ "//drivers/stratum:onos-drivers-stratum-oar",
]
ONOS_PROVIDERS = [