Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
better with files Change-Id: Ifb62a2c9a8e394fe3190582d7236eaea942ee3fc
Showing
45 changed files
with
736 additions
and
156 deletions
... | @@ -8,6 +8,9 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -8,6 +8,9 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
8 | import org.onlab.onos.cluster.ClusterEvent; | 8 | import org.onlab.onos.cluster.ClusterEvent; |
9 | import org.onlab.onos.cluster.ClusterEventListener; | 9 | import org.onlab.onos.cluster.ClusterEventListener; |
10 | import org.onlab.onos.cluster.ClusterService; | 10 | import org.onlab.onos.cluster.ClusterService; |
11 | +import org.onlab.onos.net.device.DeviceEvent; | ||
12 | +import org.onlab.onos.net.device.DeviceListener; | ||
13 | +import org.onlab.onos.net.device.DeviceService; | ||
11 | import org.slf4j.Logger; | 14 | import org.slf4j.Logger; |
12 | 15 | ||
13 | import static org.slf4j.LoggerFactory.getLogger; | 16 | import static org.slf4j.LoggerFactory.getLogger; |
... | @@ -23,17 +26,23 @@ public class FooComponent { | ... | @@ -23,17 +26,23 @@ public class FooComponent { |
23 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 26 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
24 | protected ClusterService clusterService; | 27 | protected ClusterService clusterService; |
25 | 28 | ||
26 | - private ClusterEventListener clusterListener = new InnerClusterListener(); | 29 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
30 | + protected DeviceService deviceService; | ||
31 | + | ||
32 | + private final ClusterEventListener clusterListener = new InnerClusterListener(); | ||
33 | + private final DeviceListener deviceListener = new InnerDeviceListener(); | ||
27 | 34 | ||
28 | @Activate | 35 | @Activate |
29 | public void activate() { | 36 | public void activate() { |
30 | clusterService.addListener(clusterListener); | 37 | clusterService.addListener(clusterListener); |
38 | + deviceService.addListener(deviceListener); | ||
31 | log.info("Started"); | 39 | log.info("Started"); |
32 | } | 40 | } |
33 | 41 | ||
34 | @Deactivate | 42 | @Deactivate |
35 | public void deactivate() { | 43 | public void deactivate() { |
36 | clusterService.removeListener(clusterListener); | 44 | clusterService.removeListener(clusterListener); |
45 | + deviceService.removeListener(deviceListener); | ||
37 | log.info("Stopped"); | 46 | log.info("Stopped"); |
38 | } | 47 | } |
39 | 48 | ||
... | @@ -43,6 +52,13 @@ public class FooComponent { | ... | @@ -43,6 +52,13 @@ public class FooComponent { |
43 | log.info("WOOOOT! {}", event); | 52 | log.info("WOOOOT! {}", event); |
44 | } | 53 | } |
45 | } | 54 | } |
55 | + | ||
56 | + private class InnerDeviceListener implements DeviceListener { | ||
57 | + @Override | ||
58 | + public void event(DeviceEvent event) { | ||
59 | + log.info("YEEEEHAAAAW! {}", event); | ||
60 | + } | ||
61 | + } | ||
46 | } | 62 | } |
47 | 63 | ||
48 | 64 | ... | ... |
1 | +package org.onlab.onos; | ||
2 | + | ||
3 | +import java.util.Objects; | ||
4 | +import java.util.concurrent.atomic.AtomicInteger; | ||
5 | + | ||
6 | +/** | ||
7 | + * Application id generator class. | ||
8 | + */ | ||
9 | +public final class ApplicationId { | ||
10 | + | ||
11 | + private static AtomicInteger idDispenser; | ||
12 | + private final Integer id; | ||
13 | + | ||
14 | + // Ban public construction | ||
15 | + private ApplicationId(Integer id) { | ||
16 | + this.id = id; | ||
17 | + } | ||
18 | + | ||
19 | + public Integer id() { | ||
20 | + return id; | ||
21 | + } | ||
22 | + | ||
23 | + public static ApplicationId valueOf(Integer id) { | ||
24 | + return new ApplicationId(id); | ||
25 | + } | ||
26 | + | ||
27 | + @Override | ||
28 | + public int hashCode() { | ||
29 | + return Objects.hash(id); | ||
30 | + } | ||
31 | + | ||
32 | + @Override | ||
33 | + public boolean equals(Object obj) { | ||
34 | + if (this == obj) { | ||
35 | + return true; | ||
36 | + } | ||
37 | + if (obj == null) { | ||
38 | + return false; | ||
39 | + } | ||
40 | + if (!(obj instanceof ApplicationId)) { | ||
41 | + return false; | ||
42 | + } | ||
43 | + ApplicationId other = (ApplicationId) obj; | ||
44 | + return Objects.equals(this.id, other.id); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Returns a new application id. | ||
49 | + * | ||
50 | + * @return app id | ||
51 | + */ | ||
52 | + public static ApplicationId getAppId() { | ||
53 | + if (ApplicationId.idDispenser == null) { | ||
54 | + ApplicationId.idDispenser = new AtomicInteger(1); | ||
55 | + } | ||
56 | + return new ApplicationId(ApplicationId.idDispenser.getAndIncrement()); | ||
57 | + } | ||
58 | + | ||
59 | +} |
... | @@ -4,12 +4,13 @@ import java.util.Set; | ... | @@ -4,12 +4,13 @@ import java.util.Set; |
4 | 4 | ||
5 | import org.onlab.onos.net.DeviceId; | 5 | import org.onlab.onos.net.DeviceId; |
6 | import org.onlab.onos.net.MastershipRole; | 6 | import org.onlab.onos.net.MastershipRole; |
7 | +import org.onlab.onos.store.Store; | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * Manages inventory of mastership roles for devices, across controller | 10 | * Manages inventory of mastership roles for devices, across controller |
10 | * instances; not intended for direct use. | 11 | * instances; not intended for direct use. |
11 | */ | 12 | */ |
12 | -public interface MastershipStore { | 13 | +public interface MastershipStore extends Store<MastershipEvent, MastershipStoreDelegate> { |
13 | 14 | ||
14 | // three things to map: NodeId, DeviceId, MastershipRole | 15 | // three things to map: NodeId, DeviceId, MastershipRole |
15 | 16 | ||
... | @@ -51,9 +52,7 @@ public interface MastershipStore { | ... | @@ -51,9 +52,7 @@ public interface MastershipStore { |
51 | * | 52 | * |
52 | * @param nodeId controller instance identifier | 53 | * @param nodeId controller instance identifier |
53 | * @param deviceId device identifier | 54 | * @param deviceId device identifier |
54 | - * @param role new role | ||
55 | * @return a mastership event | 55 | * @return a mastership event |
56 | */ | 56 | */ |
57 | - MastershipEvent setRole(NodeId nodeId, DeviceId deviceId, | 57 | + MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId); |
58 | - MastershipRole role); | ||
59 | } | 58 | } | ... | ... |
... | @@ -5,13 +5,14 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -5,13 +5,14 @@ import org.onlab.onos.net.DeviceId; |
5 | import org.onlab.onos.net.Port; | 5 | import org.onlab.onos.net.Port; |
6 | import org.onlab.onos.net.PortNumber; | 6 | import org.onlab.onos.net.PortNumber; |
7 | import org.onlab.onos.net.provider.ProviderId; | 7 | import org.onlab.onos.net.provider.ProviderId; |
8 | +import org.onlab.onos.store.Store; | ||
8 | 9 | ||
9 | import java.util.List; | 10 | import java.util.List; |
10 | 11 | ||
11 | /** | 12 | /** |
12 | * Manages inventory of infrastructure devices; not intended for direct use. | 13 | * Manages inventory of infrastructure devices; not intended for direct use. |
13 | */ | 14 | */ |
14 | -public interface DeviceStore { | 15 | +public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> { |
15 | 16 | ||
16 | /** | 17 | /** |
17 | * Returns the number of devices known to the system. | 18 | * Returns the number of devices known to the system. | ... | ... |
... | @@ -2,11 +2,12 @@ package org.onlab.onos.net.flow; | ... | @@ -2,11 +2,12 @@ package org.onlab.onos.net.flow; |
2 | 2 | ||
3 | import org.onlab.onos.ApplicationId; | 3 | import org.onlab.onos.ApplicationId; |
4 | import org.onlab.onos.net.DeviceId; | 4 | import org.onlab.onos.net.DeviceId; |
5 | +import org.onlab.onos.store.Store; | ||
5 | 6 | ||
6 | /** | 7 | /** |
7 | * Manages inventory of flow rules; not intended for direct use. | 8 | * Manages inventory of flow rules; not intended for direct use. |
8 | */ | 9 | */ |
9 | -public interface FlowRuleStore { | 10 | +public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> { |
10 | 11 | ||
11 | /** | 12 | /** |
12 | * Returns the stored flow. | 13 | * Returns the stored flow. | ... | ... |
1 | package org.onlab.onos.net.host; | 1 | package org.onlab.onos.net.host; |
2 | 2 | ||
3 | -import java.util.Set; | ||
4 | - | ||
5 | import org.onlab.onos.net.ConnectPoint; | 3 | import org.onlab.onos.net.ConnectPoint; |
6 | import org.onlab.onos.net.DeviceId; | 4 | import org.onlab.onos.net.DeviceId; |
7 | import org.onlab.onos.net.Host; | 5 | import org.onlab.onos.net.Host; |
8 | import org.onlab.onos.net.HostId; | 6 | import org.onlab.onos.net.HostId; |
9 | import org.onlab.onos.net.provider.ProviderId; | 7 | import org.onlab.onos.net.provider.ProviderId; |
8 | +import org.onlab.onos.store.Store; | ||
10 | import org.onlab.packet.IpPrefix; | 9 | import org.onlab.packet.IpPrefix; |
11 | import org.onlab.packet.MacAddress; | 10 | import org.onlab.packet.MacAddress; |
12 | import org.onlab.packet.VlanId; | 11 | import org.onlab.packet.VlanId; |
13 | 12 | ||
13 | +import java.util.Set; | ||
14 | + | ||
14 | /** | 15 | /** |
15 | * Manages inventory of end-station hosts; not intended for direct use. | 16 | * Manages inventory of end-station hosts; not intended for direct use. |
16 | */ | 17 | */ |
17 | -public interface HostStore { | 18 | +public interface HostStore extends Store<HostEvent, HostStoreDelegate> { |
18 | 19 | ||
19 | /** | 20 | /** |
20 | * Creates a new host or updates the existing one based on the specified | 21 | * Creates a new host or updates the existing one based on the specified |
... | @@ -133,7 +134,7 @@ public interface HostStore { | ... | @@ -133,7 +134,7 @@ public interface HostStore { |
133 | * Returns the address bindings for a particular connection point. | 134 | * Returns the address bindings for a particular connection point. |
134 | * | 135 | * |
135 | * @param connectPoint the connection point to return address information | 136 | * @param connectPoint the connection point to return address information |
136 | - * for | 137 | + * for |
137 | * @return address information for the connection point | 138 | * @return address information for the connection point |
138 | */ | 139 | */ |
139 | PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint); | 140 | PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint); | ... | ... |
... | @@ -4,13 +4,14 @@ import org.onlab.onos.net.ConnectPoint; | ... | @@ -4,13 +4,14 @@ import org.onlab.onos.net.ConnectPoint; |
4 | import org.onlab.onos.net.DeviceId; | 4 | import org.onlab.onos.net.DeviceId; |
5 | import org.onlab.onos.net.Link; | 5 | import org.onlab.onos.net.Link; |
6 | import org.onlab.onos.net.provider.ProviderId; | 6 | import org.onlab.onos.net.provider.ProviderId; |
7 | +import org.onlab.onos.store.Store; | ||
7 | 8 | ||
8 | import java.util.Set; | 9 | import java.util.Set; |
9 | 10 | ||
10 | /** | 11 | /** |
11 | * Manages inventory of infrastructure links; not intended for direct use. | 12 | * Manages inventory of infrastructure links; not intended for direct use. |
12 | */ | 13 | */ |
13 | -public interface LinkStore { | 14 | +public interface LinkStore extends Store<LinkEvent, LinkStoreDelegate> { |
14 | 15 | ||
15 | /** | 16 | /** |
16 | * Returns the number of links in the store. | 17 | * Returns the number of links in the store. | ... | ... |
... | @@ -6,6 +6,7 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -6,6 +6,7 @@ import org.onlab.onos.net.DeviceId; |
6 | import org.onlab.onos.net.Link; | 6 | import org.onlab.onos.net.Link; |
7 | import org.onlab.onos.net.Path; | 7 | import org.onlab.onos.net.Path; |
8 | import org.onlab.onos.net.provider.ProviderId; | 8 | import org.onlab.onos.net.provider.ProviderId; |
9 | +import org.onlab.onos.store.Store; | ||
9 | 10 | ||
10 | import java.util.List; | 11 | import java.util.List; |
11 | import java.util.Set; | 12 | import java.util.Set; |
... | @@ -13,7 +14,7 @@ import java.util.Set; | ... | @@ -13,7 +14,7 @@ import java.util.Set; |
13 | /** | 14 | /** |
14 | * Manages inventory of topology snapshots; not intended for direct use. | 15 | * Manages inventory of topology snapshots; not intended for direct use. |
15 | */ | 16 | */ |
16 | -public interface TopologyStore { | 17 | +public interface TopologyStore extends Store<TopologyEvent, TopologyStoreDelegate> { |
17 | 18 | ||
18 | /** | 19 | /** |
19 | * Returns the current topology snapshot. | 20 | * Returns the current topology snapshot. | ... | ... |
... | @@ -2,6 +2,8 @@ package org.onlab.onos.store; | ... | @@ -2,6 +2,8 @@ package org.onlab.onos.store; |
2 | 2 | ||
3 | import org.onlab.onos.event.Event; | 3 | import org.onlab.onos.event.Event; |
4 | 4 | ||
5 | +import static com.google.common.base.Preconditions.checkState; | ||
6 | + | ||
5 | /** | 7 | /** |
6 | * Base implementation of a store. | 8 | * Base implementation of a store. |
7 | */ | 9 | */ |
... | @@ -12,12 +14,21 @@ public class AbstractStore<E extends Event, D extends StoreDelegate<E>> | ... | @@ -12,12 +14,21 @@ public class AbstractStore<E extends Event, D extends StoreDelegate<E>> |
12 | 14 | ||
13 | @Override | 15 | @Override |
14 | public void setDelegate(D delegate) { | 16 | public void setDelegate(D delegate) { |
17 | + checkState(this.delegate == null || this.delegate == delegate, | ||
18 | + "Store delegate already set"); | ||
15 | this.delegate = delegate; | 19 | this.delegate = delegate; |
16 | } | 20 | } |
17 | 21 | ||
18 | @Override | 22 | @Override |
19 | - public D getDelegate() { | 23 | + public void unsetDelegate(D delegate) { |
20 | - return delegate; | 24 | + if (this.delegate == delegate) { |
25 | + this.delegate = null; | ||
26 | + } | ||
27 | + } | ||
28 | + | ||
29 | + @Override | ||
30 | + public boolean hasDelegate() { | ||
31 | + return delegate != null; | ||
21 | } | 32 | } |
22 | 33 | ||
23 | /** | 34 | /** | ... | ... |
... | @@ -12,14 +12,25 @@ public interface Store<E extends Event, D extends StoreDelegate<E>> { | ... | @@ -12,14 +12,25 @@ public interface Store<E extends Event, D extends StoreDelegate<E>> { |
12 | * Sets the delegate on the store. | 12 | * Sets the delegate on the store. |
13 | * | 13 | * |
14 | * @param delegate new store delegate | 14 | * @param delegate new store delegate |
15 | + * @throws java.lang.IllegalStateException if a delegate is already | ||
16 | + * currently set on the store and is a different one that | ||
15 | */ | 17 | */ |
16 | void setDelegate(D delegate); | 18 | void setDelegate(D delegate); |
17 | 19 | ||
18 | /** | 20 | /** |
19 | - * Get the current store delegate. | 21 | + * Withdraws the delegate from the store. |
20 | * | 22 | * |
21 | - * @return store delegate | 23 | + * @param delegate store delegate to withdraw |
24 | + * @throws java.lang.IllegalArgumentException if the delegate is not | ||
25 | + * currently set on the store | ||
22 | */ | 26 | */ |
23 | - D getDelegate(); | 27 | + void unsetDelegate(D delegate); |
28 | + | ||
29 | + /** | ||
30 | + * Indicates whether the store has a delegate. | ||
31 | + * | ||
32 | + * @return true if delegate is set | ||
33 | + */ | ||
34 | + boolean hasDelegate(); | ||
24 | 35 | ||
25 | } | 36 | } | ... | ... |
... | @@ -8,6 +8,11 @@ import org.onlab.onos.event.Event; | ... | @@ -8,6 +8,11 @@ import org.onlab.onos.event.Event; |
8 | */ | 8 | */ |
9 | public interface StoreDelegate<E extends Event> { | 9 | public interface StoreDelegate<E extends Event> { |
10 | 10 | ||
11 | + /** | ||
12 | + * Notifies the delegate via the specified event. | ||
13 | + * | ||
14 | + * @param event store generated event | ||
15 | + */ | ||
11 | void notify(E event); | 16 | void notify(E event); |
12 | 17 | ||
13 | } | 18 | } | ... | ... |
... | @@ -44,6 +44,13 @@ | ... | @@ -44,6 +44,13 @@ |
44 | <version>${project.version}</version> | 44 | <version>${project.version}</version> |
45 | <scope>test</scope> | 45 | <scope>test</scope> |
46 | </dependency> | 46 | </dependency> |
47 | + <dependency> | ||
48 | + <groupId>org.onlab.onos</groupId> | ||
49 | + <artifactId>onos-core-store</artifactId> | ||
50 | + <version>${project.version}</version> | ||
51 | + <classifier>tests</classifier> | ||
52 | + <scope>test</scope> | ||
53 | + </dependency> | ||
47 | 54 | ||
48 | <dependency> | 55 | <dependency> |
49 | <groupId>org.apache.felix</groupId> | 56 | <groupId>org.apache.felix</groupId> | ... | ... |
... | @@ -53,6 +53,7 @@ public class ClusterManager implements ClusterService, ClusterAdminService { | ... | @@ -53,6 +53,7 @@ public class ClusterManager implements ClusterService, ClusterAdminService { |
53 | 53 | ||
54 | @Deactivate | 54 | @Deactivate |
55 | public void deactivate() { | 55 | public void deactivate() { |
56 | + store.unsetDelegate(delegate); | ||
56 | eventDispatcher.removeSink(ClusterEvent.class); | 57 | eventDispatcher.removeSink(ClusterEvent.class); |
57 | log.info("Stopped"); | 58 | log.info("Stopped"); |
58 | } | 59 | } | ... | ... |
... | @@ -64,9 +64,12 @@ public class MastershipManager | ... | @@ -64,9 +64,12 @@ public class MastershipManager |
64 | checkNotNull(nodeId, NODE_ID_NULL); | 64 | checkNotNull(nodeId, NODE_ID_NULL); |
65 | checkNotNull(deviceId, DEVICE_ID_NULL); | 65 | checkNotNull(deviceId, DEVICE_ID_NULL); |
66 | checkNotNull(role, ROLE_NULL); | 66 | checkNotNull(role, ROLE_NULL); |
67 | - MastershipEvent event = store.setRole(nodeId, deviceId, role); | 67 | + //TODO figure out appropriate action for non-MASTER roles, if we even set those |
68 | - if (event != null) { | 68 | + if (role.equals(MastershipRole.MASTER)) { |
69 | - post(event); | 69 | + MastershipEvent event = store.setMaster(nodeId, deviceId); |
70 | + if (event != null) { | ||
71 | + post(event); | ||
72 | + } | ||
70 | } | 73 | } |
71 | } | 74 | } |
72 | 75 | ... | ... |
... | @@ -26,6 +26,7 @@ import org.onlab.onos.net.device.DeviceProviderRegistry; | ... | @@ -26,6 +26,7 @@ import org.onlab.onos.net.device.DeviceProviderRegistry; |
26 | import org.onlab.onos.net.device.DeviceProviderService; | 26 | import org.onlab.onos.net.device.DeviceProviderService; |
27 | import org.onlab.onos.net.device.DeviceService; | 27 | import org.onlab.onos.net.device.DeviceService; |
28 | import org.onlab.onos.net.device.DeviceStore; | 28 | import org.onlab.onos.net.device.DeviceStore; |
29 | +import org.onlab.onos.net.device.DeviceStoreDelegate; | ||
29 | import org.onlab.onos.net.device.PortDescription; | 30 | import org.onlab.onos.net.device.PortDescription; |
30 | import org.onlab.onos.net.provider.AbstractProviderRegistry; | 31 | import org.onlab.onos.net.provider.AbstractProviderRegistry; |
31 | import org.onlab.onos.net.provider.AbstractProviderService; | 32 | import org.onlab.onos.net.provider.AbstractProviderService; |
... | @@ -33,8 +34,8 @@ import org.slf4j.Logger; | ... | @@ -33,8 +34,8 @@ import org.slf4j.Logger; |
33 | 34 | ||
34 | import java.util.List; | 35 | import java.util.List; |
35 | 36 | ||
36 | -import static org.onlab.onos.net.device.DeviceEvent.Type.*; | ||
37 | import static com.google.common.base.Preconditions.checkNotNull; | 37 | import static com.google.common.base.Preconditions.checkNotNull; |
38 | +import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED; | ||
38 | import static org.slf4j.LoggerFactory.getLogger; | 39 | import static org.slf4j.LoggerFactory.getLogger; |
39 | 40 | ||
40 | /** | 41 | /** |
... | @@ -57,7 +58,9 @@ public class DeviceManager | ... | @@ -57,7 +58,9 @@ public class DeviceManager |
57 | protected final AbstractListenerRegistry<DeviceEvent, DeviceListener> | 58 | protected final AbstractListenerRegistry<DeviceEvent, DeviceListener> |
58 | listenerRegistry = new AbstractListenerRegistry<>(); | 59 | listenerRegistry = new AbstractListenerRegistry<>(); |
59 | 60 | ||
60 | - private final MastershipListener mastershipListener = new InnerMastershipListener(); | 61 | + private DeviceStoreDelegate delegate = new InternalStoreDelegate(); |
62 | + | ||
63 | + private final MastershipListener mastershipListener = new InternalMastershipListener(); | ||
61 | 64 | ||
62 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 65 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
63 | protected DeviceStore store; | 66 | protected DeviceStore store; |
... | @@ -73,6 +76,7 @@ public class DeviceManager | ... | @@ -73,6 +76,7 @@ public class DeviceManager |
73 | 76 | ||
74 | @Activate | 77 | @Activate |
75 | public void activate() { | 78 | public void activate() { |
79 | + store.setDelegate(delegate); | ||
76 | eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); | 80 | eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); |
77 | mastershipService.addListener(mastershipListener); | 81 | mastershipService.addListener(mastershipListener); |
78 | log.info("Started"); | 82 | log.info("Started"); |
... | @@ -80,6 +84,7 @@ public class DeviceManager | ... | @@ -80,6 +84,7 @@ public class DeviceManager |
80 | 84 | ||
81 | @Deactivate | 85 | @Deactivate |
82 | public void deactivate() { | 86 | public void deactivate() { |
87 | + store.unsetDelegate(delegate); | ||
83 | mastershipService.removeListener(mastershipListener); | 88 | mastershipService.removeListener(mastershipListener); |
84 | eventDispatcher.removeSink(DeviceEvent.class); | 89 | eventDispatcher.removeSink(DeviceEvent.class); |
85 | log.info("Stopped"); | 90 | log.info("Stopped"); |
... | @@ -239,7 +244,7 @@ public class DeviceManager | ... | @@ -239,7 +244,7 @@ public class DeviceManager |
239 | } | 244 | } |
240 | 245 | ||
241 | // Intercepts mastership events | 246 | // Intercepts mastership events |
242 | - private class InnerMastershipListener implements MastershipListener { | 247 | + private class InternalMastershipListener implements MastershipListener { |
243 | @Override | 248 | @Override |
244 | public void event(MastershipEvent event) { | 249 | public void event(MastershipEvent event) { |
245 | // FIXME: for now we're taking action only on becoming master | 250 | // FIXME: for now we're taking action only on becoming master |
... | @@ -248,4 +253,12 @@ public class DeviceManager | ... | @@ -248,4 +253,12 @@ public class DeviceManager |
248 | } | 253 | } |
249 | } | 254 | } |
250 | } | 255 | } |
256 | + | ||
257 | + // Store delegate to re-post events emitted from the store. | ||
258 | + private class InternalStoreDelegate implements DeviceStoreDelegate { | ||
259 | + @Override | ||
260 | + public void notify(DeviceEvent event) { | ||
261 | + post(event); | ||
262 | + } | ||
263 | + } | ||
251 | } | 264 | } | ... | ... |
1 | package org.onlab.onos.net.flow.impl; | 1 | package org.onlab.onos.net.flow.impl; |
2 | 2 | ||
3 | -import static com.google.common.base.Preconditions.checkNotNull; | 3 | +import com.google.common.collect.Lists; |
4 | -import static org.slf4j.LoggerFactory.getLogger; | ||
5 | - | ||
6 | -import java.util.Iterator; | ||
7 | -import java.util.List; | ||
8 | - | ||
9 | import org.apache.felix.scr.annotations.Activate; | 4 | import org.apache.felix.scr.annotations.Activate; |
10 | import org.apache.felix.scr.annotations.Component; | 5 | import org.apache.felix.scr.annotations.Component; |
11 | import org.apache.felix.scr.annotations.Deactivate; | 6 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -26,11 +21,16 @@ import org.onlab.onos.net.flow.FlowRuleProviderRegistry; | ... | @@ -26,11 +21,16 @@ import org.onlab.onos.net.flow.FlowRuleProviderRegistry; |
26 | import org.onlab.onos.net.flow.FlowRuleProviderService; | 21 | import org.onlab.onos.net.flow.FlowRuleProviderService; |
27 | import org.onlab.onos.net.flow.FlowRuleService; | 22 | import org.onlab.onos.net.flow.FlowRuleService; |
28 | import org.onlab.onos.net.flow.FlowRuleStore; | 23 | import org.onlab.onos.net.flow.FlowRuleStore; |
24 | +import org.onlab.onos.net.flow.FlowRuleStoreDelegate; | ||
29 | import org.onlab.onos.net.provider.AbstractProviderRegistry; | 25 | import org.onlab.onos.net.provider.AbstractProviderRegistry; |
30 | import org.onlab.onos.net.provider.AbstractProviderService; | 26 | import org.onlab.onos.net.provider.AbstractProviderService; |
31 | import org.slf4j.Logger; | 27 | import org.slf4j.Logger; |
32 | 28 | ||
33 | -import com.google.common.collect.Lists; | 29 | +import java.util.Iterator; |
30 | +import java.util.List; | ||
31 | + | ||
32 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
33 | +import static org.slf4j.LoggerFactory.getLogger; | ||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Provides implementation of the flow NB & SB APIs. | 36 | * Provides implementation of the flow NB & SB APIs. |
... | @@ -47,6 +47,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -47,6 +47,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
47 | private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener> | 47 | private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener> |
48 | listenerRegistry = new AbstractListenerRegistry<>(); | 48 | listenerRegistry = new AbstractListenerRegistry<>(); |
49 | 49 | ||
50 | + private FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); | ||
51 | + | ||
50 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 52 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
51 | protected FlowRuleStore store; | 53 | protected FlowRuleStore store; |
52 | 54 | ||
... | @@ -58,12 +60,14 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -58,12 +60,14 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
58 | 60 | ||
59 | @Activate | 61 | @Activate |
60 | public void activate() { | 62 | public void activate() { |
63 | + store.setDelegate(delegate); | ||
61 | eventDispatcher.addSink(FlowRuleEvent.class, listenerRegistry); | 64 | eventDispatcher.addSink(FlowRuleEvent.class, listenerRegistry); |
62 | log.info("Started"); | 65 | log.info("Started"); |
63 | } | 66 | } |
64 | 67 | ||
65 | @Deactivate | 68 | @Deactivate |
66 | public void deactivate() { | 69 | public void deactivate() { |
70 | + store.unsetDelegate(delegate); | ||
67 | eventDispatcher.removeSink(FlowRuleEvent.class); | 71 | eventDispatcher.removeSink(FlowRuleEvent.class); |
68 | log.info("Stopped"); | 72 | log.info("Stopped"); |
69 | } | 73 | } |
... | @@ -249,4 +253,11 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -249,4 +253,11 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
249 | } | 253 | } |
250 | } | 254 | } |
251 | 255 | ||
256 | + // Store delegate to re-post events emitted from the store. | ||
257 | + private class InternalStoreDelegate implements FlowRuleStoreDelegate { | ||
258 | + @Override | ||
259 | + public void notify(FlowRuleEvent event) { | ||
260 | + eventDispatcher.post(event); | ||
261 | + } | ||
262 | + } | ||
252 | } | 263 | } | ... | ... |
1 | package org.onlab.onos.net.host.impl; | 1 | package org.onlab.onos.net.host.impl; |
2 | 2 | ||
3 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | -import static org.slf4j.LoggerFactory.getLogger; | ||
5 | - | ||
6 | -import java.util.Set; | ||
7 | - | ||
8 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
9 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
10 | import org.apache.felix.scr.annotations.Deactivate; | 5 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -26,6 +21,7 @@ import org.onlab.onos.net.host.HostProviderRegistry; | ... | @@ -26,6 +21,7 @@ import org.onlab.onos.net.host.HostProviderRegistry; |
26 | import org.onlab.onos.net.host.HostProviderService; | 21 | import org.onlab.onos.net.host.HostProviderService; |
27 | import org.onlab.onos.net.host.HostService; | 22 | import org.onlab.onos.net.host.HostService; |
28 | import org.onlab.onos.net.host.HostStore; | 23 | import org.onlab.onos.net.host.HostStore; |
24 | +import org.onlab.onos.net.host.HostStoreDelegate; | ||
29 | import org.onlab.onos.net.host.PortAddresses; | 25 | import org.onlab.onos.net.host.PortAddresses; |
30 | import org.onlab.onos.net.provider.AbstractProviderRegistry; | 26 | import org.onlab.onos.net.provider.AbstractProviderRegistry; |
31 | import org.onlab.onos.net.provider.AbstractProviderService; | 27 | import org.onlab.onos.net.provider.AbstractProviderService; |
... | @@ -35,6 +31,11 @@ import org.onlab.packet.MacAddress; | ... | @@ -35,6 +31,11 @@ import org.onlab.packet.MacAddress; |
35 | import org.onlab.packet.VlanId; | 31 | import org.onlab.packet.VlanId; |
36 | import org.slf4j.Logger; | 32 | import org.slf4j.Logger; |
37 | 33 | ||
34 | +import java.util.Set; | ||
35 | + | ||
36 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
37 | +import static org.slf4j.LoggerFactory.getLogger; | ||
38 | + | ||
38 | /** | 39 | /** |
39 | * Provides basic implementation of the host SB & NB APIs. | 40 | * Provides basic implementation of the host SB & NB APIs. |
40 | */ | 41 | */ |
... | @@ -50,6 +51,8 @@ public class HostManager | ... | @@ -50,6 +51,8 @@ public class HostManager |
50 | private final AbstractListenerRegistry<HostEvent, HostListener> | 51 | private final AbstractListenerRegistry<HostEvent, HostListener> |
51 | listenerRegistry = new AbstractListenerRegistry<>(); | 52 | listenerRegistry = new AbstractListenerRegistry<>(); |
52 | 53 | ||
54 | + private HostStoreDelegate delegate = new InternalStoreDelegate(); | ||
55 | + | ||
53 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 56 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
54 | protected HostStore store; | 57 | protected HostStore store; |
55 | 58 | ||
... | @@ -59,12 +62,14 @@ public class HostManager | ... | @@ -59,12 +62,14 @@ public class HostManager |
59 | 62 | ||
60 | @Activate | 63 | @Activate |
61 | public void activate() { | 64 | public void activate() { |
65 | + store.setDelegate(delegate); | ||
62 | eventDispatcher.addSink(HostEvent.class, listenerRegistry); | 66 | eventDispatcher.addSink(HostEvent.class, listenerRegistry); |
63 | log.info("Started"); | 67 | log.info("Started"); |
64 | } | 68 | } |
65 | 69 | ||
66 | @Deactivate | 70 | @Deactivate |
67 | public void deactivate() { | 71 | public void deactivate() { |
72 | + store.unsetDelegate(delegate); | ||
68 | eventDispatcher.removeSink(HostEvent.class); | 73 | eventDispatcher.removeSink(HostEvent.class); |
69 | log.info("Stopped"); | 74 | log.info("Stopped"); |
70 | } | 75 | } |
... | @@ -219,4 +224,11 @@ public class HostManager | ... | @@ -219,4 +224,11 @@ public class HostManager |
219 | } | 224 | } |
220 | } | 225 | } |
221 | 226 | ||
227 | + // Store delegate to re-post events emitted from the store. | ||
228 | + private class InternalStoreDelegate implements HostStoreDelegate { | ||
229 | + @Override | ||
230 | + public void notify(HostEvent event) { | ||
231 | + post(event); | ||
232 | + } | ||
233 | + } | ||
222 | } | 234 | } | ... | ... |
... | @@ -28,6 +28,7 @@ import org.onlab.onos.net.link.LinkProviderRegistry; | ... | @@ -28,6 +28,7 @@ import org.onlab.onos.net.link.LinkProviderRegistry; |
28 | import org.onlab.onos.net.link.LinkProviderService; | 28 | import org.onlab.onos.net.link.LinkProviderService; |
29 | import org.onlab.onos.net.link.LinkService; | 29 | import org.onlab.onos.net.link.LinkService; |
30 | import org.onlab.onos.net.link.LinkStore; | 30 | import org.onlab.onos.net.link.LinkStore; |
31 | +import org.onlab.onos.net.link.LinkStoreDelegate; | ||
31 | import org.onlab.onos.net.provider.AbstractProviderRegistry; | 32 | import org.onlab.onos.net.provider.AbstractProviderRegistry; |
32 | import org.onlab.onos.net.provider.AbstractProviderService; | 33 | import org.onlab.onos.net.provider.AbstractProviderService; |
33 | import org.slf4j.Logger; | 34 | import org.slf4j.Logger; |
... | @@ -52,7 +53,9 @@ public class LinkManager | ... | @@ -52,7 +53,9 @@ public class LinkManager |
52 | protected final AbstractListenerRegistry<LinkEvent, LinkListener> | 53 | protected final AbstractListenerRegistry<LinkEvent, LinkListener> |
53 | listenerRegistry = new AbstractListenerRegistry<>(); | 54 | listenerRegistry = new AbstractListenerRegistry<>(); |
54 | 55 | ||
55 | - private final DeviceListener deviceListener = new InnerDeviceListener(); | 56 | + private LinkStoreDelegate delegate = new InternalStoreDelegate(); |
57 | + | ||
58 | + private final DeviceListener deviceListener = new InternalDeviceListener(); | ||
56 | 59 | ||
57 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 60 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
58 | protected LinkStore store; | 61 | protected LinkStore store; |
... | @@ -65,6 +68,7 @@ public class LinkManager | ... | @@ -65,6 +68,7 @@ public class LinkManager |
65 | 68 | ||
66 | @Activate | 69 | @Activate |
67 | public void activate() { | 70 | public void activate() { |
71 | + store.setDelegate(delegate); | ||
68 | eventDispatcher.addSink(LinkEvent.class, listenerRegistry); | 72 | eventDispatcher.addSink(LinkEvent.class, listenerRegistry); |
69 | deviceService.addListener(deviceListener); | 73 | deviceService.addListener(deviceListener); |
70 | log.info("Started"); | 74 | log.info("Started"); |
... | @@ -72,6 +76,7 @@ public class LinkManager | ... | @@ -72,6 +76,7 @@ public class LinkManager |
72 | 76 | ||
73 | @Deactivate | 77 | @Deactivate |
74 | public void deactivate() { | 78 | public void deactivate() { |
79 | + store.unsetDelegate(delegate); | ||
75 | eventDispatcher.removeSink(LinkEvent.class); | 80 | eventDispatcher.removeSink(LinkEvent.class); |
76 | deviceService.removeListener(deviceListener); | 81 | deviceService.removeListener(deviceListener); |
77 | log.info("Stopped"); | 82 | log.info("Stopped"); |
... | @@ -154,7 +159,7 @@ public class LinkManager | ... | @@ -154,7 +159,7 @@ public class LinkManager |
154 | 159 | ||
155 | // Auxiliary interceptor for device remove events to prune links that | 160 | // Auxiliary interceptor for device remove events to prune links that |
156 | // are associated with the removed device or its port. | 161 | // are associated with the removed device or its port. |
157 | - private class InnerDeviceListener implements DeviceListener { | 162 | + private class InternalDeviceListener implements DeviceListener { |
158 | @Override | 163 | @Override |
159 | public void event(DeviceEvent event) { | 164 | public void event(DeviceEvent event) { |
160 | if (event.type() == DeviceEvent.Type.DEVICE_REMOVED) { | 165 | if (event.type() == DeviceEvent.Type.DEVICE_REMOVED) { |
... | @@ -236,4 +241,11 @@ public class LinkManager | ... | @@ -236,4 +241,11 @@ public class LinkManager |
236 | } | 241 | } |
237 | } | 242 | } |
238 | 243 | ||
244 | + // Store delegate to re-post events emitted from the store. | ||
245 | + private class InternalStoreDelegate implements LinkStoreDelegate { | ||
246 | + @Override | ||
247 | + public void notify(LinkEvent event) { | ||
248 | + post(event); | ||
249 | + } | ||
250 | + } | ||
239 | } | 251 | } | ... | ... |
... | @@ -28,6 +28,7 @@ import org.onlab.onos.net.topology.TopologyProviderRegistry; | ... | @@ -28,6 +28,7 @@ import org.onlab.onos.net.topology.TopologyProviderRegistry; |
28 | import org.onlab.onos.net.topology.TopologyProviderService; | 28 | import org.onlab.onos.net.topology.TopologyProviderService; |
29 | import org.onlab.onos.net.topology.TopologyService; | 29 | import org.onlab.onos.net.topology.TopologyService; |
30 | import org.onlab.onos.net.topology.TopologyStore; | 30 | import org.onlab.onos.net.topology.TopologyStore; |
31 | +import org.onlab.onos.net.topology.TopologyStoreDelegate; | ||
31 | import org.slf4j.Logger; | 32 | import org.slf4j.Logger; |
32 | 33 | ||
33 | import java.util.List; | 34 | import java.util.List; |
... | @@ -56,6 +57,8 @@ public class TopologyManager | ... | @@ -56,6 +57,8 @@ public class TopologyManager |
56 | private final AbstractListenerRegistry<TopologyEvent, TopologyListener> | 57 | private final AbstractListenerRegistry<TopologyEvent, TopologyListener> |
57 | listenerRegistry = new AbstractListenerRegistry<>(); | 58 | listenerRegistry = new AbstractListenerRegistry<>(); |
58 | 59 | ||
60 | + private TopologyStoreDelegate delegate = new InternalStoreDelegate(); | ||
61 | + | ||
59 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 62 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
60 | protected TopologyStore store; | 63 | protected TopologyStore store; |
61 | 64 | ||
... | @@ -65,12 +68,14 @@ public class TopologyManager | ... | @@ -65,12 +68,14 @@ public class TopologyManager |
65 | 68 | ||
66 | @Activate | 69 | @Activate |
67 | public void activate() { | 70 | public void activate() { |
71 | + store.setDelegate(delegate); | ||
68 | eventDispatcher.addSink(TopologyEvent.class, listenerRegistry); | 72 | eventDispatcher.addSink(TopologyEvent.class, listenerRegistry); |
69 | log.info("Started"); | 73 | log.info("Started"); |
70 | } | 74 | } |
71 | 75 | ||
72 | @Deactivate | 76 | @Deactivate |
73 | public void deactivate() { | 77 | public void deactivate() { |
78 | + store.unsetDelegate(delegate); | ||
74 | eventDispatcher.removeSink(TopologyEvent.class); | 79 | eventDispatcher.removeSink(TopologyEvent.class); |
75 | log.info("Stopped"); | 80 | log.info("Stopped"); |
76 | } | 81 | } |
... | @@ -188,4 +193,11 @@ public class TopologyManager | ... | @@ -188,4 +193,11 @@ public class TopologyManager |
188 | } | 193 | } |
189 | } | 194 | } |
190 | 195 | ||
196 | + // Store delegate to re-post events emitted from the store. | ||
197 | + private class InternalStoreDelegate implements TopologyStoreDelegate { | ||
198 | + @Override | ||
199 | + public void notify(TopologyEvent event) { | ||
200 | + eventDispatcher.post(event); | ||
201 | + } | ||
202 | + } | ||
191 | } | 203 | } | ... | ... |
1 | +package org.onlab.onos.cluster.impl; | ||
2 | + | ||
3 | +import java.util.Set; | ||
4 | + | ||
5 | +import org.junit.After; | ||
6 | +import org.junit.Before; | ||
7 | +import org.junit.Test; | ||
8 | +import org.onlab.onos.cluster.ClusterEventListener; | ||
9 | +import org.onlab.onos.cluster.ClusterService; | ||
10 | +import org.onlab.onos.cluster.ControllerNode; | ||
11 | +import org.onlab.onos.cluster.ControllerNode.State; | ||
12 | +import org.onlab.onos.cluster.DefaultControllerNode; | ||
13 | +import org.onlab.onos.cluster.MastershipService; | ||
14 | +import org.onlab.onos.cluster.NodeId; | ||
15 | +import org.onlab.onos.event.impl.TestEventDispatcher; | ||
16 | +import org.onlab.onos.net.DeviceId; | ||
17 | +import org.onlab.onos.net.trivial.impl.SimpleMastershipStore; | ||
18 | +import org.onlab.packet.IpPrefix; | ||
19 | + | ||
20 | +import static org.junit.Assert.assertEquals; | ||
21 | +import static org.onlab.onos.net.MastershipRole.*; | ||
22 | + | ||
23 | +/** | ||
24 | + * Test codifying the mastership service contracts. | ||
25 | + */ | ||
26 | +public class MastershipManagerTest { | ||
27 | + | ||
28 | + private static final NodeId NID_LOCAL = new NodeId("local"); | ||
29 | + private static final NodeId NID_OTHER = new NodeId("foo"); | ||
30 | + private static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1"); | ||
31 | + private static final DeviceId DEV_MASTER = DeviceId.deviceId("of:1"); | ||
32 | + private static final DeviceId DEV_OTHER = DeviceId.deviceId("of:2"); | ||
33 | + | ||
34 | + private MastershipManager mgr; | ||
35 | + protected MastershipService service; | ||
36 | + | ||
37 | + @Before | ||
38 | + public void setUp() { | ||
39 | + mgr = new MastershipManager(); | ||
40 | + service = mgr; | ||
41 | + mgr.store = new SimpleMastershipStore(); | ||
42 | + mgr.eventDispatcher = new TestEventDispatcher(); | ||
43 | + mgr.clusterService = new TestClusterService(); | ||
44 | + mgr.activate(); | ||
45 | + } | ||
46 | + | ||
47 | + @After | ||
48 | + public void tearDown() { | ||
49 | + mgr.deactivate(); | ||
50 | + mgr.clusterService = null; | ||
51 | + mgr.eventDispatcher = null; | ||
52 | + mgr.store = null; | ||
53 | + } | ||
54 | + | ||
55 | + @Test | ||
56 | + public void setRole() { | ||
57 | + mgr.setRole(NID_OTHER, DEV_MASTER, MASTER); | ||
58 | + assertEquals("wrong local role:", STANDBY, mgr.getLocalRole(DEV_MASTER)); | ||
59 | + | ||
60 | + //set to master | ||
61 | + mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER); | ||
62 | + assertEquals("wrong local role:", MASTER, mgr.getLocalRole(DEV_MASTER)); | ||
63 | + } | ||
64 | + | ||
65 | + @Test | ||
66 | + public void relinquishMastership() { | ||
67 | + //TODO | ||
68 | + } | ||
69 | + | ||
70 | + @Test | ||
71 | + public void requestRoleFor() { | ||
72 | + mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER); | ||
73 | + mgr.setRole(NID_OTHER, DEV_OTHER, MASTER); | ||
74 | + | ||
75 | + //local should be master for one but standby for other | ||
76 | + assertEquals("wrong role:", MASTER, mgr.requestRoleFor(DEV_MASTER)); | ||
77 | + assertEquals("wrong role:", STANDBY, mgr.requestRoleFor(DEV_OTHER)); | ||
78 | + } | ||
79 | + | ||
80 | + @Test | ||
81 | + public void getMasterFor() { | ||
82 | + mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER); | ||
83 | + mgr.setRole(NID_OTHER, DEV_OTHER, MASTER); | ||
84 | + assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DEV_MASTER)); | ||
85 | + assertEquals("wrong master:", NID_OTHER, mgr.getMasterFor(DEV_OTHER)); | ||
86 | + | ||
87 | + //have NID_OTHER hand over DEV_OTHER to NID_LOCAL | ||
88 | + mgr.setRole(NID_LOCAL, DEV_OTHER, MASTER); | ||
89 | + assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DEV_OTHER)); | ||
90 | + } | ||
91 | + | ||
92 | + @Test | ||
93 | + public void getDevicesOf() { | ||
94 | + mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER); | ||
95 | + mgr.setRole(NID_LOCAL, DEV_OTHER, STANDBY); | ||
96 | + assertEquals("should be one device:", 1, mgr.getDevicesOf(NID_LOCAL).size()); | ||
97 | + | ||
98 | + //hand both devices to NID_LOCAL | ||
99 | + mgr.setRole(NID_LOCAL, DEV_OTHER, MASTER); | ||
100 | + assertEquals("should be two devices:", 2, mgr.getDevicesOf(NID_LOCAL).size()); | ||
101 | + } | ||
102 | + | ||
103 | + private final class TestClusterService implements ClusterService { | ||
104 | + | ||
105 | + ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST); | ||
106 | + | ||
107 | + @Override | ||
108 | + public ControllerNode getLocalNode() { | ||
109 | + return local; | ||
110 | + } | ||
111 | + | ||
112 | + @Override | ||
113 | + public Set<ControllerNode> getNodes() { | ||
114 | + return null; | ||
115 | + } | ||
116 | + | ||
117 | + @Override | ||
118 | + public ControllerNode getNode(NodeId nodeId) { | ||
119 | + return null; | ||
120 | + } | ||
121 | + | ||
122 | + @Override | ||
123 | + public State getState(NodeId nodeId) { | ||
124 | + return null; | ||
125 | + } | ||
126 | + | ||
127 | + @Override | ||
128 | + public void addListener(ClusterEventListener listener) { | ||
129 | + } | ||
130 | + | ||
131 | + @Override | ||
132 | + public void removeListener(ClusterEventListener listener) { | ||
133 | + } | ||
134 | + | ||
135 | + } | ||
136 | +} |
... | @@ -4,13 +4,15 @@ import com.google.common.collect.Iterables; | ... | @@ -4,13 +4,15 @@ import com.google.common.collect.Iterables; |
4 | import com.google.common.collect.Sets; | 4 | import com.google.common.collect.Sets; |
5 | import com.hazelcast.config.Config; | 5 | import com.hazelcast.config.Config; |
6 | import com.hazelcast.core.Hazelcast; | 6 | import com.hazelcast.core.Hazelcast; |
7 | -import com.hazelcast.core.HazelcastInstance; | 7 | + |
8 | import org.junit.After; | 8 | import org.junit.After; |
9 | import org.junit.Before; | 9 | import org.junit.Before; |
10 | import org.junit.Test; | 10 | import org.junit.Test; |
11 | +import org.onlab.onos.cluster.DefaultControllerNode; | ||
11 | import org.onlab.onos.cluster.MastershipServiceAdapter; | 12 | import org.onlab.onos.cluster.MastershipServiceAdapter; |
12 | import org.onlab.onos.cluster.NodeId; | 13 | import org.onlab.onos.cluster.NodeId; |
13 | import org.onlab.onos.event.Event; | 14 | import org.onlab.onos.event.Event; |
15 | +import org.onlab.onos.event.EventDeliveryService; | ||
14 | import org.onlab.onos.event.impl.TestEventDispatcher; | 16 | import org.onlab.onos.event.impl.TestEventDispatcher; |
15 | import org.onlab.onos.net.Device; | 17 | import org.onlab.onos.net.Device; |
16 | import org.onlab.onos.net.DeviceId; | 18 | import org.onlab.onos.net.DeviceId; |
... | @@ -30,23 +32,26 @@ import org.onlab.onos.net.device.DeviceService; | ... | @@ -30,23 +32,26 @@ import org.onlab.onos.net.device.DeviceService; |
30 | import org.onlab.onos.net.device.PortDescription; | 32 | import org.onlab.onos.net.device.PortDescription; |
31 | import org.onlab.onos.net.provider.AbstractProvider; | 33 | import org.onlab.onos.net.provider.AbstractProvider; |
32 | import org.onlab.onos.net.provider.ProviderId; | 34 | import org.onlab.onos.net.provider.ProviderId; |
33 | -import org.onlab.onos.store.common.StoreService; | ||
34 | import org.onlab.onos.store.device.impl.DistributedDeviceStore; | 35 | import org.onlab.onos.store.device.impl.DistributedDeviceStore; |
35 | import org.onlab.onos.store.impl.StoreManager; | 36 | import org.onlab.onos.store.impl.StoreManager; |
37 | +import org.onlab.onos.store.impl.TestStoreManager; | ||
38 | +import org.onlab.packet.IpPrefix; | ||
36 | 39 | ||
37 | import java.util.ArrayList; | 40 | import java.util.ArrayList; |
41 | +import java.util.HashSet; | ||
38 | import java.util.Iterator; | 42 | import java.util.Iterator; |
39 | import java.util.List; | 43 | import java.util.List; |
44 | +import java.util.Map.Entry; | ||
40 | import java.util.Set; | 45 | import java.util.Set; |
41 | -import java.util.UUID; | 46 | +import java.util.concurrent.ConcurrentHashMap; |
47 | +import java.util.concurrent.ConcurrentMap; | ||
42 | 48 | ||
43 | import static org.junit.Assert.*; | 49 | import static org.junit.Assert.*; |
44 | import static org.onlab.onos.net.Device.Type.SWITCH; | 50 | import static org.onlab.onos.net.Device.Type.SWITCH; |
45 | import static org.onlab.onos.net.DeviceId.deviceId; | 51 | import static org.onlab.onos.net.DeviceId.deviceId; |
46 | import static org.onlab.onos.net.device.DeviceEvent.Type.*; | 52 | import static org.onlab.onos.net.device.DeviceEvent.Type.*; |
47 | 53 | ||
48 | -// FIXME This test is painfully slow starting up Hazelcast on each test cases, | 54 | +// FIXME This test is slow starting up Hazelcast on each test cases. |
49 | -// turning it off in repository for now. | ||
50 | // FIXME DistributedDeviceStore should have it's own test cases. | 55 | // FIXME DistributedDeviceStore should have it's own test cases. |
51 | 56 | ||
52 | /** | 57 | /** |
... | @@ -67,6 +72,11 @@ public class DistributedDeviceManagerTest { | ... | @@ -67,6 +72,11 @@ public class DistributedDeviceManagerTest { |
67 | private static final PortNumber P2 = PortNumber.portNumber(2); | 72 | private static final PortNumber P2 = PortNumber.portNumber(2); |
68 | private static final PortNumber P3 = PortNumber.portNumber(3); | 73 | private static final PortNumber P3 = PortNumber.portNumber(3); |
69 | 74 | ||
75 | + private static final DefaultControllerNode SELF | ||
76 | + = new DefaultControllerNode(new NodeId("foobar"), | ||
77 | + IpPrefix.valueOf("127.0.0.1")); | ||
78 | + | ||
79 | + | ||
70 | private DeviceManager mgr; | 80 | private DeviceManager mgr; |
71 | 81 | ||
72 | protected StoreManager storeManager; | 82 | protected StoreManager storeManager; |
... | @@ -77,6 +87,8 @@ public class DistributedDeviceManagerTest { | ... | @@ -77,6 +87,8 @@ public class DistributedDeviceManagerTest { |
77 | protected TestProvider provider; | 87 | protected TestProvider provider; |
78 | protected TestListener listener = new TestListener(); | 88 | protected TestListener listener = new TestListener(); |
79 | private DistributedDeviceStore dstore; | 89 | private DistributedDeviceStore dstore; |
90 | + private TestMastershipManager masterManager; | ||
91 | + private EventDeliveryService eventService; | ||
80 | 92 | ||
81 | @Before | 93 | @Before |
82 | public void setUp() { | 94 | public void setUp() { |
... | @@ -84,26 +96,21 @@ public class DistributedDeviceManagerTest { | ... | @@ -84,26 +96,21 @@ public class DistributedDeviceManagerTest { |
84 | service = mgr; | 96 | service = mgr; |
85 | admin = mgr; | 97 | admin = mgr; |
86 | registry = mgr; | 98 | registry = mgr; |
87 | - // FIXME should be reading the hazelcast.xml | 99 | + // TODO should find a way to clean Hazelcast instance without shutdown. |
88 | - Config config = new Config(); | 100 | + Config config = TestStoreManager.getTestConfig(); |
89 | - // avoid accidentally joining other cluster | 101 | + |
90 | - config.getGroupConfig().setName(UUID.randomUUID().toString()); | 102 | + masterManager = new TestMastershipManager(); |
91 | - // quickly form single node cluster | ||
92 | - config.getNetworkConfig().getJoin() | ||
93 | - .getTcpIpConfig() | ||
94 | - .setEnabled(true).setConnectionTimeoutSeconds(0); | ||
95 | - config.getNetworkConfig().getJoin() | ||
96 | - .getMulticastConfig() | ||
97 | - .setEnabled(false); | ||
98 | 103 | ||
99 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); | 104 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); |
100 | storeManager.activate(); | 105 | storeManager.activate(); |
101 | 106 | ||
102 | - dstore = new TestDistributedDeviceStore(storeManager); | 107 | + dstore = new TestDistributedDeviceStore(); |
103 | dstore.activate(); | 108 | dstore.activate(); |
109 | + | ||
104 | mgr.store = dstore; | 110 | mgr.store = dstore; |
105 | - mgr.eventDispatcher = new TestEventDispatcher(); | 111 | + eventService = new TestEventDispatcher(); |
106 | - mgr.mastershipService = new TestMastershipService(); | 112 | + mgr.eventDispatcher = eventService; |
113 | + mgr.mastershipService = masterManager; | ||
107 | mgr.activate(); | 114 | mgr.activate(); |
108 | 115 | ||
109 | service.addListener(listener); | 116 | service.addListener(listener); |
... | @@ -153,7 +160,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -153,7 +160,7 @@ public class DistributedDeviceManagerTest { |
153 | public void deviceDisconnected() { | 160 | public void deviceDisconnected() { |
154 | connectDevice(DID1, SW1); | 161 | connectDevice(DID1, SW1); |
155 | connectDevice(DID2, SW1); | 162 | connectDevice(DID2, SW1); |
156 | - validateEvents(DEVICE_ADDED, DEVICE_ADDED); | 163 | + validateEvents(DEVICE_ADDED, DEVICE_ADDED, DEVICE_ADDED, DEVICE_ADDED); |
157 | assertTrue("device should be available", service.isAvailable(DID1)); | 164 | assertTrue("device should be available", service.isAvailable(DID1)); |
158 | 165 | ||
159 | // Disconnect | 166 | // Disconnect |
... | @@ -172,7 +179,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -172,7 +179,7 @@ public class DistributedDeviceManagerTest { |
172 | @Test | 179 | @Test |
173 | public void deviceUpdated() { | 180 | public void deviceUpdated() { |
174 | connectDevice(DID1, SW1); | 181 | connectDevice(DID1, SW1); |
175 | - validateEvents(DEVICE_ADDED); | 182 | + validateEvents(DEVICE_ADDED, DEVICE_ADDED); |
176 | 183 | ||
177 | connectDevice(DID1, SW2); | 184 | connectDevice(DID1, SW2); |
178 | validateEvents(DEVICE_UPDATED); | 185 | validateEvents(DEVICE_UPDATED); |
... | @@ -192,7 +199,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -192,7 +199,7 @@ public class DistributedDeviceManagerTest { |
192 | pds.add(new DefaultPortDescription(P2, true)); | 199 | pds.add(new DefaultPortDescription(P2, true)); |
193 | pds.add(new DefaultPortDescription(P3, true)); | 200 | pds.add(new DefaultPortDescription(P3, true)); |
194 | providerService.updatePorts(DID1, pds); | 201 | providerService.updatePorts(DID1, pds); |
195 | - validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED); | 202 | + validateEvents(DEVICE_ADDED, DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED); |
196 | pds.clear(); | 203 | pds.clear(); |
197 | 204 | ||
198 | pds.add(new DefaultPortDescription(P1, false)); | 205 | pds.add(new DefaultPortDescription(P1, false)); |
... | @@ -208,7 +215,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -208,7 +215,7 @@ public class DistributedDeviceManagerTest { |
208 | pds.add(new DefaultPortDescription(P1, true)); | 215 | pds.add(new DefaultPortDescription(P1, true)); |
209 | pds.add(new DefaultPortDescription(P2, true)); | 216 | pds.add(new DefaultPortDescription(P2, true)); |
210 | providerService.updatePorts(DID1, pds); | 217 | providerService.updatePorts(DID1, pds); |
211 | - validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED); | 218 | + validateEvents(DEVICE_ADDED, DEVICE_ADDED, PORT_ADDED, PORT_ADDED); |
212 | 219 | ||
213 | providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false)); | 220 | providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false)); |
214 | validateEvents(PORT_UPDATED); | 221 | validateEvents(PORT_UPDATED); |
... | @@ -223,7 +230,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -223,7 +230,7 @@ public class DistributedDeviceManagerTest { |
223 | pds.add(new DefaultPortDescription(P1, true)); | 230 | pds.add(new DefaultPortDescription(P1, true)); |
224 | pds.add(new DefaultPortDescription(P2, true)); | 231 | pds.add(new DefaultPortDescription(P2, true)); |
225 | providerService.updatePorts(DID1, pds); | 232 | providerService.updatePorts(DID1, pds); |
226 | - validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED); | 233 | + validateEvents(DEVICE_ADDED, DEVICE_ADDED, PORT_ADDED, PORT_ADDED); |
227 | assertEquals("wrong port count", 2, service.getPorts(DID1).size()); | 234 | assertEquals("wrong port count", 2, service.getPorts(DID1).size()); |
228 | 235 | ||
229 | Port port = service.getPort(DID1, P1); | 236 | Port port = service.getPort(DID1, P1); |
... | @@ -237,10 +244,10 @@ public class DistributedDeviceManagerTest { | ... | @@ -237,10 +244,10 @@ public class DistributedDeviceManagerTest { |
237 | connectDevice(DID2, SW2); | 244 | connectDevice(DID2, SW2); |
238 | assertEquals("incorrect device count", 2, service.getDeviceCount()); | 245 | assertEquals("incorrect device count", 2, service.getDeviceCount()); |
239 | admin.removeDevice(DID1); | 246 | admin.removeDevice(DID1); |
247 | + validateEvents(DEVICE_ADDED, DEVICE_ADDED, DEVICE_ADDED, DEVICE_ADDED, DEVICE_REMOVED, DEVICE_REMOVED); | ||
240 | assertNull("device should not be found", service.getDevice(DID1)); | 248 | assertNull("device should not be found", service.getDevice(DID1)); |
241 | assertNotNull("device should be found", service.getDevice(DID2)); | 249 | assertNotNull("device should be found", service.getDevice(DID2)); |
242 | assertEquals("incorrect device count", 1, service.getDeviceCount()); | 250 | assertEquals("incorrect device count", 1, service.getDeviceCount()); |
243 | - | ||
244 | } | 251 | } |
245 | 252 | ||
246 | protected void validateEvents(Enum... types) { | 253 | protected void validateEvents(Enum... types) { |
... | @@ -283,23 +290,21 @@ public class DistributedDeviceManagerTest { | ... | @@ -283,23 +290,21 @@ public class DistributedDeviceManagerTest { |
283 | } | 290 | } |
284 | 291 | ||
285 | private class TestDistributedDeviceStore extends DistributedDeviceStore { | 292 | private class TestDistributedDeviceStore extends DistributedDeviceStore { |
286 | - public TestDistributedDeviceStore(StoreService storeService) { | 293 | + |
287 | - this.storeService = storeService; | 294 | + public TestDistributedDeviceStore() { |
295 | + this.storeService = storeManager; | ||
288 | } | 296 | } |
289 | } | 297 | } |
290 | 298 | ||
291 | - private class TestStoreManager extends StoreManager { | 299 | + private static class TestMastershipManager extends MastershipServiceAdapter { |
292 | - TestStoreManager(HazelcastInstance instance) { | ||
293 | - this.instance = instance; | ||
294 | - } | ||
295 | 300 | ||
296 | - @Override | 301 | + private ConcurrentMap<DeviceId, NodeId> masters = new ConcurrentHashMap<>(); |
297 | - public void activate() { | ||
298 | - setupKryoPool(); | ||
299 | - } | ||
300 | - } | ||
301 | 302 | ||
302 | - private static class TestMastershipService extends MastershipServiceAdapter { | 303 | + public TestMastershipManager() { |
304 | + // SELF master of all initially | ||
305 | + masters.put(DID1, SELF.id()); | ||
306 | + masters.put(DID1, SELF.id()); | ||
307 | + } | ||
303 | @Override | 308 | @Override |
304 | public MastershipRole getLocalRole(DeviceId deviceId) { | 309 | public MastershipRole getLocalRole(DeviceId deviceId) { |
305 | return MastershipRole.MASTER; | 310 | return MastershipRole.MASTER; |
... | @@ -307,13 +312,27 @@ public class DistributedDeviceManagerTest { | ... | @@ -307,13 +312,27 @@ public class DistributedDeviceManagerTest { |
307 | 312 | ||
308 | @Override | 313 | @Override |
309 | public Set<DeviceId> getDevicesOf(NodeId nodeId) { | 314 | public Set<DeviceId> getDevicesOf(NodeId nodeId) { |
310 | - return Sets.newHashSet(DID1, DID2); | 315 | + HashSet<DeviceId> set = Sets.newHashSet(); |
316 | + for (Entry<DeviceId, NodeId> e : masters.entrySet()) { | ||
317 | + if (e.getValue().equals(nodeId)) { | ||
318 | + set.add(e.getKey()); | ||
319 | + } | ||
320 | + } | ||
321 | + return set; | ||
311 | } | 322 | } |
312 | 323 | ||
313 | @Override | 324 | @Override |
314 | public MastershipRole requestRoleFor(DeviceId deviceId) { | 325 | public MastershipRole requestRoleFor(DeviceId deviceId) { |
315 | - return MastershipRole.MASTER; | 326 | + if (SELF.id().equals(masters.get(deviceId))) { |
327 | + return MastershipRole.MASTER; | ||
328 | + } else { | ||
329 | + return MastershipRole.STANDBY; | ||
330 | + } | ||
316 | } | 331 | } |
317 | - } | ||
318 | 332 | ||
333 | + @Override | ||
334 | + public void relinquishMastership(DeviceId deviceId) { | ||
335 | + masters.remove(deviceId, SELF.id()); | ||
336 | + } | ||
337 | + } | ||
319 | } | 338 | } | ... | ... |
... | @@ -4,6 +4,7 @@ import com.google.common.base.Optional; | ... | @@ -4,6 +4,7 @@ import com.google.common.base.Optional; |
4 | import com.google.common.cache.LoadingCache; | 4 | import com.google.common.cache.LoadingCache; |
5 | import com.google.common.collect.ImmutableSet; | 5 | import com.google.common.collect.ImmutableSet; |
6 | import com.hazelcast.core.IMap; | 6 | import com.hazelcast.core.IMap; |
7 | + | ||
7 | import org.apache.felix.scr.annotations.Activate; | 8 | import org.apache.felix.scr.annotations.Activate; |
8 | import org.apache.felix.scr.annotations.Component; | 9 | import org.apache.felix.scr.annotations.Component; |
9 | import org.apache.felix.scr.annotations.Deactivate; | 10 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -42,6 +43,7 @@ public class DistributedMastershipStore | ... | @@ -42,6 +43,7 @@ public class DistributedMastershipStore |
42 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 43 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
43 | protected ClusterService clusterService; | 44 | protected ClusterService clusterService; |
44 | 45 | ||
46 | + @Override | ||
45 | @Activate | 47 | @Activate |
46 | public void activate() { | 48 | public void activate() { |
47 | super.activate(); | 49 | super.activate(); |
... | @@ -52,19 +54,28 @@ public class DistributedMastershipStore | ... | @@ -52,19 +54,28 @@ public class DistributedMastershipStore |
52 | masters = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader)); | 54 | masters = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader)); |
53 | rawMasters.addEntryListener(new RemoteEventHandler<>(masters), true); | 55 | rawMasters.addEntryListener(new RemoteEventHandler<>(masters), true); |
54 | 56 | ||
57 | + loadMasters(); | ||
58 | + | ||
55 | log.info("Started"); | 59 | log.info("Started"); |
56 | } | 60 | } |
57 | 61 | ||
62 | + private void loadMasters() { | ||
63 | + for (byte[] keyBytes : rawMasters.keySet()) { | ||
64 | + final DeviceId id = deserialize(keyBytes); | ||
65 | + masters.refresh(id); | ||
66 | + } | ||
67 | + } | ||
68 | + | ||
58 | @Deactivate | 69 | @Deactivate |
59 | public void deactivate() { | 70 | public void deactivate() { |
60 | log.info("Stopped"); | 71 | log.info("Stopped"); |
61 | } | 72 | } |
62 | 73 | ||
63 | @Override | 74 | @Override |
64 | - public MastershipEvent setRole(NodeId nodeId, DeviceId deviceId, MastershipRole role) { | 75 | + public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) { |
65 | synchronized (this) { | 76 | synchronized (this) { |
66 | NodeId currentMaster = getMaster(deviceId); | 77 | NodeId currentMaster = getMaster(deviceId); |
67 | - if (role == MastershipRole.MASTER && Objects.equals(currentMaster, nodeId)) { | 78 | + if (Objects.equals(currentMaster, nodeId)) { |
68 | return null; | 79 | return null; |
69 | } | 80 | } |
70 | 81 | ||
... | @@ -94,7 +105,7 @@ public class DistributedMastershipStore | ... | @@ -94,7 +105,7 @@ public class DistributedMastershipStore |
94 | @Override | 105 | @Override |
95 | public MastershipRole requestRole(DeviceId deviceId) { | 106 | public MastershipRole requestRole(DeviceId deviceId) { |
96 | // FIXME: for now we are 'selecting' as master whoever asks | 107 | // FIXME: for now we are 'selecting' as master whoever asks |
97 | - setRole(clusterService.getLocalNode().id(), deviceId, MastershipRole.MASTER); | 108 | + setMaster(clusterService.getLocalNode().id(), deviceId); |
98 | return MastershipRole.MASTER; | 109 | return MastershipRole.MASTER; |
99 | } | 110 | } |
100 | 111 | ... | ... |
... | @@ -15,7 +15,6 @@ import org.onlab.onos.net.DefaultDevice; | ... | @@ -15,7 +15,6 @@ import org.onlab.onos.net.DefaultDevice; |
15 | import org.onlab.onos.net.DefaultPort; | 15 | import org.onlab.onos.net.DefaultPort; |
16 | import org.onlab.onos.net.Device; | 16 | import org.onlab.onos.net.Device; |
17 | import org.onlab.onos.net.DeviceId; | 17 | import org.onlab.onos.net.DeviceId; |
18 | -import org.onlab.onos.net.MastershipRole; | ||
19 | import org.onlab.onos.net.Port; | 18 | import org.onlab.onos.net.Port; |
20 | import org.onlab.onos.net.PortNumber; | 19 | import org.onlab.onos.net.PortNumber; |
21 | import org.onlab.onos.net.device.DeviceDescription; | 20 | import org.onlab.onos.net.device.DeviceDescription; |
... | @@ -61,10 +60,6 @@ public class DistributedDeviceStore | ... | @@ -61,10 +60,6 @@ public class DistributedDeviceStore |
61 | private IMap<byte[], byte[]> rawDevices; | 60 | private IMap<byte[], byte[]> rawDevices; |
62 | private LoadingCache<DeviceId, Optional<DefaultDevice>> devices; | 61 | private LoadingCache<DeviceId, Optional<DefaultDevice>> devices; |
63 | 62 | ||
64 | - // private IMap<DeviceId, MastershipRole> roles; | ||
65 | - private IMap<byte[], byte[]> rawRoles; | ||
66 | - private LoadingCache<DeviceId, Optional<MastershipRole>> roles; | ||
67 | - | ||
68 | // private ISet<DeviceId> availableDevices; | 63 | // private ISet<DeviceId> availableDevices; |
69 | private ISet<byte[]> availableDevices; | 64 | private ISet<byte[]> availableDevices; |
70 | 65 | ||
... | @@ -73,6 +68,7 @@ public class DistributedDeviceStore | ... | @@ -73,6 +68,7 @@ public class DistributedDeviceStore |
73 | private IMap<byte[], byte[]> rawDevicePorts; | 68 | private IMap<byte[], byte[]> rawDevicePorts; |
74 | private LoadingCache<DeviceId, Optional<Map<PortNumber, Port>>> devicePorts; | 69 | private LoadingCache<DeviceId, Optional<Map<PortNumber, Port>>> devicePorts; |
75 | 70 | ||
71 | + @Override | ||
76 | @Activate | 72 | @Activate |
77 | public void activate() { | 73 | public void activate() { |
78 | super.activate(); | 74 | super.activate(); |
... | @@ -86,14 +82,7 @@ public class DistributedDeviceStore | ... | @@ -86,14 +82,7 @@ public class DistributedDeviceStore |
86 | = new OptionalCacheLoader<>(storeService, rawDevices); | 82 | = new OptionalCacheLoader<>(storeService, rawDevices); |
87 | devices = new AbsentInvalidatingLoadingCache<>(newBuilder().build(deviceLoader)); | 83 | devices = new AbsentInvalidatingLoadingCache<>(newBuilder().build(deviceLoader)); |
88 | // refresh/populate cache based on notification from other instance | 84 | // refresh/populate cache based on notification from other instance |
89 | - rawDevices.addEntryListener(new RemoteEventHandler<>(devices), includeValue); | 85 | + rawDevices.addEntryListener(new RemoteDeviceEventHandler(devices), includeValue); |
90 | - | ||
91 | - rawRoles = theInstance.getMap("roles"); | ||
92 | - final OptionalCacheLoader<DeviceId, MastershipRole> rolesLoader | ||
93 | - = new OptionalCacheLoader<>(storeService, rawRoles); | ||
94 | - roles = new AbsentInvalidatingLoadingCache<>(newBuilder().build(rolesLoader)); | ||
95 | - // refresh/populate cache based on notification from other instance | ||
96 | - rawRoles.addEntryListener(new RemoteEventHandler<>(roles), includeValue); | ||
97 | 86 | ||
98 | // TODO cache availableDevices | 87 | // TODO cache availableDevices |
99 | availableDevices = theInstance.getSet("availableDevices"); | 88 | availableDevices = theInstance.getSet("availableDevices"); |
... | @@ -103,7 +92,9 @@ public class DistributedDeviceStore | ... | @@ -103,7 +92,9 @@ public class DistributedDeviceStore |
103 | = new OptionalCacheLoader<>(storeService, rawDevicePorts); | 92 | = new OptionalCacheLoader<>(storeService, rawDevicePorts); |
104 | devicePorts = new AbsentInvalidatingLoadingCache<>(newBuilder().build(devicePortLoader)); | 93 | devicePorts = new AbsentInvalidatingLoadingCache<>(newBuilder().build(devicePortLoader)); |
105 | // refresh/populate cache based on notification from other instance | 94 | // refresh/populate cache based on notification from other instance |
106 | - rawDevicePorts.addEntryListener(new RemoteEventHandler<>(devicePorts), includeValue); | 95 | + rawDevicePorts.addEntryListener(new RemotePortEventHandler(devicePorts), includeValue); |
96 | + | ||
97 | + loadDeviceCache(); | ||
107 | 98 | ||
108 | log.info("Started"); | 99 | log.info("Started"); |
109 | } | 100 | } |
... | @@ -115,22 +106,11 @@ public class DistributedDeviceStore | ... | @@ -115,22 +106,11 @@ public class DistributedDeviceStore |
115 | 106 | ||
116 | @Override | 107 | @Override |
117 | public int getDeviceCount() { | 108 | public int getDeviceCount() { |
118 | - // TODO IMap size or cache size? | 109 | + return devices.asMap().size(); |
119 | - return rawDevices.size(); | ||
120 | } | 110 | } |
121 | 111 | ||
122 | @Override | 112 | @Override |
123 | public Iterable<Device> getDevices() { | 113 | public Iterable<Device> getDevices() { |
124 | -// TODO Revisit if we ever need to do this. | ||
125 | -// log.info("{}:{}", rawMap.size(), cache.size()); | ||
126 | -// if (rawMap.size() != cache.size()) { | ||
127 | -// for (Entry<byte[], byte[]> e : rawMap.entrySet()) { | ||
128 | -// final DeviceId key = deserialize(e.getKey()); | ||
129 | -// final DefaultDevice val = deserialize(e.getValue()); | ||
130 | -// cache.put(key, val); | ||
131 | -// } | ||
132 | -// } | ||
133 | - | ||
134 | // TODO builder v.s. copyOf. Guava semms to be using copyOf? | 114 | // TODO builder v.s. copyOf. Guava semms to be using copyOf? |
135 | Builder<Device> builder = ImmutableSet.builder(); | 115 | Builder<Device> builder = ImmutableSet.builder(); |
136 | for (Optional<DefaultDevice> e : devices.asMap().values()) { | 116 | for (Optional<DefaultDevice> e : devices.asMap().values()) { |
... | @@ -141,6 +121,17 @@ public class DistributedDeviceStore | ... | @@ -141,6 +121,17 @@ public class DistributedDeviceStore |
141 | return builder.build(); | 121 | return builder.build(); |
142 | } | 122 | } |
143 | 123 | ||
124 | + private void loadDeviceCache() { | ||
125 | + log.info("{}:{}", rawDevices.size(), devices.size()); | ||
126 | + if (rawDevices.size() != devices.size()) { | ||
127 | + for (Map.Entry<byte[], byte[]> e : rawDevices.entrySet()) { | ||
128 | + final DeviceId key = deserialize(e.getKey()); | ||
129 | + final DefaultDevice val = deserialize(e.getValue()); | ||
130 | + devices.put(key, Optional.of(val)); | ||
131 | + } | ||
132 | + } | ||
133 | + } | ||
134 | + | ||
144 | @Override | 135 | @Override |
145 | public Device getDevice(DeviceId deviceId) { | 136 | public Device getDevice(DeviceId deviceId) { |
146 | // TODO revisit if ignoring exception is safe. | 137 | // TODO revisit if ignoring exception is safe. |
... | @@ -171,12 +162,8 @@ public class DistributedDeviceStore | ... | @@ -171,12 +162,8 @@ public class DistributedDeviceStore |
171 | devices.put(deviceId, Optional.of(device)); | 162 | devices.put(deviceId, Optional.of(device)); |
172 | 163 | ||
173 | availableDevices.add(deviceIdBytes); | 164 | availableDevices.add(deviceIdBytes); |
174 | - | ||
175 | - // For now claim the device as a master automatically. | ||
176 | - //rawRoles.put(deviceIdBytes, serialize(MastershipRole.MASTER)); | ||
177 | - //roles.put(deviceId, Optional.of(MastershipRole.MASTER)); | ||
178 | } | 165 | } |
179 | - return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null); | 166 | + return new DeviceEvent(DEVICE_ADDED, device, null); |
180 | } | 167 | } |
181 | 168 | ||
182 | // Updates the device and returns the appropriate event if necessary. | 169 | // Updates the device and returns the appropriate event if necessary. |
... | @@ -348,8 +335,6 @@ public class DistributedDeviceStore | ... | @@ -348,8 +335,6 @@ public class DistributedDeviceStore |
348 | public DeviceEvent removeDevice(DeviceId deviceId) { | 335 | public DeviceEvent removeDevice(DeviceId deviceId) { |
349 | synchronized (this) { | 336 | synchronized (this) { |
350 | byte[] deviceIdBytes = serialize(deviceId); | 337 | byte[] deviceIdBytes = serialize(deviceId); |
351 | - rawRoles.remove(deviceIdBytes); | ||
352 | - roles.invalidate(deviceId); | ||
353 | 338 | ||
354 | // TODO conditional remove? | 339 | // TODO conditional remove? |
355 | Device device = deserialize(rawDevices.remove(deviceIdBytes)); | 340 | Device device = deserialize(rawDevices.remove(deviceIdBytes)); |
... | @@ -359,6 +344,48 @@ public class DistributedDeviceStore | ... | @@ -359,6 +344,48 @@ public class DistributedDeviceStore |
359 | } | 344 | } |
360 | } | 345 | } |
361 | 346 | ||
362 | - // TODO cache serialized DeviceID if we suffer from serialization cost | 347 | + private class RemoteDeviceEventHandler extends RemoteEventHandler<DeviceId, DefaultDevice> { |
348 | + public RemoteDeviceEventHandler(LoadingCache<DeviceId, Optional<DefaultDevice>> cache) { | ||
349 | + super(cache); | ||
350 | + } | ||
351 | + | ||
352 | + @Override | ||
353 | + protected void onAdd(DeviceId deviceId, DefaultDevice device) { | ||
354 | + delegate.notify(new DeviceEvent(DEVICE_ADDED, device)); | ||
355 | + } | ||
363 | 356 | ||
357 | + @Override | ||
358 | + protected void onRemove(DeviceId deviceId, DefaultDevice device) { | ||
359 | + delegate.notify(new DeviceEvent(DEVICE_REMOVED, device)); | ||
360 | + } | ||
361 | + | ||
362 | + @Override | ||
363 | + protected void onUpdate(DeviceId deviceId, DefaultDevice device) { | ||
364 | + delegate.notify(new DeviceEvent(DEVICE_UPDATED, device)); | ||
365 | + } | ||
366 | + } | ||
367 | + | ||
368 | + private class RemotePortEventHandler extends RemoteEventHandler<DeviceId, Map<PortNumber, Port>> { | ||
369 | + public RemotePortEventHandler(LoadingCache<DeviceId, Optional<Map<PortNumber, Port>>> cache) { | ||
370 | + super(cache); | ||
371 | + } | ||
372 | + | ||
373 | + @Override | ||
374 | + protected void onAdd(DeviceId deviceId, Map<PortNumber, Port> ports) { | ||
375 | +// delegate.notify(new DeviceEvent(PORT_ADDED, getDevice(deviceId))); | ||
376 | + } | ||
377 | + | ||
378 | + @Override | ||
379 | + protected void onRemove(DeviceId deviceId, Map<PortNumber, Port> ports) { | ||
380 | +// delegate.notify(new DeviceEvent(PORT_REMOVED, getDevice(deviceId))); | ||
381 | + } | ||
382 | + | ||
383 | + @Override | ||
384 | + protected void onUpdate(DeviceId deviceId, Map<PortNumber, Port> ports) { | ||
385 | +// delegate.notify(new DeviceEvent(PORT_UPDATED, getDevice(deviceId))); | ||
386 | + } | ||
387 | + } | ||
388 | + | ||
389 | + | ||
390 | + // TODO cache serialized DeviceID if we suffer from serialization cost | ||
364 | } | 391 | } | ... | ... |
... | @@ -24,7 +24,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -24,7 +24,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
24 | */ | 24 | */ |
25 | @Component(componentAbstract = true) | 25 | @Component(componentAbstract = true) |
26 | public abstract class AbstractDistributedStore<E extends Event, D extends StoreDelegate<E>> | 26 | public abstract class AbstractDistributedStore<E extends Event, D extends StoreDelegate<E>> |
27 | - extends AbstractStore<E, D> { | 27 | + extends AbstractStore<E, D> { |
28 | 28 | ||
29 | protected final Logger log = getLogger(getClass()); | 29 | protected final Logger log = getLogger(getClass()); |
30 | 30 | ||
... | @@ -66,7 +66,7 @@ public abstract class AbstractDistributedStore<E extends Event, D extends StoreD | ... | @@ -66,7 +66,7 @@ public abstract class AbstractDistributedStore<E extends Event, D extends StoreD |
66 | * @param <K> IMap key type after deserialization | 66 | * @param <K> IMap key type after deserialization |
67 | * @param <V> IMap value type after deserialization | 67 | * @param <V> IMap value type after deserialization |
68 | */ | 68 | */ |
69 | - public final class RemoteEventHandler<K, V> extends EntryAdapter<byte[], byte[]> { | 69 | + public class RemoteEventHandler<K, V> extends EntryAdapter<byte[], byte[]> { |
70 | 70 | ||
71 | private LoadingCache<K, Optional<V>> cache; | 71 | private LoadingCache<K, Optional<V>> cache; |
72 | 72 | ||
... | @@ -85,19 +85,58 @@ public abstract class AbstractDistributedStore<E extends Event, D extends StoreD | ... | @@ -85,19 +85,58 @@ public abstract class AbstractDistributedStore<E extends Event, D extends StoreD |
85 | } | 85 | } |
86 | 86 | ||
87 | @Override | 87 | @Override |
88 | + public void entryAdded(EntryEvent<byte[], byte[]> event) { | ||
89 | + K key = deserialize(event.getKey()); | ||
90 | + V newVal = deserialize(event.getValue()); | ||
91 | + Optional<V> newValue = Optional.of(newVal); | ||
92 | + cache.asMap().putIfAbsent(key, newValue); | ||
93 | + onAdd(key, newVal); | ||
94 | + } | ||
95 | + | ||
96 | + @Override | ||
88 | public void entryUpdated(EntryEvent<byte[], byte[]> event) { | 97 | public void entryUpdated(EntryEvent<byte[], byte[]> event) { |
89 | - cache.put(storeService.<K>deserialize(event.getKey()), | 98 | + K key = deserialize(event.getKey()); |
90 | - Optional.of(storeService.<V>deserialize(event.getValue()))); | 99 | + V oldVal = deserialize(event.getOldValue()); |
100 | + Optional<V> oldValue = Optional.fromNullable(oldVal); | ||
101 | + V newVal = deserialize(event.getValue()); | ||
102 | + Optional<V> newValue = Optional.of(newVal); | ||
103 | + cache.asMap().replace(key, oldValue, newValue); | ||
104 | + onUpdate(key, newVal); | ||
91 | } | 105 | } |
92 | 106 | ||
93 | @Override | 107 | @Override |
94 | public void entryRemoved(EntryEvent<byte[], byte[]> event) { | 108 | public void entryRemoved(EntryEvent<byte[], byte[]> event) { |
95 | - cache.invalidate(storeService.<K>deserialize(event.getKey())); | 109 | + K key = deserialize(event.getKey()); |
110 | + V val = deserialize(event.getValue()); | ||
111 | + cache.invalidate(key); | ||
112 | + onRemove(key, val); | ||
96 | } | 113 | } |
97 | 114 | ||
98 | - @Override | 115 | + /** |
99 | - public void entryAdded(EntryEvent<byte[], byte[]> event) { | 116 | + * Cache entry addition hook. |
100 | - entryUpdated(event); | 117 | + * |
118 | + * @param key new key | ||
119 | + * @param newVal new value | ||
120 | + */ | ||
121 | + protected void onAdd(K key, V newVal) { | ||
122 | + } | ||
123 | + | ||
124 | + /** | ||
125 | + * Cache entry update hook. | ||
126 | + * | ||
127 | + * @param key new key | ||
128 | + * @param newVal new value | ||
129 | + */ | ||
130 | + protected void onUpdate(K key, V newVal) { | ||
131 | + } | ||
132 | + | ||
133 | + /** | ||
134 | + * Cache entry remove hook. | ||
135 | + * | ||
136 | + * @param key new key | ||
137 | + * @param val old value | ||
138 | + */ | ||
139 | + protected void onRemove(K key, V val) { | ||
101 | } | 140 | } |
102 | } | 141 | } |
103 | 142 | ... | ... |
... | @@ -45,7 +45,7 @@ import java.util.HashMap; | ... | @@ -45,7 +45,7 @@ import java.util.HashMap; |
45 | @Service | 45 | @Service |
46 | public class StoreManager implements StoreService { | 46 | public class StoreManager implements StoreService { |
47 | 47 | ||
48 | - private static final String HAZELCAST_XML_FILE = "etc/hazelcast.xml"; | 48 | + protected static final String HAZELCAST_XML_FILE = "etc/hazelcast.xml"; |
49 | 49 | ||
50 | private final Logger log = LoggerFactory.getLogger(getClass()); | 50 | private final Logger log = LoggerFactory.getLogger(getClass()); |
51 | 51 | ... | ... |
1 | +package org.onlab.onos.store.impl; | ||
2 | + | ||
3 | +import java.io.FileNotFoundException; | ||
4 | +import java.util.UUID; | ||
5 | + | ||
6 | +import com.hazelcast.config.Config; | ||
7 | +import com.hazelcast.config.FileSystemXmlConfig; | ||
8 | +import com.hazelcast.core.HazelcastInstance; | ||
9 | + | ||
10 | +/** | ||
11 | + * Dummy StoreManager to use specified Hazelcast instance. | ||
12 | + */ | ||
13 | +public class TestStoreManager extends StoreManager { | ||
14 | + | ||
15 | + /** | ||
16 | + * Gets the Hazelcast Config for testing. | ||
17 | + * | ||
18 | + * @return | ||
19 | + */ | ||
20 | + public static Config getTestConfig() { | ||
21 | + Config config; | ||
22 | + try { | ||
23 | + config = new FileSystemXmlConfig(HAZELCAST_XML_FILE); | ||
24 | + } catch (FileNotFoundException e) { | ||
25 | + // falling back to default | ||
26 | + config = new Config(); | ||
27 | + } | ||
28 | + // avoid accidentally joining other cluster | ||
29 | + config.getGroupConfig().setName(UUID.randomUUID().toString()); | ||
30 | + // quickly form single node cluster | ||
31 | + config.getNetworkConfig().getJoin() | ||
32 | + .getTcpIpConfig() | ||
33 | + .setEnabled(true).setConnectionTimeoutSeconds(0); | ||
34 | + config.getNetworkConfig().getJoin() | ||
35 | + .getMulticastConfig() | ||
36 | + .setEnabled(false); | ||
37 | + return config; | ||
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * Constructor. | ||
42 | + * | ||
43 | + * @param instance Hazelast instance to return on #getHazelcastInstance() | ||
44 | + */ | ||
45 | + public TestStoreManager(HazelcastInstance instance) { | ||
46 | + this.instance = instance; | ||
47 | + } | ||
48 | + | ||
49 | + // Hazelcast setup removed from original code. | ||
50 | + @Override | ||
51 | + public void activate() { | ||
52 | + setupKryoPool(); | ||
53 | + } | ||
54 | +} |
... | @@ -15,8 +15,10 @@ import org.onlab.onos.net.PortNumber; | ... | @@ -15,8 +15,10 @@ import org.onlab.onos.net.PortNumber; |
15 | import org.onlab.onos.net.device.DeviceDescription; | 15 | import org.onlab.onos.net.device.DeviceDescription; |
16 | import org.onlab.onos.net.device.DeviceEvent; | 16 | import org.onlab.onos.net.device.DeviceEvent; |
17 | import org.onlab.onos.net.device.DeviceStore; | 17 | import org.onlab.onos.net.device.DeviceStore; |
18 | +import org.onlab.onos.net.device.DeviceStoreDelegate; | ||
18 | import org.onlab.onos.net.device.PortDescription; | 19 | import org.onlab.onos.net.device.PortDescription; |
19 | import org.onlab.onos.net.provider.ProviderId; | 20 | import org.onlab.onos.net.provider.ProviderId; |
21 | +import org.onlab.onos.store.AbstractStore; | ||
20 | import org.slf4j.Logger; | 22 | import org.slf4j.Logger; |
21 | 23 | ||
22 | import java.util.ArrayList; | 24 | import java.util.ArrayList; |
... | @@ -40,7 +42,9 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -40,7 +42,9 @@ import static org.slf4j.LoggerFactory.getLogger; |
40 | */ | 42 | */ |
41 | @Component(immediate = true) | 43 | @Component(immediate = true) |
42 | @Service | 44 | @Service |
43 | -public class SimpleDeviceStore implements DeviceStore { | 45 | +public class SimpleDeviceStore |
46 | + extends AbstractStore<DeviceEvent, DeviceStoreDelegate> | ||
47 | + implements DeviceStore { | ||
44 | 48 | ||
45 | private final Logger log = getLogger(getClass()); | 49 | private final Logger log = getLogger(getClass()); |
46 | 50 | ... | ... |
... | @@ -19,6 +19,8 @@ import org.onlab.onos.net.flow.FlowRule.FlowRuleState; | ... | @@ -19,6 +19,8 @@ import org.onlab.onos.net.flow.FlowRule.FlowRuleState; |
19 | import org.onlab.onos.net.flow.FlowRuleEvent; | 19 | import org.onlab.onos.net.flow.FlowRuleEvent; |
20 | import org.onlab.onos.net.flow.FlowRuleEvent.Type; | 20 | import org.onlab.onos.net.flow.FlowRuleEvent.Type; |
21 | import org.onlab.onos.net.flow.FlowRuleStore; | 21 | import org.onlab.onos.net.flow.FlowRuleStore; |
22 | +import org.onlab.onos.net.flow.FlowRuleStoreDelegate; | ||
23 | +import org.onlab.onos.store.AbstractStore; | ||
22 | import org.slf4j.Logger; | 24 | import org.slf4j.Logger; |
23 | 25 | ||
24 | import com.google.common.collect.ArrayListMultimap; | 26 | import com.google.common.collect.ArrayListMultimap; |
... | @@ -30,7 +32,9 @@ import com.google.common.collect.Multimap; | ... | @@ -30,7 +32,9 @@ import com.google.common.collect.Multimap; |
30 | */ | 32 | */ |
31 | @Component(immediate = true) | 33 | @Component(immediate = true) |
32 | @Service | 34 | @Service |
33 | -public class SimpleFlowRuleStore implements FlowRuleStore { | 35 | +public class SimpleFlowRuleStore |
36 | + extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate> | ||
37 | + implements FlowRuleStore { | ||
34 | 38 | ||
35 | private final Logger log = getLogger(getClass()); | 39 | private final Logger log = getLogger(getClass()); |
36 | 40 | ... | ... |
... | @@ -24,8 +24,10 @@ import org.onlab.onos.net.HostId; | ... | @@ -24,8 +24,10 @@ import org.onlab.onos.net.HostId; |
24 | import org.onlab.onos.net.host.HostDescription; | 24 | import org.onlab.onos.net.host.HostDescription; |
25 | import org.onlab.onos.net.host.HostEvent; | 25 | import org.onlab.onos.net.host.HostEvent; |
26 | import org.onlab.onos.net.host.HostStore; | 26 | import org.onlab.onos.net.host.HostStore; |
27 | +import org.onlab.onos.net.host.HostStoreDelegate; | ||
27 | import org.onlab.onos.net.host.PortAddresses; | 28 | import org.onlab.onos.net.host.PortAddresses; |
28 | import org.onlab.onos.net.provider.ProviderId; | 29 | import org.onlab.onos.net.provider.ProviderId; |
30 | +import org.onlab.onos.store.AbstractStore; | ||
29 | import org.onlab.packet.IpPrefix; | 31 | import org.onlab.packet.IpPrefix; |
30 | import org.onlab.packet.MacAddress; | 32 | import org.onlab.packet.MacAddress; |
31 | import org.onlab.packet.VlanId; | 33 | import org.onlab.packet.VlanId; |
... | @@ -41,7 +43,9 @@ import com.google.common.collect.Multimap; | ... | @@ -41,7 +43,9 @@ import com.google.common.collect.Multimap; |
41 | */ | 43 | */ |
42 | @Component(immediate = true) | 44 | @Component(immediate = true) |
43 | @Service | 45 | @Service |
44 | -public class SimpleHostStore implements HostStore { | 46 | +public class SimpleHostStore |
47 | + extends AbstractStore<HostEvent, HostStoreDelegate> | ||
48 | + implements HostStore { | ||
45 | 49 | ||
46 | private final Logger log = getLogger(getClass()); | 50 | private final Logger log = getLogger(getClass()); |
47 | 51 | ... | ... |
... | @@ -14,7 +14,9 @@ import org.onlab.onos.net.Link; | ... | @@ -14,7 +14,9 @@ import org.onlab.onos.net.Link; |
14 | import org.onlab.onos.net.link.LinkDescription; | 14 | import org.onlab.onos.net.link.LinkDescription; |
15 | import org.onlab.onos.net.link.LinkEvent; | 15 | import org.onlab.onos.net.link.LinkEvent; |
16 | import org.onlab.onos.net.link.LinkStore; | 16 | import org.onlab.onos.net.link.LinkStore; |
17 | +import org.onlab.onos.net.link.LinkStoreDelegate; | ||
17 | import org.onlab.onos.net.provider.ProviderId; | 18 | import org.onlab.onos.net.provider.ProviderId; |
19 | +import org.onlab.onos.store.AbstractStore; | ||
18 | import org.slf4j.Logger; | 20 | import org.slf4j.Logger; |
19 | 21 | ||
20 | import java.util.Collections; | 22 | import java.util.Collections; |
... | @@ -35,7 +37,9 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -35,7 +37,9 @@ import static org.slf4j.LoggerFactory.getLogger; |
35 | */ | 37 | */ |
36 | @Component(immediate = true) | 38 | @Component(immediate = true) |
37 | @Service | 39 | @Service |
38 | -public class SimpleLinkStore implements LinkStore { | 40 | +public class SimpleLinkStore |
41 | + extends AbstractStore<LinkEvent, LinkStoreDelegate> | ||
42 | + implements LinkStore { | ||
39 | 43 | ||
40 | private final Logger log = getLogger(getClass()); | 44 | private final Logger log = getLogger(getClass()); |
41 | 45 | ... | ... |
... | @@ -3,6 +3,8 @@ package org.onlab.onos.net.trivial.impl; | ... | @@ -3,6 +3,8 @@ package org.onlab.onos.net.trivial.impl; |
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | import java.util.Collections; | 5 | import java.util.Collections; |
6 | +import java.util.HashSet; | ||
7 | +import java.util.Map; | ||
6 | import java.util.Set; | 8 | import java.util.Set; |
7 | import java.util.concurrent.ConcurrentHashMap; | 9 | import java.util.concurrent.ConcurrentHashMap; |
8 | import java.util.concurrent.ConcurrentMap; | 10 | import java.util.concurrent.ConcurrentMap; |
... | @@ -15,9 +17,11 @@ import org.onlab.onos.cluster.ControllerNode; | ... | @@ -15,9 +17,11 @@ import org.onlab.onos.cluster.ControllerNode; |
15 | import org.onlab.onos.cluster.DefaultControllerNode; | 17 | import org.onlab.onos.cluster.DefaultControllerNode; |
16 | import org.onlab.onos.cluster.MastershipEvent; | 18 | import org.onlab.onos.cluster.MastershipEvent; |
17 | import org.onlab.onos.cluster.MastershipStore; | 19 | import org.onlab.onos.cluster.MastershipStore; |
20 | +import org.onlab.onos.cluster.MastershipStoreDelegate; | ||
18 | import org.onlab.onos.cluster.NodeId; | 21 | import org.onlab.onos.cluster.NodeId; |
19 | import org.onlab.onos.net.DeviceId; | 22 | import org.onlab.onos.net.DeviceId; |
20 | import org.onlab.onos.net.MastershipRole; | 23 | import org.onlab.onos.net.MastershipRole; |
24 | +import org.onlab.onos.store.AbstractStore; | ||
21 | import org.onlab.packet.IpPrefix; | 25 | import org.onlab.packet.IpPrefix; |
22 | import org.slf4j.Logger; | 26 | import org.slf4j.Logger; |
23 | 27 | ||
... | @@ -25,24 +29,27 @@ import static org.onlab.onos.cluster.MastershipEvent.Type.*; | ... | @@ -25,24 +29,27 @@ import static org.onlab.onos.cluster.MastershipEvent.Type.*; |
25 | 29 | ||
26 | /** | 30 | /** |
27 | * Manages inventory of controller mastership over devices using | 31 | * Manages inventory of controller mastership over devices using |
28 | - * trivial in-memory structures implementation. | 32 | + * trivial, non-distributed in-memory structures implementation. |
29 | */ | 33 | */ |
30 | @Component(immediate = true) | 34 | @Component(immediate = true) |
31 | @Service | 35 | @Service |
32 | -public class SimpleMastershipStore implements MastershipStore { | 36 | +public class SimpleMastershipStore |
33 | - | 37 | + extends AbstractStore<MastershipEvent, MastershipStoreDelegate> |
34 | - public static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1"); | 38 | + implements MastershipStore { |
35 | 39 | ||
36 | private final Logger log = getLogger(getClass()); | 40 | private final Logger log = getLogger(getClass()); |
37 | 41 | ||
38 | - private ControllerNode instance; | 42 | + public static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1"); |
43 | + | ||
44 | + private ControllerNode instance = | ||
45 | + new DefaultControllerNode(new NodeId("local"), LOCALHOST); | ||
39 | 46 | ||
40 | - protected final ConcurrentMap<DeviceId, MastershipRole> roleMap = | 47 | + //devices mapped to their masters, to emulate multiple nodes |
48 | + protected final ConcurrentMap<DeviceId, NodeId> masterMap = | ||
41 | new ConcurrentHashMap<>(); | 49 | new ConcurrentHashMap<>(); |
42 | 50 | ||
43 | @Activate | 51 | @Activate |
44 | public void activate() { | 52 | public void activate() { |
45 | - instance = new DefaultControllerNode(new NodeId("local"), LOCALHOST); | ||
46 | log.info("Started"); | 53 | log.info("Started"); |
47 | } | 54 | } |
48 | 55 | ||
... | @@ -52,23 +59,36 @@ public class SimpleMastershipStore implements MastershipStore { | ... | @@ -52,23 +59,36 @@ public class SimpleMastershipStore implements MastershipStore { |
52 | } | 59 | } |
53 | 60 | ||
54 | @Override | 61 | @Override |
55 | - public MastershipEvent setRole(NodeId nodeId, DeviceId deviceId, | 62 | + public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) { |
56 | - MastershipRole role) { | 63 | + |
57 | - if (roleMap.get(deviceId) == null) { | 64 | + NodeId node = masterMap.get(deviceId); |
65 | + if (node == null) { | ||
66 | + masterMap.put(deviceId, nodeId); | ||
67 | + return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); | ||
68 | + } | ||
69 | + | ||
70 | + if (node.equals(nodeId)) { | ||
58 | return null; | 71 | return null; |
72 | + } else { | ||
73 | + masterMap.put(deviceId, nodeId); | ||
74 | + return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); | ||
59 | } | 75 | } |
60 | - roleMap.put(deviceId, role); | ||
61 | - return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); | ||
62 | } | 76 | } |
63 | 77 | ||
64 | @Override | 78 | @Override |
65 | public NodeId getMaster(DeviceId deviceId) { | 79 | public NodeId getMaster(DeviceId deviceId) { |
66 | - return instance.id(); | 80 | + return masterMap.get(deviceId); |
67 | } | 81 | } |
68 | 82 | ||
69 | @Override | 83 | @Override |
70 | public Set<DeviceId> getDevices(NodeId nodeId) { | 84 | public Set<DeviceId> getDevices(NodeId nodeId) { |
71 | - return Collections.unmodifiableSet(roleMap.keySet()); | 85 | + Set<DeviceId> ids = new HashSet<>(); |
86 | + for (Map.Entry<DeviceId, NodeId> d : masterMap.entrySet()) { | ||
87 | + if (d.getValue().equals(nodeId)) { | ||
88 | + ids.add(d.getKey()); | ||
89 | + } | ||
90 | + } | ||
91 | + return Collections.unmodifiableSet(ids); | ||
72 | } | 92 | } |
73 | 93 | ||
74 | @Override | 94 | @Override |
... | @@ -78,11 +98,18 @@ public class SimpleMastershipStore implements MastershipStore { | ... | @@ -78,11 +98,18 @@ public class SimpleMastershipStore implements MastershipStore { |
78 | 98 | ||
79 | @Override | 99 | @Override |
80 | public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { | 100 | public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { |
81 | - MastershipRole role = roleMap.get(deviceId); | 101 | + NodeId node = masterMap.get(deviceId); |
82 | - if (role == null) { | 102 | + MastershipRole role; |
83 | - //say MASTER. If clustered, we'd figure out if anyone's got dibs here. | 103 | + if (node != null) { |
104 | + if (node.equals(nodeId)) { | ||
105 | + role = MastershipRole.MASTER; | ||
106 | + } else { | ||
107 | + role = MastershipRole.STANDBY; | ||
108 | + } | ||
109 | + } else { | ||
110 | + //masterMap doesn't contain it. | ||
84 | role = MastershipRole.MASTER; | 111 | role = MastershipRole.MASTER; |
85 | - roleMap.put(deviceId, role); | 112 | + masterMap.put(deviceId, nodeId); |
86 | } | 113 | } |
87 | return role; | 114 | return role; |
88 | } | 115 | } | ... | ... |
... | @@ -18,6 +18,8 @@ import org.onlab.onos.net.topology.TopologyCluster; | ... | @@ -18,6 +18,8 @@ import org.onlab.onos.net.topology.TopologyCluster; |
18 | import org.onlab.onos.net.topology.TopologyEvent; | 18 | import org.onlab.onos.net.topology.TopologyEvent; |
19 | import org.onlab.onos.net.topology.TopologyGraph; | 19 | import org.onlab.onos.net.topology.TopologyGraph; |
20 | import org.onlab.onos.net.topology.TopologyStore; | 20 | import org.onlab.onos.net.topology.TopologyStore; |
21 | +import org.onlab.onos.net.topology.TopologyStoreDelegate; | ||
22 | +import org.onlab.onos.store.AbstractStore; | ||
21 | import org.slf4j.Logger; | 23 | import org.slf4j.Logger; |
22 | 24 | ||
23 | import java.util.List; | 25 | import java.util.List; |
... | @@ -31,7 +33,9 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -31,7 +33,9 @@ import static org.slf4j.LoggerFactory.getLogger; |
31 | */ | 33 | */ |
32 | @Component(immediate = true) | 34 | @Component(immediate = true) |
33 | @Service | 35 | @Service |
34 | -public class SimpleTopologyStore implements TopologyStore { | 36 | +public class SimpleTopologyStore |
37 | + extends AbstractStore<TopologyEvent, TopologyStoreDelegate> | ||
38 | + implements TopologyStore { | ||
35 | 39 | ||
36 | private final Logger log = getLogger(getClass()); | 40 | private final Logger log = getLogger(getClass()); |
37 | 41 | ... | ... |
... | @@ -16,6 +16,18 @@ | ... | @@ -16,6 +16,18 @@ |
16 | 16 | ||
17 | <description>ONOS OpenFlow controller subsystem API</description> | 17 | <description>ONOS OpenFlow controller subsystem API</description> |
18 | 18 | ||
19 | + <repositories> | ||
20 | + <!-- FIXME: for Loxigen. Decide how to use Loxigen before release. --> | ||
21 | + <repository> | ||
22 | + <id>sonatype-oss-snapshot</id> | ||
23 | + <name>Sonatype OSS snapshot repository</name> | ||
24 | + <url>https://oss.sonatype.org/content/repositories/snapshots</url> | ||
25 | + <releases> | ||
26 | + <enabled>false</enabled> | ||
27 | + </releases> | ||
28 | + </repository> | ||
29 | + </repositories> | ||
30 | + | ||
19 | <dependencies> | 31 | <dependencies> |
20 | <dependency> | 32 | <dependency> |
21 | <groupId>org.projectfloodlight</groupId> | 33 | <groupId>org.projectfloodlight</groupId> | ... | ... |
... | @@ -391,13 +391,13 @@ | ... | @@ -391,13 +391,13 @@ |
391 | <group> | 391 | <group> |
392 | <title>Network Model & Services</title> | 392 | <title>Network Model & Services</title> |
393 | <packages> | 393 | <packages> |
394 | - org.onlab.onos:org.onlab.onos.*: | 394 | + org.onlab.onos:org.onlab.onos.* |
395 | </packages> | 395 | </packages> |
396 | </group> | 396 | </group> |
397 | <group> | 397 | <group> |
398 | <title>Core Subsystems</title> | 398 | <title>Core Subsystems</title> |
399 | <packages> | 399 | <packages> |
400 | - org.onlab.onos.cluster.impl:org.onlab.onos.store:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.net.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.cluster:org.onlab.onos.event.impl:org.onlab.onos.store.* | 400 | + org.onlab.onos.cluster.impl:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.net.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.event.impl:org.onlab.onos.store.* |
401 | </packages> | 401 | </packages> |
402 | </group> | 402 | </group> |
403 | <group> | 403 | <group> |
... | @@ -422,7 +422,7 @@ | ... | @@ -422,7 +422,7 @@ |
422 | <group> | 422 | <group> |
423 | <title>Sample Applications</title> | 423 | <title>Sample Applications</title> |
424 | <packages> | 424 | <packages> |
425 | - org.onlab.onos.tvue:org.onlab.onos.fwd | 425 | + org.onlab.onos.tvue:org.onlab.onos.fwd:org.onlab.onos.foo |
426 | </packages> | 426 | </packages> |
427 | </group> | 427 | </group> |
428 | </groups> | 428 | </groups> | ... | ... |
... | @@ -51,7 +51,7 @@ perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-feature | ... | @@ -51,7 +51,7 @@ perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-feature |
51 | $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg | 51 | $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg |
52 | 52 | ||
53 | # Patch the Apache Karaf distribution file to load ONOS features | 53 | # Patch the Apache Karaf distribution file to load ONOS features |
54 | -perl -pi.old -e 's|^(featuresBoot=.*)|\1,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-fwd,onos-app-foo|' \ | 54 | +perl -pi.old -e 's|^(featuresBoot=.*)|\1,webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-fwd,onos-app-foo|' \ |
55 | $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg | 55 | $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg |
56 | 56 | ||
57 | # Patch the Apache Karaf distribution with ONOS branding bundle | 57 | # Patch the Apache Karaf distribution with ONOS branding bundle | ... | ... |
... | @@ -8,4 +8,7 @@ | ... | @@ -8,4 +8,7 @@ |
8 | 8 | ||
9 | remote=$ONOS_USER@${1:-$OCI} | 9 | remote=$ONOS_USER@${1:-$OCI} |
10 | 10 | ||
11 | -echo "Deprecated!" | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
11 | +ssh $remote " | ||
12 | + sudo perl -pi.bak -e \"s/ <interface>.*</ <interface>${ONOS_NIC:-192.168.56.*}</g\" \ | ||
13 | + $ONOS_INSTALL_DIR/$KARAF_DIST/etc/hazelcast.xml | ||
14 | +" | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -9,7 +9,8 @@ | ... | @@ -9,7 +9,8 @@ |
9 | # If the first option is -f attempt uninstall first. | 9 | # If the first option is -f attempt uninstall first. |
10 | [ "$1" = "-f" ] && shift && onos-uninstall ${1:-$OCI} | 10 | [ "$1" = "-f" ] && shift && onos-uninstall ${1:-$OCI} |
11 | 11 | ||
12 | -remote=$ONOS_USER@${1:-$OCI} | 12 | +node=${1:-$OCI} |
13 | +remote=$ONOS_USER@$node | ||
13 | 14 | ||
14 | scp -q $ONOS_TAR $remote:/tmp | 15 | scp -q $ONOS_TAR $remote:/tmp |
15 | 16 | ||
... | @@ -30,7 +31,10 @@ ssh $remote " | ... | @@ -30,7 +31,10 @@ ssh $remote " |
30 | 31 | ||
31 | # Remove any previous ON.Lab bits from ~/.m2 repo | 32 | # Remove any previous ON.Lab bits from ~/.m2 repo |
32 | rm -fr ~/.m2/repository/org/onlab | 33 | rm -fr ~/.m2/repository/org/onlab |
33 | - | ||
34 | - # Ignite the ONOS service. | ||
35 | - sudo service onos start | ||
36 | " | 34 | " |
35 | + | ||
36 | +# Configure the ONOS installation | ||
37 | +onos-config $node | ||
38 | + | ||
39 | +# Ignite the ONOS service. | ||
40 | +onos-service $node start | ... | ... |
tools/test/cells/.reset
0 → 100644
1 | +unset OC1 OC2 OC3 OC4 OC5 OC6 OC7 OC8 OC9 OCN ONOS_NIC |
-
Please register or login to post a comment