Device driver framework enhancements and CLI.
Change-Id: I5dea67620259797eff89a985718934034a86d63e
diff --git a/cli/src/main/java/org/onosproject/cli/net/DriverNameCompleter.java b/cli/src/main/java/org/onosproject/cli/net/DriverNameCompleter.java
new file mode 100644
index 0000000..2ba8a20
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/DriverNameCompleter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.cli.net;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.driver.DriverAdminService;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * Device driver name completer.
+ */
+public class DriverNameCompleter implements Completer {
+ @Override
+ public int complete(String buffer, int cursor, List<String> candidates) {
+ // Delegate string completer
+ StringsCompleter delegate = new StringsCompleter();
+ SortedSet<String> strings = delegate.getStrings();
+
+ // Fetch our service and feed it's offerings to the string completer
+ DriverAdminService service = AbstractShellCommand.get(DriverAdminService.class);
+ service.getDrivers().forEach(d -> strings.add(d.name()));
+
+ // Now let the completer do the work for figuring out what to offer.
+ return delegate.complete(buffer, cursor, candidates);
+ }
+
+}
diff --git a/cli/src/main/java/org/onosproject/cli/net/DriversListCommand.java b/cli/src/main/java/org/onosproject/cli/net/DriversListCommand.java
new file mode 100644
index 0000000..fd4c96c
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/DriversListCommand.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverAdminService;
+
+/**
+ * Lists device drivers.
+ */
+@Command(scope = "onos", name = "drivers",
+ description = "Lists device drivers")
+public class DriversListCommand extends AbstractShellCommand {
+
+ private static final String FMT = "driver=%s, mfr=%s, hw=%s, sw=%s";
+ private static final String FMT_B = " %s via %s";
+ private static final String FMT_P = " %s=%s";
+
+ @Argument(index = 0, name = "driverName", description = "Driver name",
+ required = false, multiValued = false)
+ String driverName = null;
+
+ @Override
+ protected void execute() {
+ DriverAdminService service = get(DriverAdminService.class);
+
+ if (driverName != null) {
+ printDriver(service.getDriver(driverName));
+ } else {
+ service.getDrivers().forEach(this::printDriver);
+ }
+ }
+
+ private void printDriver(Driver driver) {
+ print(FMT, driver.name(), driver.manufacturer(),
+ driver.hwVersion(), driver.swVersion());
+ driver.behaviours().forEach(b -> print(FMT_B, b.getCanonicalName(),
+ driver.implementation(b).getCanonicalName()));
+ driver.properties().forEach((k, v) -> print(FMT_P, k, v));
+ }
+
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 5fefe45..8234462 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -71,6 +71,14 @@
</command>
<command>
+ <action class="org.onosproject.cli.net.DriversListCommand"/>
+ <completers>
+ <ref component-id="driverNameCompleter"/>
+ <null/>
+ </completers>
+ </command>
+
+ <command>
<action class="org.onosproject.cli.net.DevicesListCommand"/>
</command>
<command>
@@ -316,5 +324,6 @@
<bean id="nullCompleter" class="org.apache.karaf.shell.console.completer.NullCompleter"/>
<bean id="ethTypeCompleter" class="org.onosproject.cli.net.EthTypeCompleter"/>
<bean id="ipProtocolCompleter" class="org.onosproject.cli.net.IpProtocolCompleter"/>
+ <bean id="driverNameCompleter" class="org.onosproject.cli.net.DriverNameCompleter"/>
</blueprint>
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java
index e95ddca..e7cd89e 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java
@@ -69,15 +69,17 @@
* @param other other driver
* @return new driver
*/
- DefaultDriver merge(DefaultDriver other) {
+ @Override
+ public Driver merge(Driver other) {
// Merge the behaviours.
ImmutableMap.Builder<Class<? extends Behaviour>, Class<? extends Behaviour>>
behaviours = ImmutableMap.builder();
- behaviours.putAll(other.behaviours).putAll(this.behaviours);
+ behaviours.putAll(this.behaviours);
+ other.behaviours().forEach(b -> behaviours.put(b, other.implementation(b)));
// Merge the properties.
ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
- properties.putAll(other.properties).putAll(this.properties);
+ properties.putAll(this.properties).putAll(other.properties());
return new DefaultDriver(name, manufacturer, hwVersion, swVersion,
behaviours.build(), properties.build());
@@ -109,6 +111,11 @@
}
@Override
+ public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) {
+ return behaviours.get(behaviour);
+ }
+
+ @Override
public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
return behaviours.containsKey(behaviourClass);
}
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java
index 3110dc8..b2b5281 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java
@@ -16,8 +16,8 @@
package org.onosproject.net.driver;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
-import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -28,7 +28,7 @@
*/
public class DefaultDriverProvider implements DriverProvider {
- private final Map<String, DefaultDriver> drivers = new HashMap<>();
+ protected final Map<String, Driver> drivers = Maps.newConcurrentMap();
@Override
public Set<Driver> getDrivers() {
@@ -36,30 +36,47 @@
}
/**
- * Adds the specified driver to be provided.
+ * Adds the specified drivers to the provider.
*
- * @param driverClasses driver to be provided
+ * @param drivers drivers to be added
*/
- public void addDrivers(Set<DefaultDriver> driverClasses) {
- for (DefaultDriver driverClass : driverClasses) {
- addDriver(driverClass);
+ public void addDrivers(Set<Driver> drivers) {
+ drivers.forEach(this::addDriver);
+ }
+
+ /**
+ * Adds the specified driver to the provider.
+ *
+ * @param driver driver to be provided
+ */
+ public void addDriver(Driver driver) {
+ Driver ddc = drivers.get(driver.name());
+ if (ddc == null) {
+ // If we don't have the driver yet, just use the new one.
+ drivers.put(driver.name(), driver);
+ } else {
+ // Otherwise merge the existing driver with the new one and rebind.
+ drivers.put(driver.name(), ddc.merge(driver));
}
}
/**
- * Adds the specified driver to be provided.
+ * Removes the specified drivers from the provider.
*
- * @param driverClass driver to be provided
+ * @param drivers drivers to be removed
*/
- public void addDriver(DefaultDriver driverClass) {
- DefaultDriver ddc = drivers.get(driverClass.name());
- if (ddc == null) {
- // If we don't have the driver yet, just use the new one.
- drivers.put(driverClass.name(), driverClass);
- } else {
- // Otherwise merge the existing driver with the new one and rebind.
- drivers.put(driverClass.name(), ddc.merge(driverClass));
- }
+ public void removeDrivers(Set<Driver> drivers) {
+ drivers.forEach(this::removeDriver);
+ }
+
+ /**
+ * Removes the specified driver from the provider.
+ *
+ * @param driver driver to be removed
+ */
+ public void removeDriver(Driver driver) {
+ // TODO: make selective if possible
+ drivers.remove(driver.name());
}
@Override
diff --git a/core/api/src/main/java/org/onosproject/net/driver/Driver.java b/core/api/src/main/java/org/onosproject/net/driver/Driver.java
index a6883d5..c8d6134 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/Driver.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/Driver.java
@@ -63,6 +63,14 @@
Set<Class<? extends Behaviour>> behaviours();
/**
+ * Returns the implementation class for the specified behaviour.
+ *
+ * @param behaviour behaviour interface
+ * @return implementation class
+ */
+ Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour);
+
+ /**
* Indicates whether or not the driver supports the specified class
* of behaviour.
*
@@ -90,4 +98,13 @@
*/
Map<String, String> properties();
+ /**
+ * Merges the specified driver behaviours and properties into this one,
+ * giving preference to the other driver when dealing with conflicts.
+ *
+ * @param other other driver
+ * @return merged driver
+ */
+ Driver merge(Driver other);
+
}
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DriverService.java b/core/api/src/main/java/org/onosproject/net/driver/DriverService.java
index ffb7c93..fa37f1b 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DriverService.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DriverService.java
@@ -25,13 +25,19 @@
public interface DriverService {
/**
- * Returns the overall set of drivers being provided, optionally
- * filtered to only those that support all specified behaviours.
+ * Returns the overall set of drivers being provided.
*
- * @param withBehaviours optional behaviour classes to query by
* @return provided drivers
*/
- Set<Driver> getDrivers(Class<? extends Behaviour>... withBehaviours);
+ Set<Driver> getDrivers();
+
+ /**
+ * Returns the set of drivers which support the specified behaviour.
+ *
+ * @param withBehaviour behaviour class to query by
+ * @return provided drivers
+ */
+ Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour);
/**
* Returns the specified driver.
diff --git a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java
index f10602a..204eb3b 100644
--- a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java
+++ b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java
@@ -50,7 +50,7 @@
ImmutableMap.of(TestBehaviour.class,
TestBehaviourImpl.class),
ImmutableMap.of("foo", "bar"));
- DefaultDriver ddc =
+ Driver ddc =
one.merge(new DefaultDriver("foo.bar", "", "", "",
ImmutableMap.of(TestBehaviourTwo.class,
TestBehaviourTwoImpl.class),
diff --git a/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java b/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java
index 9c7fddb..5f7e2e2 100644
--- a/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java
+++ b/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java
@@ -30,6 +30,7 @@
import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.DefaultDriverData;
import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.DefaultDriverProvider;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverAdminService;
import org.onosproject.net.driver.DriverHandler;
@@ -40,6 +41,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import static org.onlab.util.Tools.nullIsNotFound;
import static org.onosproject.net.AnnotationKeys.DRIVER;
@@ -49,7 +51,7 @@
*/
@Component(immediate = true)
@Service
-public class DriverManager implements DriverAdminService {
+public class DriverManager extends DefaultDriverProvider implements DriverAdminService {
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -61,7 +63,6 @@
protected DeviceService deviceService;
private Set<DriverProvider> providers = Sets.newConcurrentHashSet();
- private Map<String, Driver> driverByName = Maps.newConcurrentMap();
private Map<String, Driver> driverByKey = Maps.newConcurrentMap();
@Activate
@@ -83,7 +84,7 @@
@Override
public void registerProvider(DriverProvider provider) {
provider.getDrivers().forEach(driver -> {
- driverByName.put(driver.name(), driver);
+ addDrivers(provider.getDrivers());
driverByKey.put(key(driver.manufacturer(),
driver.hwVersion(),
driver.swVersion()), driver);
@@ -94,7 +95,7 @@
@Override
public void unregisterProvider(DriverProvider provider) {
provider.getDrivers().forEach(driver -> {
- driverByName.remove(driver.name());
+ removeDrivers(provider.getDrivers());
driverByKey.remove(key(driver.manufacturer(),
driver.hwVersion(),
driver.swVersion()));
@@ -103,21 +104,22 @@
}
@Override
- public Set<Driver> getDrivers(Class<? extends Behaviour>... withBehaviours) {
+ public Set<Driver> getDrivers() {
ImmutableSet.Builder<Driver> builder = ImmutableSet.builder();
- for (Class<? extends Behaviour> behaviour : withBehaviours) {
- driverByName.forEach((name, driver) -> {
- if (driver.hasBehaviour(behaviour)) {
- builder.add(driver);
- }
- });
- }
+ drivers.values().forEach(builder::add);
return builder.build();
}
@Override
+ public Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour) {
+ return drivers.values().stream()
+ .filter(d -> d.hasBehaviour(withBehaviour))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
public Driver getDriver(String driverName) {
- return nullIsNotFound(driverByName.get(driverName), NO_DRIVER);
+ return nullIsNotFound(drivers.get(driverName), NO_DRIVER);
}
@Override
@@ -134,7 +136,7 @@
.filter(d -> matches(d, mfr, hw, sw)).findFirst();
// If no matching driver is found, return default.
- return optional.isPresent() ? optional.get() : driverByName.get(DEFAULT);
+ return optional.isPresent() ? optional.get() : drivers.get(DEFAULT);
}
// Matches the given driver using ERE matching against the given criteria.
@@ -163,6 +165,7 @@
return new DefaultDriverHandler(new DefaultDriverData(driver));
}
+ // Produces a composite driver key using the specified components.
private String key(String mfr, String hw, String sw) {
return String.format("%s-%s-%s", mfr, hw, sw);
}
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/DefaultSingleTablePipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/DefaultSingleTablePipeline.java
index 6e99b35..866f57e 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/DefaultSingleTablePipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/DefaultSingleTablePipeline.java
@@ -21,7 +21,7 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.behaviour.PipelinerContext;
-import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.AbstractBehaviour;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperations;
@@ -41,7 +41,7 @@
/**
* Simple single table pipeline abstraction.
*/
-public class DefaultSingleTablePipeline implements Pipeliner {
+public class DefaultSingleTablePipeline extends AbstractBehaviour implements Pipeliner {
private final Logger log = getLogger(getClass());
@@ -89,7 +89,7 @@
flowBuilder.remove(rule);
break;
default:
- log.warn("Unknown operation {}", fwd.op());
+ log.warn("Unknown operation {}", fwd.op());
}
});
@@ -115,8 +115,4 @@
throw new UnsupportedOperationException("Single table does not next hop.");
}
- @Override
- public void setData(DriverData data) {
-
- }
}
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
index 2ac846c..3da786a 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
@@ -24,7 +24,7 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.behaviour.PipelinerContext;
-import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.AbstractBehaviour;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -45,9 +45,9 @@
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Created by ash on 07/04/15.
+ * Corsa pipeline handler.
*/
-public class OVSCorsaPipeline implements Pipeliner {
+public class OVSCorsaPipeline extends AbstractBehaviour implements Pipeliner {
private static final int CONTROLLER_PRIORITY = 255;
private static final int DROP_PRIORITY = 0;
@@ -92,12 +92,6 @@
return null;
}
- @Override
- public void setData(DriverData data) {
-
- }
-
-
private void pushDefaultRules() {
boolean install = true;
processTableZero(install);
@@ -130,7 +124,6 @@
ops = install ? ops.add(rule) : ops.remove(rule);
-
//Drop rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
@@ -195,7 +188,6 @@
FlowRule rule;
-
//Drop rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();