Committed by
Gerrit Code Review
Adding device driver inheritance mechanism.
Change-Id: I9c883d32ce0c39f961eddd5c4624dc23f794fe4d
Showing
14 changed files
with
172 additions
and
62 deletions
| ... | @@ -28,7 +28,7 @@ import org.onosproject.net.driver.DriverAdminService; | ... | @@ -28,7 +28,7 @@ import org.onosproject.net.driver.DriverAdminService; |
| 28 | description = "Lists device drivers") | 28 | description = "Lists device drivers") |
| 29 | public class DriversListCommand extends AbstractShellCommand { | 29 | public class DriversListCommand extends AbstractShellCommand { |
| 30 | 30 | ||
| 31 | - private static final String FMT = "driver=%s, mfr=%s, hw=%s, sw=%s"; | 31 | + private static final String FMT = "driver=%s, extends=%s, mfr=%s, hw=%s, sw=%s"; |
| 32 | private static final String FMT_B = " %s via %s"; | 32 | private static final String FMT_B = " %s via %s"; |
| 33 | private static final String FMT_P = " %s=%s"; | 33 | private static final String FMT_P = " %s=%s"; |
| 34 | 34 | ||
| ... | @@ -48,8 +48,9 @@ public class DriversListCommand extends AbstractShellCommand { | ... | @@ -48,8 +48,9 @@ public class DriversListCommand extends AbstractShellCommand { |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | private void printDriver(Driver driver) { | 50 | private void printDriver(Driver driver) { |
| 51 | - print(FMT, driver.name(), driver.manufacturer(), | 51 | + Driver parent = driver.parent(); |
| 52 | - driver.hwVersion(), driver.swVersion()); | 52 | + print(FMT, driver.name(), parent != null ? parent.name() : "none", |
| 53 | + driver.manufacturer(), driver.hwVersion(), driver.swVersion()); | ||
| 53 | driver.behaviours().forEach(b -> print(FMT_B, b.getCanonicalName(), | 54 | driver.behaviours().forEach(b -> print(FMT_B, b.getCanonicalName(), |
| 54 | driver.implementation(b).getCanonicalName())); | 55 | driver.implementation(b).getCanonicalName())); |
| 55 | driver.properties().forEach((k, v) -> print(FMT_P, k, v)); | 56 | driver.properties().forEach((k, v) -> print(FMT_P, k, v)); | ... | ... |
| ... | @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableMap; | ... | @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableMap; |
| 19 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
| 20 | 20 | ||
| 21 | import java.util.Map; | 21 | import java.util.Map; |
| 22 | +import java.util.Objects; | ||
| 22 | import java.util.Set; | 23 | import java.util.Set; |
| 23 | 24 | ||
| 24 | import static com.google.common.base.MoreObjects.toStringHelper; | 25 | import static com.google.common.base.MoreObjects.toStringHelper; |
| ... | @@ -32,6 +33,7 @@ import static com.google.common.collect.ImmutableMap.copyOf; | ... | @@ -32,6 +33,7 @@ import static com.google.common.collect.ImmutableMap.copyOf; |
| 32 | public class DefaultDriver implements Driver { | 33 | public class DefaultDriver implements Driver { |
| 33 | 34 | ||
| 34 | private final String name; | 35 | private final String name; |
| 36 | + private final Driver parent; | ||
| 35 | 37 | ||
| 36 | private final String manufacturer; | 38 | private final String manufacturer; |
| 37 | private final String hwVersion; | 39 | private final String hwVersion; |
| ... | @@ -40,22 +42,23 @@ public class DefaultDriver implements Driver { | ... | @@ -40,22 +42,23 @@ public class DefaultDriver implements Driver { |
| 40 | private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours; | 42 | private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours; |
| 41 | private final Map<String, String> properties; | 43 | private final Map<String, String> properties; |
| 42 | 44 | ||
| 43 | - | ||
| 44 | /** | 45 | /** |
| 45 | * Creates a driver with the specified name. | 46 | * Creates a driver with the specified name. |
| 46 | * | 47 | * |
| 47 | * @param name driver name | 48 | * @param name driver name |
| 49 | + * @param parent optional parent driver | ||
| 48 | * @param manufacturer device manufacturer | 50 | * @param manufacturer device manufacturer |
| 49 | * @param hwVersion device hardware version | 51 | * @param hwVersion device hardware version |
| 50 | * @param swVersion device software version | 52 | * @param swVersion device software version |
| 51 | * @param behaviours device behaviour classes | 53 | * @param behaviours device behaviour classes |
| 52 | * @param properties properties for configuration of device behaviour classes | 54 | * @param properties properties for configuration of device behaviour classes |
| 53 | */ | 55 | */ |
| 54 | - public DefaultDriver(String name, String manufacturer, | 56 | + public DefaultDriver(String name, Driver parent, String manufacturer, |
| 55 | String hwVersion, String swVersion, | 57 | String hwVersion, String swVersion, |
| 56 | Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours, | 58 | Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours, |
| 57 | Map<String, String> properties) { | 59 | Map<String, String> properties) { |
| 58 | this.name = checkNotNull(name, "Name cannot be null"); | 60 | this.name = checkNotNull(name, "Name cannot be null"); |
| 61 | + this.parent = parent; | ||
| 59 | this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null"); | 62 | this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null"); |
| 60 | this.hwVersion = checkNotNull(hwVersion, "HW version cannot be null"); | 63 | this.hwVersion = checkNotNull(hwVersion, "HW version cannot be null"); |
| 61 | this.swVersion = checkNotNull(swVersion, "SW version cannot be null"); | 64 | this.swVersion = checkNotNull(swVersion, "SW version cannot be null"); |
| ... | @@ -65,6 +68,9 @@ public class DefaultDriver implements Driver { | ... | @@ -65,6 +68,9 @@ public class DefaultDriver implements Driver { |
| 65 | 68 | ||
| 66 | @Override | 69 | @Override |
| 67 | public Driver merge(Driver other) { | 70 | public Driver merge(Driver other) { |
| 71 | + checkArgument(parent == null || Objects.equals(parent, other.parent()), | ||
| 72 | + "Parent drivers are not the same"); | ||
| 73 | + | ||
| 68 | // Merge the behaviours. | 74 | // Merge the behaviours. |
| 69 | Map<Class<? extends Behaviour>, Class<? extends Behaviour>> | 75 | Map<Class<? extends Behaviour>, Class<? extends Behaviour>> |
| 70 | behaviours = Maps.newHashMap(); | 76 | behaviours = Maps.newHashMap(); |
| ... | @@ -75,7 +81,7 @@ public class DefaultDriver implements Driver { | ... | @@ -75,7 +81,7 @@ public class DefaultDriver implements Driver { |
| 75 | ImmutableMap.Builder<String, String> properties = ImmutableMap.builder(); | 81 | ImmutableMap.Builder<String, String> properties = ImmutableMap.builder(); |
| 76 | properties.putAll(this.properties).putAll(other.properties()); | 82 | properties.putAll(this.properties).putAll(other.properties()); |
| 77 | 83 | ||
| 78 | - return new DefaultDriver(name, manufacturer, hwVersion, swVersion, | 84 | + return new DefaultDriver(name, other.parent(), manufacturer, hwVersion, swVersion, |
| 79 | ImmutableMap.copyOf(behaviours), properties.build()); | 85 | ImmutableMap.copyOf(behaviours), properties.build()); |
| 80 | } | 86 | } |
| 81 | 87 | ||
| ... | @@ -100,6 +106,11 @@ public class DefaultDriver implements Driver { | ... | @@ -100,6 +106,11 @@ public class DefaultDriver implements Driver { |
| 100 | } | 106 | } |
| 101 | 107 | ||
| 102 | @Override | 108 | @Override |
| 109 | + public Driver parent() { | ||
| 110 | + return parent; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + @Override | ||
| 103 | public Set<Class<? extends Behaviour>> behaviours() { | 114 | public Set<Class<? extends Behaviour>> behaviours() { |
| 104 | return behaviours.keySet(); | 115 | return behaviours.keySet(); |
| 105 | } | 116 | } |
| ... | @@ -111,19 +122,32 @@ public class DefaultDriver implements Driver { | ... | @@ -111,19 +122,32 @@ public class DefaultDriver implements Driver { |
| 111 | 122 | ||
| 112 | @Override | 123 | @Override |
| 113 | public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) { | 124 | public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) { |
| 114 | - return behaviours.containsKey(behaviourClass); | 125 | + return behaviours.containsKey(behaviourClass) || |
| 126 | + (parent != null && parent.hasBehaviour(behaviourClass)); | ||
| 115 | } | 127 | } |
| 116 | 128 | ||
| 117 | @Override | 129 | @Override |
| 118 | public <T extends Behaviour> T createBehaviour(DriverData data, | 130 | public <T extends Behaviour> T createBehaviour(DriverData data, |
| 119 | Class<T> behaviourClass) { | 131 | Class<T> behaviourClass) { |
| 120 | - return createBehaviour(data, null, behaviourClass); | 132 | + T behaviour = createBehaviour(data, null, behaviourClass); |
| 133 | + if (behaviour != null) { | ||
| 134 | + return behaviour; | ||
| 135 | + } else if (parent != null) { | ||
| 136 | + return parent.createBehaviour(data, behaviourClass); | ||
| 137 | + } | ||
| 138 | + throw new IllegalArgumentException(behaviourClass.getName() + " not supported"); | ||
| 121 | } | 139 | } |
| 122 | 140 | ||
| 123 | @Override | 141 | @Override |
| 124 | public <T extends Behaviour> T createBehaviour(DriverHandler handler, | 142 | public <T extends Behaviour> T createBehaviour(DriverHandler handler, |
| 125 | Class<T> behaviourClass) { | 143 | Class<T> behaviourClass) { |
| 126 | - return createBehaviour(handler.data(), handler, behaviourClass); | 144 | + T behaviour = createBehaviour(handler.data(), handler, behaviourClass); |
| 145 | + if (behaviour != null) { | ||
| 146 | + return behaviour; | ||
| 147 | + } else if (parent != null) { | ||
| 148 | + return parent.createBehaviour(handler, behaviourClass); | ||
| 149 | + } | ||
| 150 | + throw new IllegalArgumentException(behaviourClass.getName() + " not supported"); | ||
| 127 | } | 151 | } |
| 128 | 152 | ||
| 129 | // Creates an instance of behaviour primed with the specified driver data. | 153 | // Creates an instance of behaviour primed with the specified driver data. |
| ... | @@ -134,17 +158,18 @@ public class DefaultDriver implements Driver { | ... | @@ -134,17 +158,18 @@ public class DefaultDriver implements Driver { |
| 134 | 158 | ||
| 135 | // Locate the implementation of the requested behaviour. | 159 | // Locate the implementation of the requested behaviour. |
| 136 | Class<? extends Behaviour> implementation = behaviours.get(behaviourClass); | 160 | Class<? extends Behaviour> implementation = behaviours.get(behaviourClass); |
| 137 | - checkArgument(implementation != null, "{} not supported", behaviourClass.getName()); | 161 | + if (implementation != null) { |
| 138 | - | 162 | + // Create an instance of the behaviour and apply data as its context. |
| 139 | - // Create an instance of the behaviour and apply data as its context. | 163 | + T behaviour = createBehaviour(behaviourClass, implementation); |
| 140 | - T behaviour = createBehaviour(behaviourClass, implementation); | 164 | + behaviour.setData(data); |
| 141 | - behaviour.setData(data); | 165 | + |
| 142 | - | 166 | + // If this is a handler behaviour, also apply handler as its context. |
| 143 | - // If this is a handler behaviour, also apply handler as its context. | 167 | + if (handler != null) { |
| 144 | - if (handler != null) { | 168 | + ((HandlerBehaviour) behaviour).setHandler(handler); |
| 145 | - ((HandlerBehaviour) behaviour).setHandler(handler); | 169 | + } |
| 170 | + return behaviour; | ||
| 146 | } | 171 | } |
| 147 | - return behaviour; | 172 | + return null; |
| 148 | } | 173 | } |
| 149 | 174 | ||
| 150 | @SuppressWarnings("unchecked") | 175 | @SuppressWarnings("unchecked") |
| ... | @@ -177,6 +202,7 @@ public class DefaultDriver implements Driver { | ... | @@ -177,6 +202,7 @@ public class DefaultDriver implements Driver { |
| 177 | public String toString() { | 202 | public String toString() { |
| 178 | return toStringHelper(this) | 203 | return toStringHelper(this) |
| 179 | .add("name", name) | 204 | .add("name", name) |
| 205 | + .add("parent", parent) | ||
| 180 | .add("manufacturer", manufacturer) | 206 | .add("manufacturer", manufacturer) |
| 181 | .add("hwVersion", hwVersion) | 207 | .add("hwVersion", hwVersion) |
| 182 | .add("swVersion", swVersion) | 208 | .add("swVersion", swVersion) | ... | ... |
| ... | @@ -35,6 +35,14 @@ public interface Driver extends Annotations { | ... | @@ -35,6 +35,14 @@ public interface Driver extends Annotations { |
| 35 | String name(); | 35 | String name(); |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | + * Returns the parent driver from which this driver inherits behaviours | ||
| 39 | + * and properties. | ||
| 40 | + * | ||
| 41 | + * @return parent driver; null if driver has no parent | ||
| 42 | + */ | ||
| 43 | + Driver parent(); | ||
| 44 | + | ||
| 45 | + /** | ||
| 38 | * Returns the device manufacturer name. | 46 | * Returns the device manufacturer name. |
| 39 | * | 47 | * |
| 40 | * @return manufacturer name | 48 | * @return manufacturer name |
| ... | @@ -57,6 +65,7 @@ public interface Driver extends Annotations { | ... | @@ -57,6 +65,7 @@ public interface Driver extends Annotations { |
| 57 | 65 | ||
| 58 | /** | 66 | /** |
| 59 | * Returns the set of behaviours supported by this driver. | 67 | * Returns the set of behaviours supported by this driver. |
| 68 | + * It reflects behaviours of only this driver and not its parent. | ||
| 60 | * | 69 | * |
| 61 | * @return set of device driver behaviours | 70 | * @return set of device driver behaviours |
| 62 | */ | 71 | */ |
| ... | @@ -64,6 +73,7 @@ public interface Driver extends Annotations { | ... | @@ -64,6 +73,7 @@ public interface Driver extends Annotations { |
| 64 | 73 | ||
| 65 | /** | 74 | /** |
| 66 | * Returns the implementation class for the specified behaviour. | 75 | * Returns the implementation class for the specified behaviour. |
| 76 | + * It reflects behaviours of only this driver and not its parent. | ||
| 67 | * | 77 | * |
| 68 | * @param behaviour behaviour interface | 78 | * @param behaviour behaviour interface |
| 69 | * @return implementation class | 79 | * @return implementation class |
| ... | @@ -71,8 +81,8 @@ public interface Driver extends Annotations { | ... | @@ -71,8 +81,8 @@ public interface Driver extends Annotations { |
| 71 | Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour); | 81 | Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour); |
| 72 | 82 | ||
| 73 | /** | 83 | /** |
| 74 | - * Indicates whether or not the driver supports the specified class | 84 | + * Indicates whether or not the driver, or any of its parents, support |
| 75 | - * of behaviour. | 85 | + * the specified class of behaviour. It |
| 76 | * | 86 | * |
| 77 | * @param behaviourClass behaviour class | 87 | * @param behaviourClass behaviour class |
| 78 | * @return true if behaviour is supported | 88 | * @return true if behaviour is supported |
| ... | @@ -81,6 +91,8 @@ public interface Driver extends Annotations { | ... | @@ -81,6 +91,8 @@ public interface Driver extends Annotations { |
| 81 | 91 | ||
| 82 | /** | 92 | /** |
| 83 | * Creates an instance of behaviour primed with the specified driver data. | 93 | * Creates an instance of behaviour primed with the specified driver data. |
| 94 | + * If the current driver does not support the specified behaviour and the | ||
| 95 | + * driver has parent, the request is delegated to the parent driver. | ||
| 84 | * | 96 | * |
| 85 | * @param data driver data context | 97 | * @param data driver data context |
| 86 | * @param behaviourClass driver behaviour class | 98 | * @param behaviourClass driver behaviour class |
| ... | @@ -91,6 +103,8 @@ public interface Driver extends Annotations { | ... | @@ -91,6 +103,8 @@ public interface Driver extends Annotations { |
| 91 | 103 | ||
| 92 | /** | 104 | /** |
| 93 | * Creates an instance of behaviour primed with the specified driver data. | 105 | * Creates an instance of behaviour primed with the specified driver data. |
| 106 | + * If the current driver does not support the specified behaviour and the | ||
| 107 | + * driver has parent, the request is delegated to the parent driver. | ||
| 94 | * | 108 | * |
| 95 | * @param handler driver handler context | 109 | * @param handler driver handler context |
| 96 | * @param behaviourClass driver behaviour class | 110 | * @param behaviourClass driver behaviour class | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.net.driver; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Entity capable of resolving a driver using its name. | ||
| 21 | + */ | ||
| 22 | +public interface DriverResolver { | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * Returns the specified driver. | ||
| 26 | + * | ||
| 27 | + * @param driverName driver name | ||
| 28 | + * @return driver | ||
| 29 | + * @throws org.onlab.util.ItemNotFoundException if driver with the given | ||
| 30 | + * name is not found | ||
| 31 | + */ | ||
| 32 | + Driver getDriver(String driverName); | ||
| 33 | + | ||
| 34 | +} |
| ... | @@ -22,7 +22,7 @@ import java.util.Set; | ... | @@ -22,7 +22,7 @@ import java.util.Set; |
| 22 | /** | 22 | /** |
| 23 | * Service for obtaining drivers and driver behaviour implementations. | 23 | * Service for obtaining drivers and driver behaviour implementations. |
| 24 | */ | 24 | */ |
| 25 | -public interface DriverService { | 25 | +public interface DriverService extends DriverResolver { |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | * Returns the overall set of drivers being provided. | 28 | * Returns the overall set of drivers being provided. |
| ... | @@ -40,16 +40,6 @@ public interface DriverService { | ... | @@ -40,16 +40,6 @@ public interface DriverService { |
| 40 | Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour); | 40 | Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour); |
| 41 | 41 | ||
| 42 | /** | 42 | /** |
| 43 | - * Returns the specified driver. | ||
| 44 | - * | ||
| 45 | - * @param driverName driver name | ||
| 46 | - * @return driver | ||
| 47 | - * @throws org.onlab.util.ItemNotFoundException if driver with the given | ||
| 48 | - * name is not found | ||
| 49 | - */ | ||
| 50 | - Driver getDriver(String driverName); | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | * Returns the driver that matches the specified primordial device | 43 | * Returns the driver that matches the specified primordial device |
| 54 | * discovery information. | 44 | * discovery information. |
| 55 | * | 45 | * | ... | ... |
| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | package org.onosproject.net.driver; | 16 | package org.onosproject.net.driver; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.ImmutableMap; | 18 | import com.google.common.collect.ImmutableMap; |
| 19 | +import com.google.common.collect.Maps; | ||
| 19 | import org.apache.commons.configuration.ConfigurationException; | 20 | import org.apache.commons.configuration.ConfigurationException; |
| 20 | import org.apache.commons.configuration.HierarchicalConfiguration; | 21 | import org.apache.commons.configuration.HierarchicalConfiguration; |
| 21 | import org.apache.commons.configuration.XMLConfiguration; | 22 | import org.apache.commons.configuration.XMLConfiguration; |
| ... | @@ -51,6 +52,7 @@ public class XmlDriverLoader { | ... | @@ -51,6 +52,7 @@ public class XmlDriverLoader { |
| 51 | private static final String PROPERTY = "property"; | 52 | private static final String PROPERTY = "property"; |
| 52 | 53 | ||
| 53 | private static final String NAME = "[@name]"; | 54 | private static final String NAME = "[@name]"; |
| 55 | + private static final String EXTENDS = "[@extends]"; | ||
| 54 | private static final String MFG = "[@manufacturer]"; | 56 | private static final String MFG = "[@manufacturer]"; |
| 55 | private static final String HW = "[@hwVersion]"; | 57 | private static final String HW = "[@hwVersion]"; |
| 56 | private static final String SW = "[@swVersion]"; | 58 | private static final String SW = "[@swVersion]"; |
| ... | @@ -59,6 +61,8 @@ public class XmlDriverLoader { | ... | @@ -59,6 +61,8 @@ public class XmlDriverLoader { |
| 59 | 61 | ||
| 60 | private final ClassLoader classLoader; | 62 | private final ClassLoader classLoader; |
| 61 | 63 | ||
| 64 | + private Map<String, Driver> drivers = Maps.newHashMap(); | ||
| 65 | + | ||
| 62 | /** | 66 | /** |
| 63 | * Creates a new driver loader capable of loading drivers from the supplied | 67 | * Creates a new driver loader capable of loading drivers from the supplied |
| 64 | * class loader. | 68 | * class loader. |
| ... | @@ -74,18 +78,20 @@ public class XmlDriverLoader { | ... | @@ -74,18 +78,20 @@ public class XmlDriverLoader { |
| 74 | * produce a ready-to-register driver provider. | 78 | * produce a ready-to-register driver provider. |
| 75 | * | 79 | * |
| 76 | * @param driversStream stream containing the drivers definitions | 80 | * @param driversStream stream containing the drivers definitions |
| 81 | + * @param resolver driver resolver | ||
| 77 | * @return driver provider | 82 | * @return driver provider |
| 78 | * @throws java.io.IOException if issues are encountered reading the stream | 83 | * @throws java.io.IOException if issues are encountered reading the stream |
| 79 | * or parsing the driver definitions within | 84 | * or parsing the driver definitions within |
| 80 | */ | 85 | */ |
| 81 | - public DefaultDriverProvider loadDrivers(InputStream driversStream) throws IOException { | 86 | + public DefaultDriverProvider loadDrivers(InputStream driversStream, |
| 87 | + DriverResolver resolver) throws IOException { | ||
| 82 | try { | 88 | try { |
| 83 | XMLConfiguration cfg = new XMLConfiguration(); | 89 | XMLConfiguration cfg = new XMLConfiguration(); |
| 84 | cfg.setRootElementName(DRIVERS); | 90 | cfg.setRootElementName(DRIVERS); |
| 85 | cfg.setAttributeSplittingDisabled(true); | 91 | cfg.setAttributeSplittingDisabled(true); |
| 86 | 92 | ||
| 87 | cfg.load(driversStream); | 93 | cfg.load(driversStream); |
| 88 | - return loadDrivers(cfg); | 94 | + return loadDrivers(cfg, resolver); |
| 89 | } catch (ConfigurationException e) { | 95 | } catch (ConfigurationException e) { |
| 90 | throw new IOException("Unable to load drivers", e); | 96 | throw new IOException("Unable to load drivers", e); |
| 91 | } | 97 | } |
| ... | @@ -95,13 +101,18 @@ public class XmlDriverLoader { | ... | @@ -95,13 +101,18 @@ public class XmlDriverLoader { |
| 95 | * Loads a driver provider from the supplied hierarchical configuration. | 101 | * Loads a driver provider from the supplied hierarchical configuration. |
| 96 | * | 102 | * |
| 97 | * @param driversCfg hierarchical configuration containing the drivers definitions | 103 | * @param driversCfg hierarchical configuration containing the drivers definitions |
| 104 | + * @param resolver driver resolver | ||
| 98 | * @return driver provider | 105 | * @return driver provider |
| 99 | */ | 106 | */ |
| 100 | - public DefaultDriverProvider loadDrivers(HierarchicalConfiguration driversCfg) { | 107 | + public DefaultDriverProvider loadDrivers(HierarchicalConfiguration driversCfg, |
| 108 | + DriverResolver resolver) { | ||
| 101 | DefaultDriverProvider provider = new DefaultDriverProvider(); | 109 | DefaultDriverProvider provider = new DefaultDriverProvider(); |
| 102 | for (HierarchicalConfiguration cfg : driversCfg.configurationsAt(DRIVER)) { | 110 | for (HierarchicalConfiguration cfg : driversCfg.configurationsAt(DRIVER)) { |
| 103 | - provider.addDriver(loadDriver(cfg)); | 111 | + DefaultDriver driver = loadDriver(cfg, resolver); |
| 112 | + drivers.put(driver.name(), driver); | ||
| 113 | + provider.addDriver(driver); | ||
| 104 | } | 114 | } |
| 115 | + drivers.clear(); | ||
| 105 | return provider; | 116 | return provider; |
| 106 | } | 117 | } |
| 107 | 118 | ||
| ... | @@ -109,19 +120,30 @@ public class XmlDriverLoader { | ... | @@ -109,19 +120,30 @@ public class XmlDriverLoader { |
| 109 | * Loads a driver from the supplied hierarchical configuration. | 120 | * Loads a driver from the supplied hierarchical configuration. |
| 110 | * | 121 | * |
| 111 | * @param driverCfg hierarchical configuration containing the driver definition | 122 | * @param driverCfg hierarchical configuration containing the driver definition |
| 123 | + * @param resolver driver resolver | ||
| 112 | * @return driver | 124 | * @return driver |
| 113 | */ | 125 | */ |
| 114 | - public DefaultDriver loadDriver(HierarchicalConfiguration driverCfg) { | 126 | + public DefaultDriver loadDriver(HierarchicalConfiguration driverCfg, |
| 127 | + DriverResolver resolver) { | ||
| 115 | String name = driverCfg.getString(NAME); | 128 | String name = driverCfg.getString(NAME); |
| 129 | + String parentName = driverCfg.getString(EXTENDS); | ||
| 116 | String manufacturer = driverCfg.getString(MFG, ""); | 130 | String manufacturer = driverCfg.getString(MFG, ""); |
| 117 | String hwVersion = driverCfg.getString(HW, ""); | 131 | String hwVersion = driverCfg.getString(HW, ""); |
| 118 | String swVersion = driverCfg.getString(SW, ""); | 132 | String swVersion = driverCfg.getString(SW, ""); |
| 119 | 133 | ||
| 120 | - return new DefaultDriver(name, manufacturer, hwVersion, swVersion, | 134 | + Driver parent = parentName != null ? resolve(parentName, resolver) : null; |
| 135 | + return new DefaultDriver(name, parent, manufacturer, hwVersion, swVersion, | ||
| 121 | parseBehaviours(driverCfg), | 136 | parseBehaviours(driverCfg), |
| 122 | parseProperties(driverCfg)); | 137 | parseProperties(driverCfg)); |
| 123 | } | 138 | } |
| 124 | 139 | ||
| 140 | + // Resolves the driver by name locally at first and then using the specified resolver. | ||
| 141 | + private Driver resolve(String parentName, DriverResolver resolver) { | ||
| 142 | + Driver driver = drivers.get(parentName); | ||
| 143 | + return driver != null ? driver : | ||
| 144 | + (resolver != null ? resolver.getDriver(parentName) : null); | ||
| 145 | + } | ||
| 146 | + | ||
| 125 | // Parses the behaviours section. | 147 | // Parses the behaviours section. |
| 126 | private Map<Class<? extends Behaviour>, Class<? extends Behaviour>> | 148 | private Map<Class<? extends Behaviour>, Class<? extends Behaviour>> |
| 127 | parseBehaviours(HierarchicalConfiguration driverCfg) { | 149 | parseBehaviours(HierarchicalConfiguration driverCfg) { | ... | ... |
| ... | @@ -28,7 +28,7 @@ public class DefaultDriverDataTest { | ... | @@ -28,7 +28,7 @@ public class DefaultDriverDataTest { |
| 28 | 28 | ||
| 29 | @Before | 29 | @Before |
| 30 | public void setUp() { | 30 | public void setUp() { |
| 31 | - ddc = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a", | 31 | + ddc = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a", |
| 32 | ImmutableMap.of(TestBehaviour.class, | 32 | ImmutableMap.of(TestBehaviour.class, |
| 33 | TestBehaviourImpl.class), | 33 | TestBehaviourImpl.class), |
| 34 | ImmutableMap.of("foo", "bar")); | 34 | ImmutableMap.of("foo", "bar")); | ... | ... |
| ... | @@ -30,7 +30,7 @@ public class DefaultDriverHandlerTest { | ... | @@ -30,7 +30,7 @@ public class DefaultDriverHandlerTest { |
| 30 | 30 | ||
| 31 | @Before | 31 | @Before |
| 32 | public void setUp() { | 32 | public void setUp() { |
| 33 | - ddc = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a", | 33 | + ddc = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a", |
| 34 | ImmutableMap.of(TestBehaviour.class, | 34 | ImmutableMap.of(TestBehaviour.class, |
| 35 | TestBehaviourImpl.class, | 35 | TestBehaviourImpl.class, |
| 36 | TestBehaviourTwo.class, | 36 | TestBehaviourTwo.class, | ... | ... |
| ... | @@ -28,15 +28,15 @@ public class DefaultDriverProviderTest { | ... | @@ -28,15 +28,15 @@ public class DefaultDriverProviderTest { |
| 28 | @Test | 28 | @Test |
| 29 | public void basics() { | 29 | public void basics() { |
| 30 | DefaultDriverProvider ddp = new DefaultDriverProvider(); | 30 | DefaultDriverProvider ddp = new DefaultDriverProvider(); |
| 31 | - DefaultDriver one = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a", | 31 | + DefaultDriver one = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a", |
| 32 | ImmutableMap.of(TestBehaviour.class, | 32 | ImmutableMap.of(TestBehaviour.class, |
| 33 | TestBehaviourImpl.class), | 33 | TestBehaviourImpl.class), |
| 34 | ImmutableMap.of("foo", "bar")); | 34 | ImmutableMap.of("foo", "bar")); |
| 35 | - DefaultDriver two = new DefaultDriver("foo.bar", "", "", "", | 35 | + DefaultDriver two = new DefaultDriver("foo.bar", null, "", "", "", |
| 36 | ImmutableMap.of(TestBehaviourTwo.class, | 36 | ImmutableMap.of(TestBehaviourTwo.class, |
| 37 | TestBehaviourTwoImpl.class), | 37 | TestBehaviourTwoImpl.class), |
| 38 | ImmutableMap.of("goo", "wee")); | 38 | ImmutableMap.of("goo", "wee")); |
| 39 | - DefaultDriver three = new DefaultDriver("goo.foo", "BigTop", "better", "2.2", | 39 | + DefaultDriver three = new DefaultDriver("goo.foo", null, "BigTop", "better", "2.2", |
| 40 | ImmutableMap.of(TestBehaviourTwo.class, | 40 | ImmutableMap.of(TestBehaviourTwo.class, |
| 41 | TestBehaviourTwoImpl.class), | 41 | TestBehaviourTwoImpl.class), |
| 42 | ImmutableMap.of("goo", "gee")); | 42 | ImmutableMap.of("goo", "gee")); | ... | ... |
| ... | @@ -25,18 +25,33 @@ public class DefaultDriverTest { | ... | @@ -25,18 +25,33 @@ public class DefaultDriverTest { |
| 25 | 25 | ||
| 26 | @Test | 26 | @Test |
| 27 | public void basics() { | 27 | public void basics() { |
| 28 | - DefaultDriver ddc = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a", | 28 | + DefaultDriver ddp = new DefaultDriver("foo.base", null, "Circus", "lux", "1.2a", |
| 29 | ImmutableMap.of(TestBehaviour.class, | 29 | ImmutableMap.of(TestBehaviour.class, |
| 30 | - TestBehaviourImpl.class), | 30 | + TestBehaviourImpl.class, |
| 31 | + TestBehaviourTwo.class, | ||
| 32 | + TestBehaviourTwoImpl.class), | ||
| 33 | + ImmutableMap.of("foo", "bar")); | ||
| 34 | + | ||
| 35 | + DefaultDriver ddc = new DefaultDriver("foo.bar", ddp, "Circus", "lux", "1.2a", | ||
| 36 | + ImmutableMap.of(), | ||
| 31 | ImmutableMap.of("foo", "bar")); | 37 | ImmutableMap.of("foo", "bar")); |
| 32 | assertEquals("incorrect name", "foo.bar", ddc.name()); | 38 | assertEquals("incorrect name", "foo.bar", ddc.name()); |
| 39 | + assertEquals("incorrect parent", ddp, ddc.parent()); | ||
| 33 | assertEquals("incorrect mfr", "Circus", ddc.manufacturer()); | 40 | assertEquals("incorrect mfr", "Circus", ddc.manufacturer()); |
| 34 | assertEquals("incorrect hw", "lux", ddc.hwVersion()); | 41 | assertEquals("incorrect hw", "lux", ddc.hwVersion()); |
| 35 | assertEquals("incorrect sw", "1.2a", ddc.swVersion()); | 42 | assertEquals("incorrect sw", "1.2a", ddc.swVersion()); |
| 36 | 43 | ||
| 37 | - assertEquals("incorrect behaviour count", 1, ddc.behaviours().size()); | 44 | + assertEquals("incorrect behaviour count", 2, ddp.behaviours().size()); |
| 45 | + assertEquals("incorrect behaviour count", 0, ddc.behaviours().size()); | ||
| 38 | assertTrue("incorrect behaviour", ddc.hasBehaviour(TestBehaviour.class)); | 46 | assertTrue("incorrect behaviour", ddc.hasBehaviour(TestBehaviour.class)); |
| 39 | 47 | ||
| 48 | + Behaviour b1 = ddc.createBehaviour(new DefaultDriverData(ddc), TestBehaviour.class); | ||
| 49 | + assertTrue("incorrect behaviour class", b1 instanceof TestBehaviourImpl); | ||
| 50 | + | ||
| 51 | + Behaviour b2 = ddc.createBehaviour(new DefaultDriverHandler(new DefaultDriverData(ddc)), | ||
| 52 | + TestBehaviourTwo.class); | ||
| 53 | + assertTrue("incorrect behaviour class", b2 instanceof TestBehaviourTwoImpl); | ||
| 54 | + | ||
| 40 | assertEquals("incorrect property count", 1, ddc.properties().size()); | 55 | assertEquals("incorrect property count", 1, ddc.properties().size()); |
| 41 | assertEquals("incorrect key count", 1, ddc.keys().size()); | 56 | assertEquals("incorrect key count", 1, ddc.keys().size()); |
| 42 | assertEquals("incorrect property", "bar", ddc.value("foo")); | 57 | assertEquals("incorrect property", "bar", ddc.value("foo")); |
| ... | @@ -46,12 +61,12 @@ public class DefaultDriverTest { | ... | @@ -46,12 +61,12 @@ public class DefaultDriverTest { |
| 46 | 61 | ||
| 47 | @Test | 62 | @Test |
| 48 | public void merge() { | 63 | public void merge() { |
| 49 | - DefaultDriver one = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a", | 64 | + DefaultDriver one = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a", |
| 50 | ImmutableMap.of(TestBehaviour.class, | 65 | ImmutableMap.of(TestBehaviour.class, |
| 51 | TestBehaviourImpl.class), | 66 | TestBehaviourImpl.class), |
| 52 | ImmutableMap.of("foo", "bar")); | 67 | ImmutableMap.of("foo", "bar")); |
| 53 | Driver ddc = | 68 | Driver ddc = |
| 54 | - one.merge(new DefaultDriver("foo.bar", "", "", "", | 69 | + one.merge(new DefaultDriver("foo.bar", null, "", "", "", |
| 55 | ImmutableMap.of(TestBehaviourTwo.class, | 70 | ImmutableMap.of(TestBehaviourTwo.class, |
| 56 | TestBehaviourTwoImpl.class), | 71 | TestBehaviourTwoImpl.class), |
| 57 | ImmutableMap.of("goo", "wee"))); | 72 | ImmutableMap.of("goo", "wee"))); | ... | ... |
| ... | @@ -19,6 +19,7 @@ import org.junit.Test; | ... | @@ -19,6 +19,7 @@ import org.junit.Test; |
| 19 | 19 | ||
| 20 | import java.io.IOException; | 20 | import java.io.IOException; |
| 21 | import java.io.InputStream; | 21 | import java.io.InputStream; |
| 22 | +import java.util.Iterator; | ||
| 22 | 23 | ||
| 23 | import static org.junit.Assert.assertEquals; | 24 | import static org.junit.Assert.assertEquals; |
| 24 | import static org.junit.Assert.assertTrue; | 25 | import static org.junit.Assert.assertTrue; |
| ... | @@ -32,17 +33,22 @@ public class XmlDriverLoaderTest { | ... | @@ -32,17 +33,22 @@ public class XmlDriverLoaderTest { |
| 32 | public void basics() throws IOException { | 33 | public void basics() throws IOException { |
| 33 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); | 34 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); |
| 34 | InputStream stream = getClass().getResourceAsStream("drivers.1.xml"); | 35 | InputStream stream = getClass().getResourceAsStream("drivers.1.xml"); |
| 35 | - DriverProvider provider = loader.loadDrivers(stream); | 36 | + DriverProvider provider = loader.loadDrivers(stream, null); |
| 36 | System.out.println(provider); | 37 | System.out.println(provider); |
| 37 | - assertEquals("incorrect driver count", 1, provider.getDrivers().size()); | 38 | + assertEquals("incorrect driver count", 2, provider.getDrivers().size()); |
| 39 | + | ||
| 40 | + Iterator<Driver> iterator = provider.getDrivers().iterator(); | ||
| 41 | + Driver driver = iterator.next(); | ||
| 42 | + if (!driver.name().equals("foo.1")) { | ||
| 43 | + driver = iterator.next(); | ||
| 44 | + } | ||
| 38 | 45 | ||
| 39 | - Driver driver = provider.getDrivers().iterator().next(); | ||
| 40 | assertEquals("incorrect driver name", "foo.1", driver.name()); | 46 | assertEquals("incorrect driver name", "foo.1", driver.name()); |
| 41 | assertEquals("incorrect driver mfg", "Circus", driver.manufacturer()); | 47 | assertEquals("incorrect driver mfg", "Circus", driver.manufacturer()); |
| 42 | assertEquals("incorrect driver hw", "1.2a", driver.hwVersion()); | 48 | assertEquals("incorrect driver hw", "1.2a", driver.hwVersion()); |
| 43 | assertEquals("incorrect driver sw", "2.2", driver.swVersion()); | 49 | assertEquals("incorrect driver sw", "2.2", driver.swVersion()); |
| 44 | 50 | ||
| 45 | - assertEquals("incorrect driver behaviours", 2, driver.behaviours().size()); | 51 | + assertEquals("incorrect driver behaviours", 1, driver.behaviours().size()); |
| 46 | assertTrue("incorrect driver behaviour", driver.hasBehaviour(TestBehaviour.class)); | 52 | assertTrue("incorrect driver behaviour", driver.hasBehaviour(TestBehaviour.class)); |
| 47 | 53 | ||
| 48 | assertEquals("incorrect driver properties", 2, driver.properties().size()); | 54 | assertEquals("incorrect driver properties", 2, driver.properties().size()); |
| ... | @@ -52,20 +58,20 @@ public class XmlDriverLoaderTest { | ... | @@ -52,20 +58,20 @@ public class XmlDriverLoaderTest { |
| 52 | @Test(expected = IOException.class) | 58 | @Test(expected = IOException.class) |
| 53 | public void badXML() throws IOException { | 59 | public void badXML() throws IOException { |
| 54 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); | 60 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); |
| 55 | - loader.loadDrivers(getClass().getResourceAsStream("drivers.bad.xml")); | 61 | + loader.loadDrivers(getClass().getResourceAsStream("drivers.bad.xml"), null); |
| 56 | } | 62 | } |
| 57 | 63 | ||
| 58 | @Test(expected = IllegalArgumentException.class) | 64 | @Test(expected = IllegalArgumentException.class) |
| 59 | public void noClass() throws IOException { | 65 | public void noClass() throws IOException { |
| 60 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); | 66 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); |
| 61 | - loader.loadDrivers(getClass().getResourceAsStream("drivers.noclass.xml")); | 67 | + loader.loadDrivers(getClass().getResourceAsStream("drivers.noclass.xml"), null); |
| 62 | } | 68 | } |
| 63 | 69 | ||
| 64 | @Test(expected = IllegalArgumentException.class) | 70 | @Test(expected = IllegalArgumentException.class) |
| 65 | public void noConstructor() throws IOException { | 71 | public void noConstructor() throws IOException { |
| 66 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); | 72 | XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader()); |
| 67 | InputStream stream = getClass().getResourceAsStream("drivers.noconstructor.xml"); | 73 | InputStream stream = getClass().getResourceAsStream("drivers.noconstructor.xml"); |
| 68 | - DriverProvider provider = loader.loadDrivers(stream); | 74 | + DriverProvider provider = loader.loadDrivers(stream, null); |
| 69 | Driver driver = provider.getDrivers().iterator().next(); | 75 | Driver driver = provider.getDrivers().iterator().next(); |
| 70 | driver.createBehaviour(new DefaultDriverData(driver), TestBehaviour.class); | 76 | driver.createBehaviour(new DefaultDriverData(driver), TestBehaviour.class); |
| 71 | } | 77 | } | ... | ... |
| ... | @@ -15,12 +15,15 @@ | ... | @@ -15,12 +15,15 @@ |
| 15 | ~ limitations under the License. | 15 | ~ limitations under the License. |
| 16 | --> | 16 | --> |
| 17 | <drivers> | 17 | <drivers> |
| 18 | - <driver name="foo.1" manufacturer="Circus" hwVersion="1.2a" swVersion="2.2"> | 18 | + <driver name="foo.0" manufacturer="Circus" hwVersion="1.2" swVersion="2.0"> |
| 19 | + <behaviour api="org.onosproject.net.driver.TestBehaviour" | ||
| 20 | + impl="org.onosproject.net.driver.TestBehaviourImpl"/> | ||
| 21 | + </driver> | ||
| 22 | + | ||
| 23 | + <driver name="foo.1" extends="foo.0" manufacturer="Circus" hwVersion="1.2a" swVersion="2.2"> | ||
| 19 | <fingerprint>ding</fingerprint> | 24 | <fingerprint>ding</fingerprint> |
| 20 | <fingerprint>bat</fingerprint> | 25 | <fingerprint>bat</fingerprint> |
| 21 | 26 | ||
| 22 | - <behaviour api="org.onosproject.net.driver.TestBehaviour" | ||
| 23 | - impl="org.onosproject.net.driver.TestBehaviourImpl"/> | ||
| 24 | <behaviour api="org.onosproject.net.driver.TestBehaviourTwo" | 27 | <behaviour api="org.onosproject.net.driver.TestBehaviourTwo" |
| 25 | impl="org.onosproject.net.driver.TestBehaviourTwoImpl"/> | 28 | impl="org.onosproject.net.driver.TestBehaviourTwoImpl"/> |
| 26 | 29 | ... | ... |
| ... | @@ -169,5 +169,4 @@ public class DriverManager extends DefaultDriverProvider implements DriverAdminS | ... | @@ -169,5 +169,4 @@ public class DriverManager extends DefaultDriverProvider implements DriverAdminS |
| 169 | private String key(String mfr, String hw, String sw) { | 169 | private String key(String mfr, String hw, String sw) { |
| 170 | return String.format("%s-%s-%s", mfr, hw, sw); | 170 | return String.format("%s-%s-%s", mfr, hw, sw); |
| 171 | } | 171 | } |
| 172 | - | ||
| 173 | } | 172 | } | ... | ... |
| ... | @@ -28,7 +28,6 @@ import org.onosproject.net.driver.XmlDriverLoader; | ... | @@ -28,7 +28,6 @@ import org.onosproject.net.driver.XmlDriverLoader; |
| 28 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
| 29 | import org.slf4j.LoggerFactory; | 29 | import org.slf4j.LoggerFactory; |
| 30 | 30 | ||
| 31 | -import java.io.IOException; | ||
| 32 | import java.io.InputStream; | 31 | import java.io.InputStream; |
| 33 | 32 | ||
| 34 | /** | 33 | /** |
| ... | @@ -52,9 +51,10 @@ public class DefaultDrivers implements DefaultDriverProviderService { | ... | @@ -52,9 +51,10 @@ public class DefaultDrivers implements DefaultDriverProviderService { |
| 52 | ClassLoader classLoader = getClass().getClassLoader(); | 51 | ClassLoader classLoader = getClass().getClassLoader(); |
| 53 | try { | 52 | try { |
| 54 | InputStream stream = classLoader.getResourceAsStream(DRIVERS_XML); | 53 | InputStream stream = classLoader.getResourceAsStream(DRIVERS_XML); |
| 55 | - provider = new XmlDriverLoader(classLoader).loadDrivers(stream); | 54 | + provider = new XmlDriverLoader(classLoader) |
| 55 | + .loadDrivers(stream, driverAdminService); | ||
| 56 | driverAdminService.registerProvider(provider); | 56 | driverAdminService.registerProvider(provider); |
| 57 | - } catch (IOException e) { | 57 | + } catch (Exception e) { |
| 58 | log.error("Unable to load default drivers", e); | 58 | log.error("Unable to load default drivers", e); |
| 59 | } | 59 | } |
| 60 | log.info("Started"); | 60 | log.info("Started"); | ... | ... |
-
Please register or login to post a comment