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