Add support for enabling/disabling ports for gNMI devices
This change also includes:
- Refactoring of gNMI protocol+driver to take advantage of the recent
changes to the gRPC protocol subsystem (e.g. no more locking, start RPC
with timeouts, etc.).
- Fixed Stratum driver to work after GeneralDeviceProvider refactoring
- Updated bmv2.py to generate ChassisConfig for stratum_bmv2
- Fixed portstate command to use the same port name as in the store
Change-Id: I0dad3bc73e4b6d907b5cf6b7b9a2852943226be7
diff --git a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortAdminBehaviour.java b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortAdminBehaviour.java
new file mode 100644
index 0000000..4f050b0
--- /dev/null
+++ b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortAdminBehaviour.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2019-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.gnmi;
+
+import gnmi.Gnmi;
+import org.onosproject.gnmi.api.GnmiClient;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.PortAdmin;
+
+import java.util.concurrent.CompletableFuture;
+
+import static java.util.concurrent.CompletableFuture.completedFuture;
+
+/**
+ * Implementation of PortAdmin for gNMI devices with OpenConfig support.
+ */
+public class OpenConfigGnmiPortAdminBehaviour
+ extends AbstractGnmiHandlerBehaviour
+ implements PortAdmin {
+
+ @Override
+ public CompletableFuture<Boolean> enable(PortNumber number) {
+ doEnable(number, true);
+ // Always returning true is OK assuming this is used only by the
+ // GeneralDeviceProvider, which ignores the return value and instead
+ // waits for a gNMI Update over the Subscribe RPC.
+ return completedFuture(true);
+ }
+
+ @Override
+ public CompletableFuture<Boolean> disable(PortNumber number) {
+ doEnable(number, false);
+ return completedFuture(true);
+ }
+
+ @Override
+ public CompletableFuture<Boolean> isEnabled(PortNumber number) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ private void doEnable(PortNumber portNumber, boolean enabled) {
+ if (portNumber.isLogical()) {
+ log.warn("Cannot update port status for logical port {} on {}",
+ portNumber, deviceId);
+ return;
+ }
+ final GnmiClient client = getClientByKey();
+ if (client == null) {
+ log.warn("Cannot update ports on {}, missing gNMI client", deviceId);
+ return;
+ }
+ final Gnmi.Path path = Gnmi.Path.newBuilder()
+ .addElem(Gnmi.PathElem.newBuilder().setName("interfaces").build())
+ .addElem(Gnmi.PathElem.newBuilder().setName("interface")
+ .putKey("name", portNumber.name()).build())
+ .addElem(Gnmi.PathElem.newBuilder().setName("config").build())
+ .addElem(Gnmi.PathElem.newBuilder().setName("enabled").build())
+ .build();
+ final Gnmi.TypedValue value = Gnmi.TypedValue.newBuilder()
+ .setBoolVal(enabled)
+ .build();
+ final Gnmi.SetRequest request = Gnmi.SetRequest.newBuilder()
+ .addUpdate(Gnmi.Update.newBuilder()
+ .setPath(path)
+ .setVal(value)
+ .build())
+ .build();
+
+ // Async submit request and forget about it. In case of errors, the
+ // client will log them. In case of success, we should receive a gNMI
+ // Update over the Subscribe RPC with the new oper status.
+ client.set(request);
+ }
+}