Committed by
Gerrit Code Review
Code clean up: Removed unused code. Fixed comments. Renamed some files.
Change-Id: I78ca1f4a973c3b5356f749680ebe0f4ccde01279
Showing
37 changed files
with
78 additions
and
2765 deletions
core/store/dist/src/main/java/org/onosproject/store/cfg/GossipComponentConfigStore.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cfg; | ||
17 | - | ||
18 | -import org.apache.felix.scr.annotations.Activate; | ||
19 | -import org.apache.felix.scr.annotations.Component; | ||
20 | -import org.apache.felix.scr.annotations.Deactivate; | ||
21 | -import org.apache.felix.scr.annotations.Reference; | ||
22 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
23 | -import org.apache.felix.scr.annotations.Service; | ||
24 | -import org.onlab.util.KryoNamespace; | ||
25 | -import org.onosproject.cfg.ComponentConfigEvent; | ||
26 | -import org.onosproject.cfg.ComponentConfigStore; | ||
27 | -import org.onosproject.cfg.ComponentConfigStoreDelegate; | ||
28 | -import org.onosproject.store.AbstractStore; | ||
29 | -import org.onosproject.store.serializers.KryoNamespaces; | ||
30 | -import org.onosproject.store.service.EventuallyConsistentMap; | ||
31 | -import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
32 | -import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
33 | -import org.onosproject.store.service.LogicalClockService; | ||
34 | -import org.onosproject.store.service.StorageService; | ||
35 | -import org.slf4j.Logger; | ||
36 | - | ||
37 | -import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_SET; | ||
38 | -import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_UNSET; | ||
39 | -import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT; | ||
40 | -import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE; | ||
41 | -import static org.slf4j.LoggerFactory.getLogger; | ||
42 | - | ||
43 | -/** | ||
44 | - * Manages inventory of component configurations in a distributed data store | ||
45 | - * that uses optimistic replication and gossip based anti-entropy techniques. | ||
46 | - */ | ||
47 | -@Component(immediate = true, enabled = false) | ||
48 | -@Service | ||
49 | -public class GossipComponentConfigStore | ||
50 | - extends AbstractStore<ComponentConfigEvent, ComponentConfigStoreDelegate> | ||
51 | - implements ComponentConfigStore { | ||
52 | - | ||
53 | - private static final String SEP = "#"; | ||
54 | - | ||
55 | - private final Logger log = getLogger(getClass()); | ||
56 | - | ||
57 | - private EventuallyConsistentMap<String, String> properties; | ||
58 | - | ||
59 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
60 | - protected StorageService storageService; | ||
61 | - | ||
62 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
63 | - protected LogicalClockService clockService; | ||
64 | - | ||
65 | - @Activate | ||
66 | - public void activate() { | ||
67 | - KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | ||
68 | - .register(KryoNamespaces.API); | ||
69 | - | ||
70 | - properties = storageService.<String, String>eventuallyConsistentMapBuilder() | ||
71 | - .withName("cfg") | ||
72 | - .withSerializer(serializer) | ||
73 | - .withTimestampProvider((k, v) -> clockService.getTimestamp()) | ||
74 | - .build(); | ||
75 | - | ||
76 | - properties.addListener(new InternalPropertiesListener()); | ||
77 | - log.info("Started"); | ||
78 | - } | ||
79 | - | ||
80 | - @Deactivate | ||
81 | - public void deactivate() { | ||
82 | - properties.destroy(); | ||
83 | - log.info("Stopped"); | ||
84 | - } | ||
85 | - | ||
86 | - @Override | ||
87 | - public void setProperty(String componentName, String name, String value) { | ||
88 | - properties.put(key(componentName, name), value); | ||
89 | - | ||
90 | - } | ||
91 | - | ||
92 | - @Override | ||
93 | - public void unsetProperty(String componentName, String name) { | ||
94 | - properties.remove(key(componentName, name)); | ||
95 | - } | ||
96 | - | ||
97 | - /** | ||
98 | - * Listener to component configuration properties distributed map changes. | ||
99 | - */ | ||
100 | - private final class InternalPropertiesListener | ||
101 | - implements EventuallyConsistentMapListener<String, String> { | ||
102 | - | ||
103 | - @Override | ||
104 | - public void event(EventuallyConsistentMapEvent<String, String> event) { | ||
105 | - String[] keys = event.key().split(SEP); | ||
106 | - String value = event.value(); | ||
107 | - if (event.type() == PUT) { | ||
108 | - delegate.notify(new ComponentConfigEvent(PROPERTY_SET, keys[0], keys[1], value)); | ||
109 | - } else if (event.type() == REMOVE) { | ||
110 | - delegate.notify(new ComponentConfigEvent(PROPERTY_UNSET, keys[0], keys[1], null)); | ||
111 | - } | ||
112 | - } | ||
113 | - } | ||
114 | - | ||
115 | - // Generates a key from component name and property name. | ||
116 | - private String key(String componentName, String name) { | ||
117 | - return componentName + SEP + name; | ||
118 | - } | ||
119 | - | ||
120 | -} |
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.impl; | ||
17 | - | ||
18 | -import org.onosproject.store.cluster.messaging.MessageSubject; | ||
19 | - | ||
20 | -//Not used right now | ||
21 | -public final class ClusterManagementMessageSubjects { | ||
22 | - // avoid instantiation | ||
23 | - private ClusterManagementMessageSubjects() {} | ||
24 | - | ||
25 | - public static final MessageSubject CLUSTER_MEMBERSHIP_EVENT = new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"); | ||
26 | -} |
core/store/dist/src/main/java/org/onosproject/store/cluster/impl/ClusterMembershipEvent.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.impl; | ||
17 | - | ||
18 | -import org.onosproject.cluster.ControllerNode; | ||
19 | - | ||
20 | -//Not used right now | ||
21 | -/** | ||
22 | - * Contains information that will be published when a cluster membership event occurs. | ||
23 | - */ | ||
24 | -public class ClusterMembershipEvent { | ||
25 | - | ||
26 | - private final ClusterMembershipEventType type; | ||
27 | - private final ControllerNode node; | ||
28 | - | ||
29 | - public ClusterMembershipEvent(ClusterMembershipEventType type, ControllerNode node) { | ||
30 | - this.type = type; | ||
31 | - this.node = node; | ||
32 | - } | ||
33 | - | ||
34 | - public ClusterMembershipEventType type() { | ||
35 | - return type; | ||
36 | - } | ||
37 | - | ||
38 | - public ControllerNode node() { | ||
39 | - return node; | ||
40 | - } | ||
41 | -} |
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.impl; | ||
17 | - | ||
18 | -//Not used right now | ||
19 | -public enum ClusterMembershipEventType { | ||
20 | - NEW_MEMBER, | ||
21 | - LEAVING_MEMBER, | ||
22 | - UNREACHABLE_MEMBER, | ||
23 | - HEART_BEAT, | ||
24 | -} |
core/store/dist/src/main/java/org/onosproject/store/cluster/impl/ClusterNodesDelegate.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.impl; | ||
17 | - | ||
18 | -import org.onosproject.cluster.DefaultControllerNode; | ||
19 | -import org.onosproject.cluster.NodeId; | ||
20 | -import org.onlab.packet.IpAddress; | ||
21 | - | ||
22 | -// Not used right now | ||
23 | -/** | ||
24 | - * Simple back interface through which connection manager can interact with | ||
25 | - * the cluster store. | ||
26 | - */ | ||
27 | -public interface ClusterNodesDelegate { | ||
28 | - | ||
29 | - /** | ||
30 | - * Notifies about cluster node coming online. | ||
31 | - * | ||
32 | - * @param nodeId newly detected cluster node id | ||
33 | - * @param ip node IP listen address | ||
34 | - * @param tcpPort node TCP listen port | ||
35 | - * @return the controller node | ||
36 | - */ | ||
37 | - DefaultControllerNode nodeDetected(NodeId nodeId, IpAddress ip, | ||
38 | - int tcpPort); | ||
39 | - | ||
40 | - /** | ||
41 | - * Notifies about cluster node going offline. | ||
42 | - * | ||
43 | - * @param nodeId identifier of the cluster node that vanished | ||
44 | - */ | ||
45 | - void nodeVanished(NodeId nodeId); | ||
46 | - | ||
47 | - /** | ||
48 | - * Notifies about remote request to remove node from cluster. | ||
49 | - * | ||
50 | - * @param nodeId identifier of the cluster node that was removed | ||
51 | - */ | ||
52 | - void nodeRemoved(NodeId nodeId); | ||
53 | - | ||
54 | -} |
... | @@ -17,10 +17,9 @@ package org.onosproject.store.cluster.impl; | ... | @@ -17,10 +17,9 @@ package org.onosproject.store.cluster.impl; |
17 | 17 | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | -import java.util.ArrayList; | ||
21 | -import java.util.List; | ||
22 | import java.util.Map; | 20 | import java.util.Map; |
23 | -import java.util.stream.Collectors; | 21 | +import java.util.Objects; |
22 | +import java.util.function.Consumer; | ||
24 | 23 | ||
25 | import org.apache.felix.scr.annotations.Activate; | 24 | import org.apache.felix.scr.annotations.Activate; |
26 | import org.apache.felix.scr.annotations.Component; | 25 | import org.apache.felix.scr.annotations.Component; |
... | @@ -29,39 +28,28 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -29,39 +28,28 @@ import org.apache.felix.scr.annotations.Reference; |
29 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 28 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
30 | import org.apache.felix.scr.annotations.Service; | 29 | import org.apache.felix.scr.annotations.Service; |
31 | import org.onosproject.cluster.ClusterService; | 30 | import org.onosproject.cluster.ClusterService; |
32 | -import org.onosproject.cluster.Leader; | ||
33 | import org.onosproject.cluster.Leadership; | 31 | import org.onosproject.cluster.Leadership; |
34 | import org.onosproject.cluster.LeadershipEvent; | 32 | import org.onosproject.cluster.LeadershipEvent; |
35 | import org.onosproject.cluster.LeadershipStore; | 33 | import org.onosproject.cluster.LeadershipStore; |
36 | import org.onosproject.cluster.LeadershipStoreDelegate; | 34 | import org.onosproject.cluster.LeadershipStoreDelegate; |
37 | import org.onosproject.cluster.NodeId; | 35 | import org.onosproject.cluster.NodeId; |
36 | +import org.onosproject.event.Change; | ||
38 | import org.onosproject.store.AbstractStore; | 37 | import org.onosproject.store.AbstractStore; |
39 | -import org.onosproject.store.serializers.KryoNamespaces; | 38 | +import org.onosproject.store.service.LeaderElector; |
40 | -import org.onosproject.store.service.ConsistentMap; | ||
41 | -import org.onosproject.store.service.MapEventListener; | ||
42 | -import org.onosproject.store.service.Serializer; | ||
43 | import org.onosproject.store.service.StorageService; | 39 | import org.onosproject.store.service.StorageService; |
44 | -import org.onosproject.store.service.Versioned; | ||
45 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
46 | 41 | ||
47 | -import com.google.common.base.MoreObjects; | ||
48 | -import com.google.common.base.Objects; | ||
49 | -import com.google.common.collect.ImmutableList; | ||
50 | -import com.google.common.collect.ImmutableMap; | ||
51 | -import com.google.common.collect.ImmutableSet; | ||
52 | -import com.google.common.collect.Maps; | ||
53 | -import com.google.common.collect.Sets; | ||
54 | - | ||
55 | /** | 42 | /** |
56 | - * Implementation of {@code LeadershipStore} backed by {@link ConsistentMap}. | 43 | + * Implementation of {@code LeadershipStore} that makes use of a {@link LeaderElector} |
44 | + * primitive. | ||
57 | */ | 45 | */ |
58 | @Service | 46 | @Service |
59 | -@Component(immediate = true, enabled = false) | 47 | +@Component(immediate = true, enabled = true) |
60 | public class DistributedLeadershipStore | 48 | public class DistributedLeadershipStore |
61 | extends AbstractStore<LeadershipEvent, LeadershipStoreDelegate> | 49 | extends AbstractStore<LeadershipEvent, LeadershipStoreDelegate> |
62 | implements LeadershipStore { | 50 | implements LeadershipStore { |
63 | 51 | ||
64 | - private static final Logger log = getLogger(DistributedLeadershipStore.class); | 52 | + private final Logger log = getLogger(getClass()); |
65 | 53 | ||
66 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 54 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
67 | protected ClusterService clusterService; | 55 | protected ClusterService clusterService; |
... | @@ -69,20 +57,15 @@ public class DistributedLeadershipStore | ... | @@ -69,20 +57,15 @@ public class DistributedLeadershipStore |
69 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 57 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
70 | protected StorageService storageService; | 58 | protected StorageService storageService; |
71 | 59 | ||
72 | - protected NodeId localNodeId; | 60 | + private NodeId localNodeId; |
73 | - protected ConsistentMap<String, InternalLeadership> leadershipMap; | 61 | + private LeaderElector leaderElector; |
74 | - protected Map<String, Versioned<InternalLeadership>> leadershipCache = Maps.newConcurrentMap(); | ||
75 | 62 | ||
76 | - private final MapEventListener<String, InternalLeadership> leadershipChangeListener = | 63 | + private final Consumer<Change<Leadership>> leadershipChangeListener = |
77 | - event -> { | 64 | + change -> { |
78 | - Leadership oldValue = InternalLeadership.toLeadership(Versioned.valueOrNull(event.oldValue())); | 65 | + Leadership oldValue = change.oldValue(); |
79 | - Leadership newValue = InternalLeadership.toLeadership(Versioned.valueOrNull(event.newValue())); | 66 | + Leadership newValue = change.newValue(); |
80 | - boolean leaderChanged = | 67 | + boolean leaderChanged = !Objects.equals(oldValue.leader(), newValue.leader()); |
81 | - !Objects.equal(oldValue == null ? null : oldValue.leader(), newValue.leader()); | 68 | + boolean candidatesChanged = !Objects.equals(oldValue.candidates(), newValue.candidates()); |
82 | - boolean candidatesChanged = | ||
83 | - !Sets.symmetricDifference(Sets.newHashSet(oldValue == null ? | ||
84 | - ImmutableSet.<NodeId>of() : oldValue.candidates()), | ||
85 | - Sets.newHashSet(newValue.candidates())).isEmpty(); | ||
86 | LeadershipEvent.Type eventType = null; | 69 | LeadershipEvent.Type eventType = null; |
87 | if (leaderChanged && candidatesChanged) { | 70 | if (leaderChanged && candidatesChanged) { |
88 | eventType = LeadershipEvent.Type.LEADER_AND_CANDIDATES_CHANGED; | 71 | eventType = LeadershipEvent.Type.LEADER_AND_CANDIDATES_CHANGED; |
... | @@ -93,193 +76,58 @@ public class DistributedLeadershipStore | ... | @@ -93,193 +76,58 @@ public class DistributedLeadershipStore |
93 | if (!leaderChanged && candidatesChanged) { | 76 | if (!leaderChanged && candidatesChanged) { |
94 | eventType = LeadershipEvent.Type.CANDIDATES_CHANGED; | 77 | eventType = LeadershipEvent.Type.CANDIDATES_CHANGED; |
95 | } | 78 | } |
96 | - leadershipCache.compute(event.key(), (k, v) -> { | 79 | + notifyDelegate(new LeadershipEvent(eventType, change.newValue())); |
97 | - if (v == null || v.version() < event.newValue().version()) { | ||
98 | - return event.newValue(); | ||
99 | - } | ||
100 | - return v; | ||
101 | - }); | ||
102 | - notifyDelegate(new LeadershipEvent(eventType, newValue)); | ||
103 | }; | 80 | }; |
104 | 81 | ||
105 | @Activate | 82 | @Activate |
106 | public void activate() { | 83 | public void activate() { |
107 | localNodeId = clusterService.getLocalNode().id(); | 84 | localNodeId = clusterService.getLocalNode().id(); |
108 | - leadershipMap = storageService.<String, InternalLeadership>consistentMapBuilder() | 85 | + leaderElector = storageService.leaderElectorBuilder() |
109 | - .withName("onos-leadership") | 86 | + .withName("onos-leadership-elections") |
110 | - .withPartitionsDisabled() | 87 | + .build() |
111 | - .withRelaxedReadConsistency() | 88 | + .asLeaderElector(); |
112 | - .withSerializer(Serializer.using(KryoNamespaces.API, InternalLeadership.class)) | 89 | + leaderElector.addChangeListener(leadershipChangeListener); |
113 | - .build(); | ||
114 | - leadershipMap.entrySet().forEach(e -> leadershipCache.put(e.getKey(), e.getValue())); | ||
115 | - leadershipMap.addListener(leadershipChangeListener); | ||
116 | log.info("Started"); | 90 | log.info("Started"); |
117 | } | 91 | } |
118 | 92 | ||
119 | @Deactivate | 93 | @Deactivate |
120 | public void deactivate() { | 94 | public void deactivate() { |
121 | - leadershipMap.removeListener(leadershipChangeListener); | 95 | + leaderElector.removeChangeListener(leadershipChangeListener); |
122 | log.info("Stopped"); | 96 | log.info("Stopped"); |
123 | } | 97 | } |
124 | 98 | ||
125 | @Override | 99 | @Override |
126 | public Leadership addRegistration(String topic) { | 100 | public Leadership addRegistration(String topic) { |
127 | - Versioned<InternalLeadership> internalLeadership = leadershipMap.computeIf(topic, | 101 | + return leaderElector.run(topic, localNodeId); |
128 | - v -> v == null || !v.candidates().contains(localNodeId), | ||
129 | - (k, v) -> { | ||
130 | - if (v == null || v.candidates().isEmpty()) { | ||
131 | - return new InternalLeadership(topic, | ||
132 | - localNodeId, | ||
133 | - v == null ? 1 : v.term() + 1, | ||
134 | - System.currentTimeMillis(), | ||
135 | - ImmutableList.of(localNodeId)); | ||
136 | - } | ||
137 | - List<NodeId> newCandidates = new ArrayList<>(v.candidates()); | ||
138 | - newCandidates.add(localNodeId); | ||
139 | - return new InternalLeadership(topic, v.leader(), v.term(), v.termStartTime(), newCandidates); | ||
140 | - }); | ||
141 | - return InternalLeadership.toLeadership(Versioned.valueOrNull(internalLeadership)); | ||
142 | } | 102 | } |
143 | 103 | ||
144 | @Override | 104 | @Override |
145 | public void removeRegistration(String topic) { | 105 | public void removeRegistration(String topic) { |
146 | - removeRegistration(topic, localNodeId); | 106 | + leaderElector.withdraw(topic); |
147 | - } | ||
148 | - | ||
149 | - private void removeRegistration(String topic, NodeId nodeId) { | ||
150 | - leadershipMap.computeIf(topic, | ||
151 | - v -> v != null && v.candidates().contains(nodeId), | ||
152 | - (k, v) -> { | ||
153 | - List<NodeId> newCandidates = v.candidates() | ||
154 | - .stream() | ||
155 | - .filter(id -> !nodeId.equals(id)) | ||
156 | - .collect(Collectors.toList()); | ||
157 | - NodeId newLeader = nodeId.equals(v.leader()) ? | ||
158 | - newCandidates.size() > 0 ? newCandidates.get(0) : null : v.leader(); | ||
159 | - long newTerm = newLeader == null || Objects.equal(newLeader, v.leader()) ? | ||
160 | - v.term() : v.term() + 1; | ||
161 | - long newTermStartTime = newLeader == null || Objects.equal(newLeader, v.leader()) ? | ||
162 | - v.termStartTime() : System.currentTimeMillis(); | ||
163 | - return new InternalLeadership(topic, newLeader, newTerm, newTermStartTime, newCandidates); | ||
164 | - }); | ||
165 | } | 107 | } |
166 | 108 | ||
167 | @Override | 109 | @Override |
168 | public void removeRegistration(NodeId nodeId) { | 110 | public void removeRegistration(NodeId nodeId) { |
169 | - leadershipMap.entrySet() | 111 | + leaderElector.evict(nodeId); |
170 | - .stream() | ||
171 | - .filter(e -> e.getValue().value().candidates().contains(nodeId)) | ||
172 | - .map(e -> e.getKey()) | ||
173 | - .forEach(topic -> this.removeRegistration(topic, nodeId)); | ||
174 | } | 112 | } |
175 | 113 | ||
176 | @Override | 114 | @Override |
177 | public boolean moveLeadership(String topic, NodeId toNodeId) { | 115 | public boolean moveLeadership(String topic, NodeId toNodeId) { |
178 | - Versioned<InternalLeadership> internalLeadership = leadershipMap.computeIf(topic, | 116 | + return leaderElector.anoint(topic, toNodeId); |
179 | - v -> v != null && | ||
180 | - v.candidates().contains(toNodeId) && | ||
181 | - !Objects.equal(v.leader(), toNodeId), | ||
182 | - (k, v) -> { | ||
183 | - List<NodeId> newCandidates = new ArrayList<>(); | ||
184 | - newCandidates.add(toNodeId); | ||
185 | - newCandidates.addAll(v.candidates() | ||
186 | - .stream() | ||
187 | - .filter(id -> !toNodeId.equals(id)) | ||
188 | - .collect(Collectors.toList())); | ||
189 | - return new InternalLeadership(topic, | ||
190 | - toNodeId, | ||
191 | - v.term() + 1, | ||
192 | - System.currentTimeMillis(), | ||
193 | - newCandidates); | ||
194 | - }); | ||
195 | - return Objects.equal(toNodeId, Versioned.valueOrNull(internalLeadership).leader()); | ||
196 | } | 117 | } |
197 | 118 | ||
198 | @Override | 119 | @Override |
199 | public boolean makeTopCandidate(String topic, NodeId nodeId) { | 120 | public boolean makeTopCandidate(String topic, NodeId nodeId) { |
200 | - Versioned<InternalLeadership> internalLeadership = leadershipMap.computeIf(topic, | 121 | + return leaderElector.promote(topic, nodeId); |
201 | - v -> v != null && | ||
202 | - v.candidates().contains(nodeId) && | ||
203 | - !v.candidates().get(0).equals(nodeId), | ||
204 | - (k, v) -> { | ||
205 | - List<NodeId> newCandidates = new ArrayList<>(); | ||
206 | - newCandidates.add(nodeId); | ||
207 | - newCandidates.addAll(v.candidates() | ||
208 | - .stream() | ||
209 | - .filter(id -> !nodeId.equals(id)) | ||
210 | - .collect(Collectors.toList())); | ||
211 | - return new InternalLeadership(topic, | ||
212 | - v.leader(), | ||
213 | - v.term(), | ||
214 | - System.currentTimeMillis(), | ||
215 | - newCandidates); | ||
216 | - }); | ||
217 | - return internalLeadership != null && nodeId.equals(internalLeadership.value().candidates().get(0)); | ||
218 | } | 122 | } |
219 | 123 | ||
220 | @Override | 124 | @Override |
221 | public Leadership getLeadership(String topic) { | 125 | public Leadership getLeadership(String topic) { |
222 | - InternalLeadership internalLeadership = Versioned.valueOrNull(leadershipMap.get(topic)); | 126 | + return leaderElector.getLeadership(topic); |
223 | - return internalLeadership == null ? null : internalLeadership.asLeadership(); | ||
224 | } | 127 | } |
225 | 128 | ||
226 | @Override | 129 | @Override |
227 | public Map<String, Leadership> getLeaderships() { | 130 | public Map<String, Leadership> getLeaderships() { |
228 | - return ImmutableMap.copyOf(Maps.transformValues(leadershipCache, v -> v.value().asLeadership())); | 131 | + return leaderElector.getLeaderships(); |
229 | - } | ||
230 | - | ||
231 | - private static class InternalLeadership { | ||
232 | - private final String topic; | ||
233 | - private final NodeId leader; | ||
234 | - private final long term; | ||
235 | - private final long termStartTime; | ||
236 | - private final List<NodeId> candidates; | ||
237 | - | ||
238 | - public InternalLeadership(String topic, | ||
239 | - NodeId leader, | ||
240 | - long term, | ||
241 | - long termStartTime, | ||
242 | - List<NodeId> candidates) { | ||
243 | - this.topic = topic; | ||
244 | - this.leader = leader; | ||
245 | - this.term = term; | ||
246 | - this.termStartTime = termStartTime; | ||
247 | - this.candidates = ImmutableList.copyOf(candidates); | ||
248 | - } | ||
249 | - | ||
250 | - public NodeId leader() { | ||
251 | - return this.leader; | ||
252 | - } | ||
253 | - | ||
254 | - public long term() { | ||
255 | - return term; | ||
256 | - } | ||
257 | - | ||
258 | - public long termStartTime() { | ||
259 | - return termStartTime; | ||
260 | - } | ||
261 | - | ||
262 | - public List<NodeId> candidates() { | ||
263 | - return candidates; | ||
264 | - } | ||
265 | - | ||
266 | - public Leadership asLeadership() { | ||
267 | - return new Leadership(topic, leader == null ? | ||
268 | - null : new Leader(leader, term, termStartTime), candidates); | ||
269 | - } | ||
270 | - | ||
271 | - public static Leadership toLeadership(InternalLeadership internalLeadership) { | ||
272 | - return internalLeadership == null ? null : internalLeadership.asLeadership(); | ||
273 | - } | ||
274 | - | ||
275 | - @Override | ||
276 | - public String toString() { | ||
277 | - return MoreObjects.toStringHelper(getClass()) | ||
278 | - .add("leader", leader) | ||
279 | - .add("term", term) | ||
280 | - .add("termStartTime", termStartTime) | ||
281 | - .add("candidates", candidates) | ||
282 | - .toString(); | ||
283 | - } | ||
284 | } | 132 | } |
285 | } | 133 | } | ... | ... |
1 | -/* | ||
2 | - * Copyright 2016-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.impl; | ||
17 | - | ||
18 | -import static org.slf4j.LoggerFactory.getLogger; | ||
19 | - | ||
20 | -import java.util.Map; | ||
21 | -import java.util.Objects; | ||
22 | -import java.util.function.Consumer; | ||
23 | - | ||
24 | -import org.apache.felix.scr.annotations.Activate; | ||
25 | -import org.apache.felix.scr.annotations.Component; | ||
26 | -import org.apache.felix.scr.annotations.Deactivate; | ||
27 | -import org.apache.felix.scr.annotations.Reference; | ||
28 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
29 | -import org.apache.felix.scr.annotations.Service; | ||
30 | -import org.onosproject.cluster.ClusterService; | ||
31 | -import org.onosproject.cluster.Leadership; | ||
32 | -import org.onosproject.cluster.LeadershipEvent; | ||
33 | -import org.onosproject.cluster.LeadershipStore; | ||
34 | -import org.onosproject.cluster.LeadershipStoreDelegate; | ||
35 | -import org.onosproject.cluster.NodeId; | ||
36 | -import org.onosproject.event.Change; | ||
37 | -import org.onosproject.store.AbstractStore; | ||
38 | -import org.onosproject.store.service.LeaderElector; | ||
39 | -import org.onosproject.store.service.StorageService; | ||
40 | -import org.slf4j.Logger; | ||
41 | - | ||
42 | -/** | ||
43 | - * Implementation of {@code LeadershipStore} that makes use of a {@link LeaderElector} | ||
44 | - * primitive. | ||
45 | - */ | ||
46 | -@Service | ||
47 | -@Component(immediate = true, enabled = true) | ||
48 | -public class NewDistributedLeadershipStore | ||
49 | - extends AbstractStore<LeadershipEvent, LeadershipStoreDelegate> | ||
50 | - implements LeadershipStore { | ||
51 | - | ||
52 | - private final Logger log = getLogger(getClass()); | ||
53 | - | ||
54 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
55 | - protected ClusterService clusterService; | ||
56 | - | ||
57 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
58 | - protected StorageService storageService; | ||
59 | - | ||
60 | - private NodeId localNodeId; | ||
61 | - private LeaderElector leaderElector; | ||
62 | - | ||
63 | - private final Consumer<Change<Leadership>> leadershipChangeListener = | ||
64 | - change -> { | ||
65 | - Leadership oldValue = change.oldValue(); | ||
66 | - Leadership newValue = change.newValue(); | ||
67 | - boolean leaderChanged = !Objects.equals(oldValue.leader(), newValue.leader()); | ||
68 | - boolean candidatesChanged = !Objects.equals(oldValue.candidates(), newValue.candidates()); | ||
69 | - LeadershipEvent.Type eventType = null; | ||
70 | - if (leaderChanged && candidatesChanged) { | ||
71 | - eventType = LeadershipEvent.Type.LEADER_AND_CANDIDATES_CHANGED; | ||
72 | - } | ||
73 | - if (leaderChanged && !candidatesChanged) { | ||
74 | - eventType = LeadershipEvent.Type.LEADER_CHANGED; | ||
75 | - } | ||
76 | - if (!leaderChanged && candidatesChanged) { | ||
77 | - eventType = LeadershipEvent.Type.CANDIDATES_CHANGED; | ||
78 | - } | ||
79 | - notifyDelegate(new LeadershipEvent(eventType, change.newValue())); | ||
80 | - }; | ||
81 | - | ||
82 | - @Activate | ||
83 | - public void activate() { | ||
84 | - localNodeId = clusterService.getLocalNode().id(); | ||
85 | - leaderElector = storageService.leaderElectorBuilder() | ||
86 | - .withName("onos-leadership-elections") | ||
87 | - .build() | ||
88 | - .asLeaderElector(); | ||
89 | - leaderElector.addChangeListener(leadershipChangeListener); | ||
90 | - log.info("Started"); | ||
91 | - } | ||
92 | - | ||
93 | - @Deactivate | ||
94 | - public void deactivate() { | ||
95 | - leaderElector.removeChangeListener(leadershipChangeListener); | ||
96 | - log.info("Stopped"); | ||
97 | - } | ||
98 | - | ||
99 | - @Override | ||
100 | - public Leadership addRegistration(String topic) { | ||
101 | - return leaderElector.run(topic, localNodeId); | ||
102 | - } | ||
103 | - | ||
104 | - @Override | ||
105 | - public void removeRegistration(String topic) { | ||
106 | - leaderElector.withdraw(topic); | ||
107 | - } | ||
108 | - | ||
109 | - @Override | ||
110 | - public void removeRegistration(NodeId nodeId) { | ||
111 | - leaderElector.evict(nodeId); | ||
112 | - } | ||
113 | - | ||
114 | - @Override | ||
115 | - public boolean moveLeadership(String topic, NodeId toNodeId) { | ||
116 | - return leaderElector.anoint(topic, toNodeId); | ||
117 | - } | ||
118 | - | ||
119 | - @Override | ||
120 | - public boolean makeTopCandidate(String topic, NodeId nodeId) { | ||
121 | - return leaderElector.promote(topic, nodeId); | ||
122 | - } | ||
123 | - | ||
124 | - @Override | ||
125 | - public Leadership getLeadership(String topic) { | ||
126 | - return leaderElector.getLeadership(topic); | ||
127 | - } | ||
128 | - | ||
129 | - @Override | ||
130 | - public Map<String, Leadership> getLeaderships() { | ||
131 | - return leaderElector.getLeaderships(); | ||
132 | - } | ||
133 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.impl; | ||
17 | - | ||
18 | -import static com.google.common.base.MoreObjects.toStringHelper; | ||
19 | - | ||
20 | -import java.util.Objects; | ||
21 | - | ||
22 | -import org.onosproject.cluster.ControllerNode; | ||
23 | - | ||
24 | -/** | ||
25 | - * Node info read from configuration files during bootstrap. | ||
26 | - */ | ||
27 | -public final class NodeInfo { | ||
28 | - private final String id; | ||
29 | - private final String ip; | ||
30 | - private final int tcpPort; | ||
31 | - | ||
32 | - private NodeInfo(String id, String ip, int port) { | ||
33 | - this.id = id; | ||
34 | - this.ip = ip; | ||
35 | - this.tcpPort = port; | ||
36 | - } | ||
37 | - | ||
38 | - /* | ||
39 | - * Needed for serialization. | ||
40 | - */ | ||
41 | - private NodeInfo() { | ||
42 | - id = null; | ||
43 | - ip = null; | ||
44 | - tcpPort = 0; | ||
45 | - } | ||
46 | - | ||
47 | - /** | ||
48 | - * Creates a new instance. | ||
49 | - * @param id node id | ||
50 | - * @param ip node ip address | ||
51 | - * @param port tcp port | ||
52 | - * @return NodeInfo | ||
53 | - */ | ||
54 | - public static NodeInfo from(String id, String ip, int port) { | ||
55 | - NodeInfo node = new NodeInfo(id, ip, port); | ||
56 | - return node; | ||
57 | - } | ||
58 | - | ||
59 | - /** | ||
60 | - * Returns the NodeInfo for a controller node. | ||
61 | - * @param node controller node | ||
62 | - * @return NodeInfo | ||
63 | - */ | ||
64 | - public static NodeInfo of(ControllerNode node) { | ||
65 | - return NodeInfo.from(node.id().toString(), node.ip().toString(), node.tcpPort()); | ||
66 | - } | ||
67 | - | ||
68 | - /** | ||
69 | - * Returns node id. | ||
70 | - * @return node id | ||
71 | - */ | ||
72 | - public String getId() { | ||
73 | - return id; | ||
74 | - } | ||
75 | - | ||
76 | - /** | ||
77 | - * Returns node ip. | ||
78 | - * @return node ip | ||
79 | - */ | ||
80 | - public String getIp() { | ||
81 | - return ip; | ||
82 | - } | ||
83 | - | ||
84 | - /** | ||
85 | - * Returns node port. | ||
86 | - * @return port | ||
87 | - */ | ||
88 | - public int getTcpPort() { | ||
89 | - return tcpPort; | ||
90 | - } | ||
91 | - | ||
92 | - @Override | ||
93 | - public int hashCode() { | ||
94 | - return Objects.hash(id, ip, tcpPort); | ||
95 | - } | ||
96 | - | ||
97 | - @Override | ||
98 | - public boolean equals(Object o) { | ||
99 | - if (this == o) { | ||
100 | - return true; | ||
101 | - } | ||
102 | - if (o instanceof NodeInfo) { | ||
103 | - NodeInfo that = (NodeInfo) o; | ||
104 | - return Objects.equals(this.id, that.id) && | ||
105 | - Objects.equals(this.ip, that.ip) && | ||
106 | - Objects.equals(this.tcpPort, that.tcpPort); | ||
107 | - } | ||
108 | - return false; | ||
109 | - } | ||
110 | - | ||
111 | - @Override | ||
112 | - public String toString() { | ||
113 | - return toStringHelper(this) | ||
114 | - .add("id", id) | ||
115 | - .add("ip", ip) | ||
116 | - .add("tcpPort", tcpPort).toString(); | ||
117 | - } | ||
118 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Implementation of a distributed cluster node store using Hazelcast. | 18 | + * Implementation of a distributed cluster membership store and failure detector. |
19 | */ | 19 | */ |
20 | package org.onosproject.store.cluster.impl; | 20 | package org.onosproject.store.cluster.impl; | ... | ... |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Implementation of the network configuration distributed store. | 18 | + * Implementation of the distributed network configuration store. |
19 | */ | 19 | */ |
20 | package org.onosproject.store.config.impl; | 20 | package org.onosproject.store.config.impl; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -17,28 +17,31 @@ package org.onosproject.store.core.impl; | ... | @@ -17,28 +17,31 @@ package org.onosproject.store.core.impl; |
17 | 17 | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | + | ||
20 | import java.util.Map; | 21 | import java.util.Map; |
21 | import java.util.Set; | 22 | import java.util.Set; |
23 | + | ||
24 | + | ||
22 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
23 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
24 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
25 | import org.apache.felix.scr.annotations.Reference; | 28 | import org.apache.felix.scr.annotations.Reference; |
26 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 29 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
27 | import org.apache.felix.scr.annotations.Service; | 30 | import org.apache.felix.scr.annotations.Service; |
28 | -import org.onlab.util.KryoNamespace; | ||
29 | -import org.onlab.util.Tools; | ||
30 | import org.onosproject.core.ApplicationId; | 31 | import org.onosproject.core.ApplicationId; |
31 | import org.onosproject.core.ApplicationIdStore; | 32 | import org.onosproject.core.ApplicationIdStore; |
32 | import org.onosproject.core.DefaultApplicationId; | 33 | import org.onosproject.core.DefaultApplicationId; |
33 | import org.onosproject.store.serializers.KryoNamespaces; | 34 | import org.onosproject.store.serializers.KryoNamespaces; |
34 | import org.onosproject.store.service.AtomicCounter; | 35 | import org.onosproject.store.service.AtomicCounter; |
35 | import org.onosproject.store.service.ConsistentMap; | 36 | import org.onosproject.store.service.ConsistentMap; |
37 | +import org.onosproject.store.service.MapEvent; | ||
38 | +import org.onosproject.store.service.MapEventListener; | ||
36 | import org.onosproject.store.service.Serializer; | 39 | import org.onosproject.store.service.Serializer; |
37 | -import org.onosproject.store.service.StorageException; | ||
38 | import org.onosproject.store.service.StorageService; | 40 | import org.onosproject.store.service.StorageService; |
39 | import org.onosproject.store.service.Versioned; | 41 | import org.onosproject.store.service.Versioned; |
40 | import org.slf4j.Logger; | 42 | import org.slf4j.Logger; |
41 | 43 | ||
44 | + | ||
42 | import com.google.common.collect.ImmutableSet; | 45 | import com.google.common.collect.ImmutableSet; |
43 | import com.google.common.collect.Maps; | 46 | import com.google.common.collect.Maps; |
44 | 47 | ||
... | @@ -48,7 +51,7 @@ import com.google.common.collect.Maps; | ... | @@ -48,7 +51,7 @@ import com.google.common.collect.Maps; |
48 | */ | 51 | */ |
49 | @Component(immediate = true, enabled = true) | 52 | @Component(immediate = true, enabled = true) |
50 | @Service | 53 | @Service |
51 | -public class ConsistentApplicationIdStore implements ApplicationIdStore { | 54 | +public class DistributedApplicationIdStore implements ApplicationIdStore { |
52 | 55 | ||
53 | private final Logger log = getLogger(getClass()); | 56 | private final Logger log = getLogger(getClass()); |
54 | 57 | ||
... | @@ -57,13 +60,12 @@ public class ConsistentApplicationIdStore implements ApplicationIdStore { | ... | @@ -57,13 +60,12 @@ public class ConsistentApplicationIdStore implements ApplicationIdStore { |
57 | 60 | ||
58 | private AtomicCounter appIdCounter; | 61 | private AtomicCounter appIdCounter; |
59 | private ConsistentMap<String, ApplicationId> registeredIds; | 62 | private ConsistentMap<String, ApplicationId> registeredIds; |
60 | - private Map<String, ApplicationId> nameToAppIdCache = Maps.newConcurrentMap(); | ||
61 | private Map<Short, ApplicationId> idToAppIdCache = Maps.newConcurrentMap(); | 63 | private Map<Short, ApplicationId> idToAppIdCache = Maps.newConcurrentMap(); |
62 | - | 64 | + private MapEventListener<String, ApplicationId> mapEventListener = event -> { |
63 | - private static final Serializer SERIALIZER = Serializer.using(new KryoNamespace.Builder() | 65 | + if (event.type() == MapEvent.Type.INSERT) { |
64 | - .register(KryoNamespaces.API) | 66 | + idToAppIdCache.put(event.newValue().value().id(), event.newValue().value()); |
65 | - .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) | 67 | + } |
66 | - .build()); | 68 | + }; |
67 | 69 | ||
68 | @Activate | 70 | @Activate |
69 | public void activate() { | 71 | public void activate() { |
... | @@ -71,75 +73,50 @@ public class ConsistentApplicationIdStore implements ApplicationIdStore { | ... | @@ -71,75 +73,50 @@ public class ConsistentApplicationIdStore implements ApplicationIdStore { |
71 | 73 | ||
72 | registeredIds = storageService.<String, ApplicationId>consistentMapBuilder() | 74 | registeredIds = storageService.<String, ApplicationId>consistentMapBuilder() |
73 | .withName("onos-app-ids") | 75 | .withName("onos-app-ids") |
74 | - .withSerializer(SERIALIZER) | 76 | + .withSerializer(Serializer.using(KryoNamespaces.API)) |
77 | + .withRelaxedReadConsistency() | ||
75 | .build(); | 78 | .build(); |
76 | 79 | ||
77 | - primeAppIds(); | 80 | + primeIdToAppIdCache(); |
81 | + registeredIds.addListener(mapEventListener); | ||
78 | 82 | ||
79 | log.info("Started"); | 83 | log.info("Started"); |
80 | } | 84 | } |
81 | 85 | ||
82 | @Deactivate | 86 | @Deactivate |
83 | public void deactivate() { | 87 | public void deactivate() { |
88 | + registeredIds.removeListener(mapEventListener); | ||
84 | log.info("Stopped"); | 89 | log.info("Stopped"); |
85 | } | 90 | } |
86 | 91 | ||
87 | @Override | 92 | @Override |
88 | public Set<ApplicationId> getAppIds() { | 93 | public Set<ApplicationId> getAppIds() { |
89 | - // TODO: Rework this when we have notification support in ConsistentMap. | 94 | + return ImmutableSet.copyOf(registeredIds.asJavaMap().values()); |
90 | - primeAppIds(); | ||
91 | - return ImmutableSet.copyOf(nameToAppIdCache.values()); | ||
92 | } | 95 | } |
93 | 96 | ||
94 | @Override | 97 | @Override |
95 | public ApplicationId getAppId(Short id) { | 98 | public ApplicationId getAppId(Short id) { |
96 | if (!idToAppIdCache.containsKey(id)) { | 99 | if (!idToAppIdCache.containsKey(id)) { |
97 | - primeAppIds(); | 100 | + primeIdToAppIdCache(); |
98 | } | 101 | } |
99 | return idToAppIdCache.get(id); | 102 | return idToAppIdCache.get(id); |
100 | } | 103 | } |
101 | 104 | ||
102 | @Override | 105 | @Override |
103 | public ApplicationId getAppId(String name) { | 106 | public ApplicationId getAppId(String name) { |
104 | - ApplicationId appId = nameToAppIdCache.computeIfAbsent(name, key -> { | 107 | + return registeredIds.asJavaMap().get(name); |
105 | - Versioned<ApplicationId> existingAppId = registeredIds.get(key); | ||
106 | - return existingAppId != null ? existingAppId.value() : null; | ||
107 | - }); | ||
108 | - if (appId != null) { | ||
109 | - idToAppIdCache.putIfAbsent(appId.id(), appId); | ||
110 | - } | ||
111 | - return appId; | ||
112 | } | 108 | } |
113 | 109 | ||
114 | @Override | 110 | @Override |
115 | public ApplicationId registerApplication(String name) { | 111 | public ApplicationId registerApplication(String name) { |
116 | - ApplicationId appId = nameToAppIdCache.computeIfAbsent(name, key -> { | 112 | + return Versioned.valueOrNull(registeredIds.computeIfAbsent(name, |
117 | - Versioned<ApplicationId> existingAppId = registeredIds.get(name); | 113 | + key -> new DefaultApplicationId((int) appIdCounter.incrementAndGet(), name))); |
118 | - if (existingAppId == null) { | ||
119 | - int id = Tools.retryable(appIdCounter::incrementAndGet, StorageException.class, 1, 2000) | ||
120 | - .get() | ||
121 | - .intValue(); | ||
122 | - DefaultApplicationId newAppId = new DefaultApplicationId(id, name); | ||
123 | - existingAppId = registeredIds.putIfAbsent(name, newAppId); | ||
124 | - if (existingAppId != null) { | ||
125 | - return existingAppId.value(); | ||
126 | - } else { | ||
127 | - return newAppId; | ||
128 | - } | ||
129 | - } else { | ||
130 | - return existingAppId.value(); | ||
131 | - } | ||
132 | - }); | ||
133 | - idToAppIdCache.putIfAbsent(appId.id(), appId); | ||
134 | - return appId; | ||
135 | } | 114 | } |
136 | 115 | ||
137 | - private void primeAppIds() { | 116 | + private void primeIdToAppIdCache() { |
138 | - registeredIds.values() | 117 | + registeredIds.asJavaMap() |
139 | - .stream() | 118 | + .values() |
140 | - .map(Versioned::value) | ||
141 | .forEach(appId -> { | 119 | .forEach(appId -> { |
142 | - nameToAppIdCache.putIfAbsent(appId.name(), appId); | ||
143 | idToAppIdCache.putIfAbsent(appId.id(), appId); | 120 | idToAppIdCache.putIfAbsent(appId.id(), appId); |
144 | }); | 121 | }); |
145 | } | 122 | } | ... | ... |
... | @@ -38,7 +38,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -38,7 +38,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
38 | */ | 38 | */ |
39 | @Component(immediate = true, enabled = true) | 39 | @Component(immediate = true, enabled = true) |
40 | @Service | 40 | @Service |
41 | -public class ConsistentIdBlockStore implements IdBlockStore { | 41 | +public class DistributedIdBlockStore implements IdBlockStore { |
42 | 42 | ||
43 | private final Logger log = getLogger(getClass()); | 43 | private final Logger log = getLogger(getClass()); |
44 | private final Map<String, AtomicCounter> topicCounters = Maps.newConcurrentMap(); | 44 | private final Map<String, AtomicCounter> topicCounters = Maps.newConcurrentMap(); | ... | ... |
... | @@ -34,7 +34,7 @@ import static org.onosproject.security.AppGuard.checkPermission; | ... | @@ -34,7 +34,7 @@ import static org.onosproject.security.AppGuard.checkPermission; |
34 | import static org.onosproject.security.AppPermission.Type.CLOCK_WRITE; | 34 | import static org.onosproject.security.AppPermission.Type.CLOCK_WRITE; |
35 | 35 | ||
36 | /** | 36 | /** |
37 | - * LogicalClockService implementation based on a AtomicCounter. | 37 | + * LogicalClockService implementation based on a {@link AtomicCounter}. |
38 | */ | 38 | */ |
39 | @Component(immediate = true, enabled = true) | 39 | @Component(immediate = true, enabled = true) |
40 | @Service | 40 | @Service | ... | ... |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Implementation of a distributed application ID registry store using Hazelcast. | 18 | + * Implementation of a distributed application registry. |
19 | */ | 19 | */ |
20 | package org.onosproject.store.core.impl; | 20 | package org.onosproject.store.core.impl; | ... | ... |
... | @@ -14,6 +14,6 @@ | ... | @@ -14,6 +14,6 @@ |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | /** | 16 | /** |
17 | - * Implementation of the group store. | 17 | + * Implementation of a distributed group store. |
18 | */ | 18 | */ |
19 | package org.onosproject.store.group.impl; | 19 | package org.onosproject.store.group.impl; | ... | ... |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Implementation of the distributed host store using p2p synchronization protocol. | 18 | + * Implementation of a distributed host store. |
19 | */ | 19 | */ |
20 | package org.onosproject.store.host.impl; | 20 | package org.onosproject.store.host.impl; | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/link/impl/GossipLinkStore.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import java.io.IOException; | ||
19 | -import java.util.Collections; | ||
20 | -import java.util.HashMap; | ||
21 | -import java.util.HashSet; | ||
22 | -import java.util.Map; | ||
23 | -import java.util.Map.Entry; | ||
24 | -import java.util.Set; | ||
25 | -import java.util.concurrent.ConcurrentHashMap; | ||
26 | -import java.util.concurrent.ConcurrentMap; | ||
27 | -import java.util.concurrent.ExecutorService; | ||
28 | -import java.util.concurrent.Executors; | ||
29 | -import java.util.concurrent.ScheduledExecutorService; | ||
30 | -import java.util.concurrent.TimeUnit; | ||
31 | - | ||
32 | -import org.apache.commons.lang3.RandomUtils; | ||
33 | -import org.apache.felix.scr.annotations.Activate; | ||
34 | -import org.apache.felix.scr.annotations.Deactivate; | ||
35 | -import org.apache.felix.scr.annotations.Reference; | ||
36 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
37 | -import org.apache.felix.scr.annotations.Service; | ||
38 | -import org.onlab.util.KryoNamespace; | ||
39 | -import org.onosproject.cluster.ClusterService; | ||
40 | -import org.onosproject.cluster.ControllerNode; | ||
41 | -import org.onosproject.cluster.NodeId; | ||
42 | -import org.onosproject.mastership.MastershipService; | ||
43 | -import org.onosproject.net.AnnotationsUtil; | ||
44 | -import org.onosproject.net.ConnectPoint; | ||
45 | -import org.onosproject.net.DefaultAnnotations; | ||
46 | -import org.onosproject.net.DefaultLink; | ||
47 | -import org.onosproject.net.DeviceId; | ||
48 | -import org.onosproject.net.Link; | ||
49 | -import org.onosproject.net.Link.Type; | ||
50 | -import org.onosproject.net.LinkKey; | ||
51 | -import org.onosproject.net.SparseAnnotations; | ||
52 | -import org.onosproject.net.device.DeviceClockService; | ||
53 | -import org.onosproject.net.link.DefaultLinkDescription; | ||
54 | -import org.onosproject.net.link.LinkDescription; | ||
55 | -import org.onosproject.net.link.LinkEvent; | ||
56 | -import org.onosproject.net.link.LinkStore; | ||
57 | -import org.onosproject.net.link.LinkStoreDelegate; | ||
58 | -import org.onosproject.net.provider.ProviderId; | ||
59 | -import org.onosproject.store.AbstractStore; | ||
60 | -import org.onosproject.store.Timestamp; | ||
61 | -import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
62 | -import org.onosproject.store.cluster.messaging.ClusterMessage; | ||
63 | -import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | ||
64 | -import org.onosproject.store.cluster.messaging.MessageSubject; | ||
65 | -import org.onosproject.store.impl.Timestamped; | ||
66 | -import org.onosproject.store.serializers.StoreSerializer; | ||
67 | -import org.onosproject.store.serializers.custom.DistributedStoreSerializers; | ||
68 | -import org.slf4j.Logger; | ||
69 | - | ||
70 | -import com.google.common.base.Function; | ||
71 | -import com.google.common.collect.FluentIterable; | ||
72 | -import com.google.common.collect.ImmutableList; | ||
73 | -import com.google.common.collect.Multimaps; | ||
74 | -import com.google.common.collect.SetMultimap; | ||
75 | -import com.google.common.collect.Sets; | ||
76 | - | ||
77 | -import static com.google.common.base.Preconditions.checkArgument; | ||
78 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
79 | -import static com.google.common.base.Predicates.notNull; | ||
80 | -import static com.google.common.collect.Multimaps.synchronizedSetMultimap; | ||
81 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
82 | -import static org.onlab.util.Tools.groupedThreads; | ||
83 | -import static org.onlab.util.Tools.minPriority; | ||
84 | -import static org.onosproject.cluster.ControllerNodeToNodeId.toNodeId; | ||
85 | -import static org.onosproject.net.DefaultAnnotations.merge; | ||
86 | -import static org.onosproject.net.DefaultAnnotations.union; | ||
87 | -import static org.onosproject.net.Link.State.ACTIVE; | ||
88 | -import static org.onosproject.net.Link.State.INACTIVE; | ||
89 | -import static org.onosproject.net.Link.Type.DIRECT; | ||
90 | -import static org.onosproject.net.Link.Type.INDIRECT; | ||
91 | -import static org.onosproject.net.LinkKey.linkKey; | ||
92 | -import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; | ||
93 | -import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED; | ||
94 | -import static org.onosproject.net.link.LinkEvent.Type.LINK_UPDATED; | ||
95 | -import static org.onosproject.store.link.impl.GossipLinkStoreMessageSubjects.LINK_ANTI_ENTROPY_ADVERTISEMENT; | ||
96 | -import static org.slf4j.LoggerFactory.getLogger; | ||
97 | - | ||
98 | -/** | ||
99 | - * Manages inventory of infrastructure links in distributed data store | ||
100 | - * that uses optimistic replication and gossip based techniques. | ||
101 | - */ | ||
102 | -//@Component(immediate = true, enabled = false) | ||
103 | -@Service | ||
104 | -public class GossipLinkStore | ||
105 | - extends AbstractStore<LinkEvent, LinkStoreDelegate> | ||
106 | - implements LinkStore { | ||
107 | - | ||
108 | - // Timeout in milliseconds to process links on remote master node | ||
109 | - private static final int REMOTE_MASTER_TIMEOUT = 1000; | ||
110 | - | ||
111 | - // Default delay for ScheduledExecutorService of anti-entropy(BackgroundExecutor) | ||
112 | - private static final long DEFAULT_INITIAL_DELAY = 5; | ||
113 | - | ||
114 | - // Default period for ScheduledExecutorService of anti-entropy(BackgroundExecutor) | ||
115 | - private static final long DEFAULT_PERIOD = 5; | ||
116 | - | ||
117 | - private static long initialDelaySec = DEFAULT_INITIAL_DELAY; | ||
118 | - private static long periodSec = DEFAULT_PERIOD; | ||
119 | - | ||
120 | - private final Logger log = getLogger(getClass()); | ||
121 | - | ||
122 | - // Link inventory | ||
123 | - private final ConcurrentMap<LinkKey, Map<ProviderId, Timestamped<LinkDescription>>> linkDescs = | ||
124 | - new ConcurrentHashMap<>(); | ||
125 | - | ||
126 | - // Link instance cache | ||
127 | - private final ConcurrentMap<LinkKey, Link> links = new ConcurrentHashMap<>(); | ||
128 | - | ||
129 | - // Egress and ingress link sets | ||
130 | - private final SetMultimap<DeviceId, LinkKey> srcLinks = createSynchronizedHashMultiMap(); | ||
131 | - private final SetMultimap<DeviceId, LinkKey> dstLinks = createSynchronizedHashMultiMap(); | ||
132 | - | ||
133 | - // Remove links | ||
134 | - private final Map<LinkKey, Timestamp> removedLinks = new ConcurrentHashMap<>(); | ||
135 | - | ||
136 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
137 | - protected DeviceClockService deviceClockService; | ||
138 | - | ||
139 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
140 | - protected ClusterCommunicationService clusterCommunicator; | ||
141 | - | ||
142 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
143 | - protected ClusterService clusterService; | ||
144 | - | ||
145 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
146 | - protected MastershipService mastershipService; | ||
147 | - | ||
148 | - protected static final StoreSerializer SERIALIZER = StoreSerializer.using( | ||
149 | - KryoNamespace.newBuilder() | ||
150 | - .register(DistributedStoreSerializers.STORE_COMMON) | ||
151 | - .nextId(DistributedStoreSerializers.STORE_CUSTOM_BEGIN) | ||
152 | - .register(InternalLinkEvent.class) | ||
153 | - .register(InternalLinkRemovedEvent.class) | ||
154 | - .register(LinkAntiEntropyAdvertisement.class) | ||
155 | - .register(LinkFragmentId.class) | ||
156 | - .register(LinkInjectedEvent.class) | ||
157 | - .build("GossipLink")); | ||
158 | - | ||
159 | - private ExecutorService executor; | ||
160 | - | ||
161 | - private ScheduledExecutorService backgroundExecutors; | ||
162 | - | ||
163 | - @Activate | ||
164 | - public void activate() { | ||
165 | - | ||
166 | - executor = Executors.newCachedThreadPool(groupedThreads("onos/link", "fg-%d")); | ||
167 | - | ||
168 | - backgroundExecutors = | ||
169 | - newSingleThreadScheduledExecutor(minPriority(groupedThreads("onos/link", "bg-%d"))); | ||
170 | - | ||
171 | - clusterCommunicator.addSubscriber( | ||
172 | - GossipLinkStoreMessageSubjects.LINK_UPDATE, | ||
173 | - new InternalLinkEventListener(), executor); | ||
174 | - clusterCommunicator.addSubscriber( | ||
175 | - GossipLinkStoreMessageSubjects.LINK_REMOVED, | ||
176 | - new InternalLinkRemovedEventListener(), executor); | ||
177 | - clusterCommunicator.addSubscriber( | ||
178 | - GossipLinkStoreMessageSubjects.LINK_ANTI_ENTROPY_ADVERTISEMENT, | ||
179 | - new InternalLinkAntiEntropyAdvertisementListener(), backgroundExecutors); | ||
180 | - clusterCommunicator.addSubscriber( | ||
181 | - GossipLinkStoreMessageSubjects.LINK_INJECTED, | ||
182 | - new LinkInjectedEventListener(), executor); | ||
183 | - | ||
184 | - // start anti-entropy thread | ||
185 | - backgroundExecutors.scheduleAtFixedRate(new SendAdvertisementTask(), | ||
186 | - initialDelaySec, periodSec, TimeUnit.SECONDS); | ||
187 | - | ||
188 | - log.info("Started"); | ||
189 | - } | ||
190 | - | ||
191 | - @Deactivate | ||
192 | - public void deactivate() { | ||
193 | - | ||
194 | - executor.shutdownNow(); | ||
195 | - | ||
196 | - backgroundExecutors.shutdownNow(); | ||
197 | - try { | ||
198 | - if (!backgroundExecutors.awaitTermination(5, TimeUnit.SECONDS)) { | ||
199 | - log.error("Timeout during executor shutdown"); | ||
200 | - } | ||
201 | - } catch (InterruptedException e) { | ||
202 | - log.error("Error during executor shutdown", e); | ||
203 | - } | ||
204 | - | ||
205 | - linkDescs.clear(); | ||
206 | - links.clear(); | ||
207 | - srcLinks.clear(); | ||
208 | - dstLinks.clear(); | ||
209 | - log.info("Stopped"); | ||
210 | - } | ||
211 | - | ||
212 | - @Override | ||
213 | - public int getLinkCount() { | ||
214 | - return links.size(); | ||
215 | - } | ||
216 | - | ||
217 | - @Override | ||
218 | - public Iterable<Link> getLinks() { | ||
219 | - return Collections.unmodifiableCollection(links.values()); | ||
220 | - } | ||
221 | - | ||
222 | - @Override | ||
223 | - public Set<Link> getDeviceEgressLinks(DeviceId deviceId) { | ||
224 | - // lock for iteration | ||
225 | - synchronized (srcLinks) { | ||
226 | - return FluentIterable.from(srcLinks.get(deviceId)) | ||
227 | - .transform(lookupLink()) | ||
228 | - .filter(notNull()) | ||
229 | - .toSet(); | ||
230 | - } | ||
231 | - } | ||
232 | - | ||
233 | - @Override | ||
234 | - public Set<Link> getDeviceIngressLinks(DeviceId deviceId) { | ||
235 | - // lock for iteration | ||
236 | - synchronized (dstLinks) { | ||
237 | - return FluentIterable.from(dstLinks.get(deviceId)) | ||
238 | - .transform(lookupLink()) | ||
239 | - .filter(notNull()) | ||
240 | - .toSet(); | ||
241 | - } | ||
242 | - } | ||
243 | - | ||
244 | - @Override | ||
245 | - public Link getLink(ConnectPoint src, ConnectPoint dst) { | ||
246 | - return links.get(linkKey(src, dst)); | ||
247 | - } | ||
248 | - | ||
249 | - @Override | ||
250 | - public Set<Link> getEgressLinks(ConnectPoint src) { | ||
251 | - Set<Link> egress = new HashSet<>(); | ||
252 | - // | ||
253 | - // Change `srcLinks` to ConcurrentMap<DeviceId, (Concurrent)Set> | ||
254 | - // to remove this synchronized block, if we hit performance issue. | ||
255 | - // SetMultiMap#get returns wrapped collection to provide modifiable-view. | ||
256 | - // And the wrapped collection is not concurrent access safe. | ||
257 | - // | ||
258 | - // Our use case here does not require returned collection to be modifiable, | ||
259 | - // so the wrapped collection forces us to lock the whole multiset, | ||
260 | - // for benefit we don't need. | ||
261 | - // | ||
262 | - // Same applies to `dstLinks` | ||
263 | - synchronized (srcLinks) { | ||
264 | - for (LinkKey linkKey : srcLinks.get(src.deviceId())) { | ||
265 | - if (linkKey.src().equals(src)) { | ||
266 | - Link link = links.get(linkKey); | ||
267 | - if (link != null) { | ||
268 | - egress.add(link); | ||
269 | - } else { | ||
270 | - log.debug("Egress link for {} was null, skipped", linkKey); | ||
271 | - } | ||
272 | - } | ||
273 | - } | ||
274 | - } | ||
275 | - return egress; | ||
276 | - } | ||
277 | - | ||
278 | - @Override | ||
279 | - public Set<Link> getIngressLinks(ConnectPoint dst) { | ||
280 | - Set<Link> ingress = new HashSet<>(); | ||
281 | - synchronized (dstLinks) { | ||
282 | - for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { | ||
283 | - if (linkKey.dst().equals(dst)) { | ||
284 | - Link link = links.get(linkKey); | ||
285 | - if (link != null) { | ||
286 | - ingress.add(link); | ||
287 | - } else { | ||
288 | - log.debug("Ingress link for {} was null, skipped", linkKey); | ||
289 | - } | ||
290 | - } | ||
291 | - } | ||
292 | - } | ||
293 | - return ingress; | ||
294 | - } | ||
295 | - | ||
296 | - @Override | ||
297 | - public LinkEvent createOrUpdateLink(ProviderId providerId, | ||
298 | - LinkDescription linkDescription) { | ||
299 | - | ||
300 | - final DeviceId dstDeviceId = linkDescription.dst().deviceId(); | ||
301 | - final NodeId localNode = clusterService.getLocalNode().id(); | ||
302 | - final NodeId dstNode = mastershipService.getMasterFor(dstDeviceId); | ||
303 | - | ||
304 | - // Process link update only if we're the master of the destination node, | ||
305 | - // otherwise signal the actual master. | ||
306 | - LinkEvent linkEvent = null; | ||
307 | - if (localNode.equals(dstNode)) { | ||
308 | - | ||
309 | - Timestamp newTimestamp = deviceClockService.getTimestamp(dstDeviceId); | ||
310 | - | ||
311 | - final Timestamped<LinkDescription> deltaDesc = new Timestamped<>(linkDescription, newTimestamp); | ||
312 | - | ||
313 | - LinkKey key = linkKey(linkDescription.src(), linkDescription.dst()); | ||
314 | - final Timestamped<LinkDescription> mergedDesc; | ||
315 | - Map<ProviderId, Timestamped<LinkDescription>> map = getOrCreateLinkDescriptions(key); | ||
316 | - | ||
317 | - synchronized (map) { | ||
318 | - linkEvent = createOrUpdateLinkInternal(providerId, deltaDesc); | ||
319 | - mergedDesc = map.get(providerId); | ||
320 | - } | ||
321 | - | ||
322 | - if (linkEvent != null) { | ||
323 | - log.debug("Notifying peers of a link update topology event from providerId: " | ||
324 | - + "{} between src: {} and dst: {}", | ||
325 | - providerId, linkDescription.src(), linkDescription.dst()); | ||
326 | - notifyPeers(new InternalLinkEvent(providerId, mergedDesc)); | ||
327 | - } | ||
328 | - | ||
329 | - } else { | ||
330 | - // Only forward for ConfigProvider | ||
331 | - // Forwarding was added as a workaround for ONOS-490 | ||
332 | - if (!providerId.scheme().equals("cfg")) { | ||
333 | - return null; | ||
334 | - } | ||
335 | - // FIXME Temporary hack for NPE (ONOS-1171). | ||
336 | - // Proper fix is to implement forwarding to master on ConfigProvider | ||
337 | - // redo ONOS-490 | ||
338 | - if (dstNode == null) { | ||
339 | - // silently ignore | ||
340 | - return null; | ||
341 | - } | ||
342 | - | ||
343 | - | ||
344 | - LinkInjectedEvent linkInjectedEvent = new LinkInjectedEvent(providerId, linkDescription); | ||
345 | - | ||
346 | - // TODO check unicast return value | ||
347 | - clusterCommunicator.unicast(linkInjectedEvent, | ||
348 | - GossipLinkStoreMessageSubjects.LINK_INJECTED, | ||
349 | - SERIALIZER::encode, | ||
350 | - dstNode); | ||
351 | - } | ||
352 | - | ||
353 | - return linkEvent; | ||
354 | - } | ||
355 | - | ||
356 | - @Override | ||
357 | - public LinkEvent removeOrDownLink(ConnectPoint src, ConnectPoint dst) { | ||
358 | - Link link = getLink(src, dst); | ||
359 | - if (link == null) { | ||
360 | - return null; | ||
361 | - } | ||
362 | - | ||
363 | - if (link.isDurable()) { | ||
364 | - // FIXME: this is not the right thing to call for the gossip store; will not sync link state!!! | ||
365 | - return link.state() == INACTIVE ? null : | ||
366 | - updateLink(linkKey(link.src(), link.dst()), link, | ||
367 | - DefaultLink.builder() | ||
368 | - .providerId(link.providerId()) | ||
369 | - .src(link.src()) | ||
370 | - .dst(link.dst()) | ||
371 | - .type(link.type()) | ||
372 | - .state(INACTIVE) | ||
373 | - .isExpected(link.isExpected()) | ||
374 | - .annotations(link.annotations()) | ||
375 | - .build()); | ||
376 | - } | ||
377 | - return removeLink(src, dst); | ||
378 | - } | ||
379 | - | ||
380 | - private LinkEvent createOrUpdateLinkInternal( | ||
381 | - ProviderId providerId, | ||
382 | - Timestamped<LinkDescription> linkDescription) { | ||
383 | - | ||
384 | - final LinkKey key = linkKey(linkDescription.value().src(), | ||
385 | - linkDescription.value().dst()); | ||
386 | - Map<ProviderId, Timestamped<LinkDescription>> descs = getOrCreateLinkDescriptions(key); | ||
387 | - | ||
388 | - synchronized (descs) { | ||
389 | - // if the link was previously removed, we should proceed if and | ||
390 | - // only if this request is more recent. | ||
391 | - Timestamp linkRemovedTimestamp = removedLinks.get(key); | ||
392 | - if (linkRemovedTimestamp != null) { | ||
393 | - if (linkDescription.isNewerThan(linkRemovedTimestamp)) { | ||
394 | - removedLinks.remove(key); | ||
395 | - } else { | ||
396 | - log.trace("Link {} was already removed ignoring.", key); | ||
397 | - return null; | ||
398 | - } | ||
399 | - } | ||
400 | - | ||
401 | - final Link oldLink = links.get(key); | ||
402 | - // update description | ||
403 | - createOrUpdateLinkDescription(descs, providerId, linkDescription); | ||
404 | - final Link newLink = composeLink(descs); | ||
405 | - if (oldLink == null) { | ||
406 | - return createLink(key, newLink); | ||
407 | - } | ||
408 | - return updateLink(key, oldLink, newLink); | ||
409 | - } | ||
410 | - } | ||
411 | - | ||
412 | - // Guarded by linkDescs value (=locking each Link) | ||
413 | - private Timestamped<LinkDescription> createOrUpdateLinkDescription( | ||
414 | - Map<ProviderId, Timestamped<LinkDescription>> descs, | ||
415 | - ProviderId providerId, | ||
416 | - Timestamped<LinkDescription> linkDescription) { | ||
417 | - | ||
418 | - // merge existing annotations | ||
419 | - Timestamped<LinkDescription> existingLinkDescription = descs.get(providerId); | ||
420 | - if (existingLinkDescription != null && existingLinkDescription.isNewer(linkDescription)) { | ||
421 | - log.trace("local info is more up-to-date, ignoring {}.", linkDescription); | ||
422 | - return null; | ||
423 | - } | ||
424 | - Timestamped<LinkDescription> newLinkDescription = linkDescription; | ||
425 | - if (existingLinkDescription != null) { | ||
426 | - // we only allow transition from INDIRECT -> DIRECT | ||
427 | - final Type newType; | ||
428 | - if (existingLinkDescription.value().type() == DIRECT) { | ||
429 | - newType = DIRECT; | ||
430 | - } else { | ||
431 | - newType = linkDescription.value().type(); | ||
432 | - } | ||
433 | - SparseAnnotations merged = union(existingLinkDescription.value().annotations(), | ||
434 | - linkDescription.value().annotations()); | ||
435 | - newLinkDescription = new Timestamped<>( | ||
436 | - new DefaultLinkDescription( | ||
437 | - linkDescription.value().src(), | ||
438 | - linkDescription.value().dst(), | ||
439 | - newType, | ||
440 | - existingLinkDescription.value().isExpected(), | ||
441 | - merged), | ||
442 | - linkDescription.timestamp()); | ||
443 | - } | ||
444 | - return descs.put(providerId, newLinkDescription); | ||
445 | - } | ||
446 | - | ||
447 | - // Creates and stores the link and returns the appropriate event. | ||
448 | - // Guarded by linkDescs value (=locking each Link) | ||
449 | - private LinkEvent createLink(LinkKey key, Link newLink) { | ||
450 | - links.put(key, newLink); | ||
451 | - srcLinks.put(newLink.src().deviceId(), key); | ||
452 | - dstLinks.put(newLink.dst().deviceId(), key); | ||
453 | - return new LinkEvent(LINK_ADDED, newLink); | ||
454 | - } | ||
455 | - | ||
456 | - // Updates, if necessary the specified link and returns the appropriate event. | ||
457 | - // Guarded by linkDescs value (=locking each Link) | ||
458 | - private LinkEvent updateLink(LinkKey key, Link oldLink, Link newLink) { | ||
459 | - // Note: INDIRECT -> DIRECT transition only | ||
460 | - // so that BDDP discovered Link will not overwrite LDDP Link | ||
461 | - if (oldLink.state() != newLink.state() || | ||
462 | - (oldLink.type() == INDIRECT && newLink.type() == DIRECT) || | ||
463 | - !AnnotationsUtil.isEqual(oldLink.annotations(), newLink.annotations())) { | ||
464 | - | ||
465 | - links.put(key, newLink); | ||
466 | - // strictly speaking following can be omitted | ||
467 | - srcLinks.put(oldLink.src().deviceId(), key); | ||
468 | - dstLinks.put(oldLink.dst().deviceId(), key); | ||
469 | - return new LinkEvent(LINK_UPDATED, newLink); | ||
470 | - } | ||
471 | - return null; | ||
472 | - } | ||
473 | - | ||
474 | - @Override | ||
475 | - public LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) { | ||
476 | - final LinkKey key = linkKey(src, dst); | ||
477 | - | ||
478 | - DeviceId dstDeviceId = dst.deviceId(); | ||
479 | - Timestamp timestamp = null; | ||
480 | - try { | ||
481 | - timestamp = deviceClockService.getTimestamp(dstDeviceId); | ||
482 | - } catch (IllegalStateException e) { | ||
483 | - log.debug("Failed to remove link {}, was not the master", key); | ||
484 | - // there are times when this is called before mastership | ||
485 | - // handoff correctly completes. | ||
486 | - return null; | ||
487 | - } | ||
488 | - | ||
489 | - LinkEvent event = removeLinkInternal(key, timestamp); | ||
490 | - | ||
491 | - if (event != null) { | ||
492 | - log.debug("Notifying peers of a link removed topology event for a link " | ||
493 | - + "between src: {} and dst: {}", src, dst); | ||
494 | - notifyPeers(new InternalLinkRemovedEvent(key, timestamp)); | ||
495 | - } | ||
496 | - return event; | ||
497 | - } | ||
498 | - | ||
499 | - private static Timestamped<LinkDescription> getPrimaryDescription( | ||
500 | - Map<ProviderId, Timestamped<LinkDescription>> linkDescriptions) { | ||
501 | - | ||
502 | - synchronized (linkDescriptions) { | ||
503 | - for (Entry<ProviderId, Timestamped<LinkDescription>> | ||
504 | - e : linkDescriptions.entrySet()) { | ||
505 | - | ||
506 | - if (!e.getKey().isAncillary()) { | ||
507 | - return e.getValue(); | ||
508 | - } | ||
509 | - } | ||
510 | - } | ||
511 | - return null; | ||
512 | - } | ||
513 | - | ||
514 | - | ||
515 | - // TODO: consider slicing out as Timestamp utils | ||
516 | - /** | ||
517 | - * Checks is timestamp is more recent than timestamped object. | ||
518 | - * | ||
519 | - * @param timestamp to check if this is more recent then other | ||
520 | - * @param timestamped object to be tested against | ||
521 | - * @return true if {@code timestamp} is more recent than {@code timestamped} | ||
522 | - * or {@code timestamped is null} | ||
523 | - */ | ||
524 | - private static boolean isMoreRecent(Timestamp timestamp, Timestamped<?> timestamped) { | ||
525 | - checkNotNull(timestamp); | ||
526 | - if (timestamped == null) { | ||
527 | - return true; | ||
528 | - } | ||
529 | - return timestamp.compareTo(timestamped.timestamp()) > 0; | ||
530 | - } | ||
531 | - | ||
532 | - private LinkEvent removeLinkInternal(LinkKey key, Timestamp timestamp) { | ||
533 | - Map<ProviderId, Timestamped<LinkDescription>> linkDescriptions | ||
534 | - = getOrCreateLinkDescriptions(key); | ||
535 | - | ||
536 | - synchronized (linkDescriptions) { | ||
537 | - if (linkDescriptions.isEmpty()) { | ||
538 | - // never seen such link before. keeping timestamp for record | ||
539 | - removedLinks.put(key, timestamp); | ||
540 | - return null; | ||
541 | - } | ||
542 | - // accept removal request if given timestamp is newer than | ||
543 | - // the latest Timestamp from Primary provider | ||
544 | - Timestamped<LinkDescription> prim = getPrimaryDescription(linkDescriptions); | ||
545 | - if (!isMoreRecent(timestamp, prim)) { | ||
546 | - // outdated remove request, ignore | ||
547 | - return null; | ||
548 | - } | ||
549 | - removedLinks.put(key, timestamp); | ||
550 | - Link link = links.remove(key); | ||
551 | - linkDescriptions.clear(); | ||
552 | - if (link != null) { | ||
553 | - srcLinks.remove(link.src().deviceId(), key); | ||
554 | - dstLinks.remove(link.dst().deviceId(), key); | ||
555 | - return new LinkEvent(LINK_REMOVED, link); | ||
556 | - } | ||
557 | - return null; | ||
558 | - } | ||
559 | - } | ||
560 | - | ||
561 | - /** | ||
562 | - * Creates concurrent readable, synchronized HashMultimap. | ||
563 | - * | ||
564 | - * @return SetMultimap | ||
565 | - */ | ||
566 | - private static <K, V> SetMultimap<K, V> createSynchronizedHashMultiMap() { | ||
567 | - return synchronizedSetMultimap( | ||
568 | - Multimaps.newSetMultimap(new ConcurrentHashMap<>(), | ||
569 | - () -> Sets.newConcurrentHashSet())); | ||
570 | - } | ||
571 | - | ||
572 | - /** | ||
573 | - * @return primary ProviderID, or randomly chosen one if none exists | ||
574 | - */ | ||
575 | - private static ProviderId pickBaseProviderId( | ||
576 | - Map<ProviderId, Timestamped<LinkDescription>> linkDescriptions) { | ||
577 | - | ||
578 | - ProviderId fallBackPrimary = null; | ||
579 | - for (Entry<ProviderId, Timestamped<LinkDescription>> e : linkDescriptions.entrySet()) { | ||
580 | - if (!e.getKey().isAncillary()) { | ||
581 | - // found primary | ||
582 | - return e.getKey(); | ||
583 | - } else if (fallBackPrimary == null) { | ||
584 | - // pick randomly as a fallback in case there is no primary | ||
585 | - fallBackPrimary = e.getKey(); | ||
586 | - } | ||
587 | - } | ||
588 | - return fallBackPrimary; | ||
589 | - } | ||
590 | - | ||
591 | - // Guarded by linkDescs value (=locking each Link) | ||
592 | - private Link composeLink(Map<ProviderId, Timestamped<LinkDescription>> descs) { | ||
593 | - ProviderId baseProviderId = pickBaseProviderId(descs); | ||
594 | - Timestamped<LinkDescription> base = descs.get(baseProviderId); | ||
595 | - | ||
596 | - ConnectPoint src = base.value().src(); | ||
597 | - ConnectPoint dst = base.value().dst(); | ||
598 | - Type type = base.value().type(); | ||
599 | - DefaultAnnotations annotations = DefaultAnnotations.builder().build(); | ||
600 | - annotations = merge(annotations, base.value().annotations()); | ||
601 | - | ||
602 | - for (Entry<ProviderId, Timestamped<LinkDescription>> e : descs.entrySet()) { | ||
603 | - if (baseProviderId.equals(e.getKey())) { | ||
604 | - continue; | ||
605 | - } | ||
606 | - | ||
607 | - // Note: In the long run we should keep track of Description timestamp | ||
608 | - // and only merge conflicting keys when timestamp is newer | ||
609 | - // Currently assuming there will never be a key conflict between | ||
610 | - // providers | ||
611 | - | ||
612 | - // annotation merging. not so efficient, should revisit later | ||
613 | - annotations = merge(annotations, e.getValue().value().annotations()); | ||
614 | - } | ||
615 | - | ||
616 | - //boolean isDurable = Objects.equals(annotations.value(AnnotationKeys.DURABLE), "true"); | ||
617 | - | ||
618 | - // TEMP | ||
619 | - Link.State initialLinkState = base.value().isExpected() ? ACTIVE : INACTIVE; | ||
620 | - return DefaultLink.builder() | ||
621 | - .providerId(baseProviderId) | ||
622 | - .src(src) | ||
623 | - .dst(dst) | ||
624 | - .type(type) | ||
625 | - .state(initialLinkState) | ||
626 | - .isExpected(base.value().isExpected()) | ||
627 | - .annotations(annotations) | ||
628 | - .build(); | ||
629 | - } | ||
630 | - | ||
631 | - private Map<ProviderId, Timestamped<LinkDescription>> getOrCreateLinkDescriptions(LinkKey key) { | ||
632 | - Map<ProviderId, Timestamped<LinkDescription>> r; | ||
633 | - r = linkDescs.get(key); | ||
634 | - if (r != null) { | ||
635 | - return r; | ||
636 | - } | ||
637 | - r = new HashMap<>(); | ||
638 | - final Map<ProviderId, Timestamped<LinkDescription>> concurrentlyAdded; | ||
639 | - concurrentlyAdded = linkDescs.putIfAbsent(key, r); | ||
640 | - if (concurrentlyAdded != null) { | ||
641 | - return concurrentlyAdded; | ||
642 | - } else { | ||
643 | - return r; | ||
644 | - } | ||
645 | - } | ||
646 | - | ||
647 | - private final Function<LinkKey, Link> lookupLink = new LookupLink(); | ||
648 | - | ||
649 | - /** | ||
650 | - * Returns a Function to lookup Link instance using LinkKey from cache. | ||
651 | - * | ||
652 | - * @return lookup link function | ||
653 | - */ | ||
654 | - private Function<LinkKey, Link> lookupLink() { | ||
655 | - return lookupLink; | ||
656 | - } | ||
657 | - | ||
658 | - private final class LookupLink implements Function<LinkKey, Link> { | ||
659 | - @Override | ||
660 | - public Link apply(LinkKey input) { | ||
661 | - if (input == null) { | ||
662 | - return null; | ||
663 | - } else { | ||
664 | - return links.get(input); | ||
665 | - } | ||
666 | - } | ||
667 | - } | ||
668 | - | ||
669 | - private void notifyDelegateIfNotNull(LinkEvent event) { | ||
670 | - if (event != null) { | ||
671 | - notifyDelegate(event); | ||
672 | - } | ||
673 | - } | ||
674 | - | ||
675 | - private void broadcastMessage(MessageSubject subject, Object event) { | ||
676 | - clusterCommunicator.broadcast(event, subject, SERIALIZER::encode); | ||
677 | - } | ||
678 | - | ||
679 | - private void unicastMessage(NodeId recipient, MessageSubject subject, Object event) throws IOException { | ||
680 | - clusterCommunicator.unicast(event, subject, SERIALIZER::encode, recipient); | ||
681 | - } | ||
682 | - | ||
683 | - private void notifyPeers(InternalLinkEvent event) { | ||
684 | - broadcastMessage(GossipLinkStoreMessageSubjects.LINK_UPDATE, event); | ||
685 | - } | ||
686 | - | ||
687 | - private void notifyPeers(InternalLinkRemovedEvent event) { | ||
688 | - broadcastMessage(GossipLinkStoreMessageSubjects.LINK_REMOVED, event); | ||
689 | - } | ||
690 | - | ||
691 | - // notify peer, silently ignoring error | ||
692 | - private void notifyPeer(NodeId peer, InternalLinkEvent event) { | ||
693 | - try { | ||
694 | - unicastMessage(peer, GossipLinkStoreMessageSubjects.LINK_UPDATE, event); | ||
695 | - } catch (IOException e) { | ||
696 | - log.debug("Failed to notify peer {} with message {}", peer, event); | ||
697 | - } | ||
698 | - } | ||
699 | - | ||
700 | - // notify peer, silently ignoring error | ||
701 | - private void notifyPeer(NodeId peer, InternalLinkRemovedEvent event) { | ||
702 | - try { | ||
703 | - unicastMessage(peer, GossipLinkStoreMessageSubjects.LINK_REMOVED, event); | ||
704 | - } catch (IOException e) { | ||
705 | - log.debug("Failed to notify peer {} with message {}", peer, event); | ||
706 | - } | ||
707 | - } | ||
708 | - | ||
709 | - /** | ||
710 | - * sets the time to delay first execution for anti-entropy. | ||
711 | - * (scheduleAtFixedRate of ScheduledExecutorService) | ||
712 | - * | ||
713 | - * @param delay the time to delay first execution for anti-entropy | ||
714 | - */ | ||
715 | - private void setInitialDelaySec(long delay) { | ||
716 | - checkArgument(delay >= 0, "Initial delay of scheduleAtFixedRate() must be 0 or more"); | ||
717 | - initialDelaySec = delay; | ||
718 | - } | ||
719 | - | ||
720 | - /** | ||
721 | - * sets the period between successive execution for anti-entropy. | ||
722 | - * (scheduleAtFixedRate of ScheduledExecutorService) | ||
723 | - * | ||
724 | - * @param period the period between successive execution for anti-entropy | ||
725 | - */ | ||
726 | - private void setPeriodSec(long period) { | ||
727 | - checkArgument(period > 0, "Period of scheduleAtFixedRate() must be greater than 0"); | ||
728 | - periodSec = period; | ||
729 | - } | ||
730 | - | ||
731 | - private final class SendAdvertisementTask implements Runnable { | ||
732 | - | ||
733 | - @Override | ||
734 | - public void run() { | ||
735 | - if (Thread.currentThread().isInterrupted()) { | ||
736 | - log.debug("Interrupted, quitting"); | ||
737 | - return; | ||
738 | - } | ||
739 | - | ||
740 | - try { | ||
741 | - final NodeId self = clusterService.getLocalNode().id(); | ||
742 | - Set<ControllerNode> nodes = clusterService.getNodes(); | ||
743 | - | ||
744 | - ImmutableList<NodeId> nodeIds = FluentIterable.from(nodes) | ||
745 | - .transform(toNodeId()) | ||
746 | - .toList(); | ||
747 | - | ||
748 | - if (nodeIds.size() == 1 && nodeIds.get(0).equals(self)) { | ||
749 | - log.trace("No other peers in the cluster."); | ||
750 | - return; | ||
751 | - } | ||
752 | - | ||
753 | - NodeId peer; | ||
754 | - do { | ||
755 | - int idx = RandomUtils.nextInt(0, nodeIds.size()); | ||
756 | - peer = nodeIds.get(idx); | ||
757 | - } while (peer.equals(self)); | ||
758 | - | ||
759 | - LinkAntiEntropyAdvertisement ad = createAdvertisement(); | ||
760 | - | ||
761 | - if (Thread.currentThread().isInterrupted()) { | ||
762 | - log.debug("Interrupted, quitting"); | ||
763 | - return; | ||
764 | - } | ||
765 | - | ||
766 | - try { | ||
767 | - unicastMessage(peer, LINK_ANTI_ENTROPY_ADVERTISEMENT, ad); | ||
768 | - } catch (IOException e) { | ||
769 | - log.debug("Failed to send anti-entropy advertisement to {}", peer); | ||
770 | - return; | ||
771 | - } | ||
772 | - } catch (Exception e) { | ||
773 | - // catch all Exception to avoid Scheduled task being suppressed. | ||
774 | - log.error("Exception thrown while sending advertisement", e); | ||
775 | - } | ||
776 | - } | ||
777 | - } | ||
778 | - | ||
779 | - private LinkAntiEntropyAdvertisement createAdvertisement() { | ||
780 | - final NodeId self = clusterService.getLocalNode().id(); | ||
781 | - | ||
782 | - Map<LinkFragmentId, Timestamp> linkTimestamps = new HashMap<>(linkDescs.size()); | ||
783 | - Map<LinkKey, Timestamp> linkTombstones = new HashMap<>(removedLinks.size()); | ||
784 | - | ||
785 | - linkDescs.forEach((linkKey, linkDesc) -> { | ||
786 | - synchronized (linkDesc) { | ||
787 | - for (Map.Entry<ProviderId, Timestamped<LinkDescription>> e : linkDesc.entrySet()) { | ||
788 | - linkTimestamps.put(new LinkFragmentId(linkKey, e.getKey()), e.getValue().timestamp()); | ||
789 | - } | ||
790 | - } | ||
791 | - }); | ||
792 | - | ||
793 | - linkTombstones.putAll(removedLinks); | ||
794 | - | ||
795 | - return new LinkAntiEntropyAdvertisement(self, linkTimestamps, linkTombstones); | ||
796 | - } | ||
797 | - | ||
798 | - private void handleAntiEntropyAdvertisement(LinkAntiEntropyAdvertisement ad) { | ||
799 | - | ||
800 | - final NodeId sender = ad.sender(); | ||
801 | - boolean localOutdated = false; | ||
802 | - | ||
803 | - for (Entry<LinkKey, Map<ProviderId, Timestamped<LinkDescription>>> | ||
804 | - l : linkDescs.entrySet()) { | ||
805 | - | ||
806 | - final LinkKey key = l.getKey(); | ||
807 | - final Map<ProviderId, Timestamped<LinkDescription>> link = l.getValue(); | ||
808 | - synchronized (link) { | ||
809 | - Timestamp localLatest = removedLinks.get(key); | ||
810 | - | ||
811 | - for (Entry<ProviderId, Timestamped<LinkDescription>> p : link.entrySet()) { | ||
812 | - final ProviderId providerId = p.getKey(); | ||
813 | - final Timestamped<LinkDescription> pDesc = p.getValue(); | ||
814 | - | ||
815 | - final LinkFragmentId fragId = new LinkFragmentId(key, providerId); | ||
816 | - // remote | ||
817 | - Timestamp remoteTimestamp = ad.linkTimestamps().get(fragId); | ||
818 | - if (remoteTimestamp == null) { | ||
819 | - remoteTimestamp = ad.linkTombstones().get(key); | ||
820 | - } | ||
821 | - if (remoteTimestamp == null || | ||
822 | - pDesc.isNewerThan(remoteTimestamp)) { | ||
823 | - // I have more recent link description. update peer. | ||
824 | - notifyPeer(sender, new InternalLinkEvent(providerId, pDesc)); | ||
825 | - } else { | ||
826 | - final Timestamp remoteLive = ad.linkTimestamps().get(fragId); | ||
827 | - if (remoteLive != null && | ||
828 | - remoteLive.compareTo(pDesc.timestamp()) > 0) { | ||
829 | - // I have something outdated | ||
830 | - localOutdated = true; | ||
831 | - } | ||
832 | - } | ||
833 | - | ||
834 | - // search local latest along the way | ||
835 | - if (localLatest == null || | ||
836 | - pDesc.isNewerThan(localLatest)) { | ||
837 | - localLatest = pDesc.timestamp(); | ||
838 | - } | ||
839 | - } | ||
840 | - // Tests if remote remove is more recent then local latest. | ||
841 | - final Timestamp remoteRemove = ad.linkTombstones().get(key); | ||
842 | - if (remoteRemove != null) { | ||
843 | - if (localLatest != null && | ||
844 | - localLatest.compareTo(remoteRemove) < 0) { | ||
845 | - // remote remove is more recent | ||
846 | - notifyDelegateIfNotNull(removeLinkInternal(key, remoteRemove)); | ||
847 | - } | ||
848 | - } | ||
849 | - } | ||
850 | - } | ||
851 | - | ||
852 | - // populate remove info if not known locally | ||
853 | - for (Entry<LinkKey, Timestamp> remoteRm : ad.linkTombstones().entrySet()) { | ||
854 | - final LinkKey key = remoteRm.getKey(); | ||
855 | - final Timestamp remoteRemove = remoteRm.getValue(); | ||
856 | - // relying on removeLinkInternal to ignore stale info | ||
857 | - notifyDelegateIfNotNull(removeLinkInternal(key, remoteRemove)); | ||
858 | - } | ||
859 | - | ||
860 | - if (localOutdated) { | ||
861 | - // send back advertisement to speed up convergence | ||
862 | - try { | ||
863 | - unicastMessage(sender, LINK_ANTI_ENTROPY_ADVERTISEMENT, | ||
864 | - createAdvertisement()); | ||
865 | - } catch (IOException e) { | ||
866 | - log.debug("Failed to send back active advertisement"); | ||
867 | - } | ||
868 | - } | ||
869 | - } | ||
870 | - | ||
871 | - private final class InternalLinkEventListener | ||
872 | - implements ClusterMessageHandler { | ||
873 | - @Override | ||
874 | - public void handle(ClusterMessage message) { | ||
875 | - | ||
876 | - log.trace("Received link event from peer: {}", message.sender()); | ||
877 | - InternalLinkEvent event = SERIALIZER.decode(message.payload()); | ||
878 | - | ||
879 | - ProviderId providerId = event.providerId(); | ||
880 | - Timestamped<LinkDescription> linkDescription = event.linkDescription(); | ||
881 | - | ||
882 | - try { | ||
883 | - notifyDelegateIfNotNull(createOrUpdateLinkInternal(providerId, linkDescription)); | ||
884 | - } catch (Exception e) { | ||
885 | - log.warn("Exception thrown handling link event", e); | ||
886 | - } | ||
887 | - } | ||
888 | - } | ||
889 | - | ||
890 | - private final class InternalLinkRemovedEventListener | ||
891 | - implements ClusterMessageHandler { | ||
892 | - @Override | ||
893 | - public void handle(ClusterMessage message) { | ||
894 | - | ||
895 | - log.trace("Received link removed event from peer: {}", message.sender()); | ||
896 | - InternalLinkRemovedEvent event = SERIALIZER.decode(message.payload()); | ||
897 | - | ||
898 | - LinkKey linkKey = event.linkKey(); | ||
899 | - Timestamp timestamp = event.timestamp(); | ||
900 | - | ||
901 | - try { | ||
902 | - notifyDelegateIfNotNull(removeLinkInternal(linkKey, timestamp)); | ||
903 | - } catch (Exception e) { | ||
904 | - log.warn("Exception thrown handling link removed", e); | ||
905 | - } | ||
906 | - } | ||
907 | - } | ||
908 | - | ||
909 | - private final class InternalLinkAntiEntropyAdvertisementListener | ||
910 | - implements ClusterMessageHandler { | ||
911 | - | ||
912 | - @Override | ||
913 | - public void handle(ClusterMessage message) { | ||
914 | - log.trace("Received Link Anti-Entropy advertisement from peer: {}", message.sender()); | ||
915 | - LinkAntiEntropyAdvertisement advertisement = SERIALIZER.decode(message.payload()); | ||
916 | - try { | ||
917 | - handleAntiEntropyAdvertisement(advertisement); | ||
918 | - } catch (Exception e) { | ||
919 | - log.warn("Exception thrown while handling Link advertisements", e); | ||
920 | - throw e; | ||
921 | - } | ||
922 | - } | ||
923 | - } | ||
924 | - | ||
925 | - private final class LinkInjectedEventListener | ||
926 | - implements ClusterMessageHandler { | ||
927 | - @Override | ||
928 | - public void handle(ClusterMessage message) { | ||
929 | - | ||
930 | - log.trace("Received injected link event from peer: {}", message.sender()); | ||
931 | - LinkInjectedEvent linkInjectedEvent = SERIALIZER.decode(message.payload()); | ||
932 | - | ||
933 | - ProviderId providerId = linkInjectedEvent.providerId(); | ||
934 | - LinkDescription linkDescription = linkInjectedEvent.linkDescription(); | ||
935 | - | ||
936 | - final DeviceId deviceId = linkDescription.dst().deviceId(); | ||
937 | - if (!deviceClockService.isTimestampAvailable(deviceId)) { | ||
938 | - // workaround for ONOS-1208 | ||
939 | - log.warn("Not ready to accept update. Dropping {}", linkDescription); | ||
940 | - return; | ||
941 | - } | ||
942 | - | ||
943 | - try { | ||
944 | - createOrUpdateLink(providerId, linkDescription); | ||
945 | - } catch (Exception e) { | ||
946 | - log.warn("Exception thrown while handling link injected event", e); | ||
947 | - } | ||
948 | - } | ||
949 | - } | ||
950 | -} |
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | - import org.onosproject.store.cluster.messaging.MessageSubject; | ||
19 | - | ||
20 | -/** | ||
21 | - * MessageSubjects used by GossipLinkStore peer-peer communication. | ||
22 | - */ | ||
23 | -public final class GossipLinkStoreMessageSubjects { | ||
24 | - | ||
25 | - private GossipLinkStoreMessageSubjects() {} | ||
26 | - | ||
27 | - public static final MessageSubject LINK_UPDATE = | ||
28 | - new MessageSubject("peer-link-update"); | ||
29 | - public static final MessageSubject LINK_REMOVED = | ||
30 | - new MessageSubject("peer-link-removed"); | ||
31 | - public static final MessageSubject LINK_ANTI_ENTROPY_ADVERTISEMENT = | ||
32 | - new MessageSubject("link-enti-entropy-advertisement"); | ||
33 | - public static final MessageSubject LINK_INJECTED = | ||
34 | - new MessageSubject("peer-link-injected"); | ||
35 | -} |
core/store/dist/src/main/java/org/onosproject/store/link/impl/InternalLinkEvent.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import com.google.common.base.MoreObjects; | ||
19 | - | ||
20 | -import org.onosproject.net.link.LinkDescription; | ||
21 | -import org.onosproject.net.provider.ProviderId; | ||
22 | -import org.onosproject.store.impl.Timestamped; | ||
23 | - | ||
24 | -/** | ||
25 | - * Information published by GossipDeviceStore to notify peers of a device | ||
26 | - * change event. | ||
27 | - */ | ||
28 | -public class InternalLinkEvent { | ||
29 | - | ||
30 | - private final ProviderId providerId; | ||
31 | - private final Timestamped<LinkDescription> linkDescription; | ||
32 | - | ||
33 | - protected InternalLinkEvent( | ||
34 | - ProviderId providerId, | ||
35 | - Timestamped<LinkDescription> linkDescription) { | ||
36 | - this.providerId = providerId; | ||
37 | - this.linkDescription = linkDescription; | ||
38 | - } | ||
39 | - | ||
40 | - public ProviderId providerId() { | ||
41 | - return providerId; | ||
42 | - } | ||
43 | - | ||
44 | - public Timestamped<LinkDescription> linkDescription() { | ||
45 | - return linkDescription; | ||
46 | - } | ||
47 | - | ||
48 | - @Override | ||
49 | - public String toString() { | ||
50 | - return MoreObjects.toStringHelper(getClass()) | ||
51 | - .add("providerId", providerId) | ||
52 | - .add("linkDescription", linkDescription) | ||
53 | - .toString(); | ||
54 | - } | ||
55 | - | ||
56 | - // for serializer | ||
57 | - protected InternalLinkEvent() { | ||
58 | - this.providerId = null; | ||
59 | - this.linkDescription = null; | ||
60 | - } | ||
61 | -} |
core/store/dist/src/main/java/org/onosproject/store/link/impl/InternalLinkRemovedEvent.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import org.onosproject.net.LinkKey; | ||
19 | -import org.onosproject.store.Timestamp; | ||
20 | - | ||
21 | -import com.google.common.base.MoreObjects; | ||
22 | - | ||
23 | -/** | ||
24 | - * Information published by GossipLinkStore to notify peers of a link | ||
25 | - * being removed. | ||
26 | - */ | ||
27 | -public class InternalLinkRemovedEvent { | ||
28 | - | ||
29 | - private final LinkKey linkKey; | ||
30 | - private final Timestamp timestamp; | ||
31 | - | ||
32 | - /** | ||
33 | - * Creates a InternalLinkRemovedEvent. | ||
34 | - * @param linkKey identifier of the removed link. | ||
35 | - * @param timestamp timestamp of when the link was removed. | ||
36 | - */ | ||
37 | - public InternalLinkRemovedEvent(LinkKey linkKey, Timestamp timestamp) { | ||
38 | - this.linkKey = linkKey; | ||
39 | - this.timestamp = timestamp; | ||
40 | - } | ||
41 | - | ||
42 | - public LinkKey linkKey() { | ||
43 | - return linkKey; | ||
44 | - } | ||
45 | - | ||
46 | - public Timestamp timestamp() { | ||
47 | - return timestamp; | ||
48 | - } | ||
49 | - | ||
50 | - @Override | ||
51 | - public String toString() { | ||
52 | - return MoreObjects.toStringHelper(getClass()) | ||
53 | - .add("linkKey", linkKey) | ||
54 | - .add("timestamp", timestamp) | ||
55 | - .toString(); | ||
56 | - } | ||
57 | - | ||
58 | - // for serializer | ||
59 | - @SuppressWarnings("unused") | ||
60 | - private InternalLinkRemovedEvent() { | ||
61 | - linkKey = null; | ||
62 | - timestamp = null; | ||
63 | - } | ||
64 | -} |
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | - | ||
20 | -import java.util.Map; | ||
21 | - | ||
22 | -import org.onosproject.cluster.NodeId; | ||
23 | -import org.onosproject.net.LinkKey; | ||
24 | -import org.onosproject.store.Timestamp; | ||
25 | - | ||
26 | -/** | ||
27 | - * Link AE Advertisement message. | ||
28 | - */ | ||
29 | -public class LinkAntiEntropyAdvertisement { | ||
30 | - | ||
31 | - private final NodeId sender; | ||
32 | - private final Map<LinkFragmentId, Timestamp> linkTimestamps; | ||
33 | - private final Map<LinkKey, Timestamp> linkTombstones; | ||
34 | - | ||
35 | - | ||
36 | - public LinkAntiEntropyAdvertisement(NodeId sender, | ||
37 | - Map<LinkFragmentId, Timestamp> linkTimestamps, | ||
38 | - Map<LinkKey, Timestamp> linkTombstones) { | ||
39 | - this.sender = checkNotNull(sender); | ||
40 | - this.linkTimestamps = checkNotNull(linkTimestamps); | ||
41 | - this.linkTombstones = checkNotNull(linkTombstones); | ||
42 | - } | ||
43 | - | ||
44 | - public NodeId sender() { | ||
45 | - return sender; | ||
46 | - } | ||
47 | - | ||
48 | - public Map<LinkFragmentId, Timestamp> linkTimestamps() { | ||
49 | - return linkTimestamps; | ||
50 | - } | ||
51 | - | ||
52 | - public Map<LinkKey, Timestamp> linkTombstones() { | ||
53 | - return linkTombstones; | ||
54 | - } | ||
55 | - | ||
56 | - // For serializer | ||
57 | - @SuppressWarnings("unused") | ||
58 | - private LinkAntiEntropyAdvertisement() { | ||
59 | - this.sender = null; | ||
60 | - this.linkTimestamps = null; | ||
61 | - this.linkTombstones = null; | ||
62 | - } | ||
63 | -} |
core/store/dist/src/main/java/org/onosproject/store/link/impl/LinkFragmentId.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import java.util.Objects; | ||
19 | - | ||
20 | -import org.onosproject.net.LinkKey; | ||
21 | -import org.onosproject.net.provider.ProviderId; | ||
22 | - | ||
23 | -import com.google.common.base.MoreObjects; | ||
24 | - | ||
25 | -/** | ||
26 | - * Identifier for LinkDescription from a Provider. | ||
27 | - */ | ||
28 | -public final class LinkFragmentId { | ||
29 | - public final ProviderId providerId; | ||
30 | - public final LinkKey linkKey; | ||
31 | - | ||
32 | - public LinkFragmentId(LinkKey linkKey, ProviderId providerId) { | ||
33 | - this.providerId = providerId; | ||
34 | - this.linkKey = linkKey; | ||
35 | - } | ||
36 | - | ||
37 | - public LinkKey linkKey() { | ||
38 | - return linkKey; | ||
39 | - } | ||
40 | - | ||
41 | - public ProviderId providerId() { | ||
42 | - return providerId; | ||
43 | - } | ||
44 | - | ||
45 | - @Override | ||
46 | - public int hashCode() { | ||
47 | - return Objects.hash(providerId, linkKey); | ||
48 | - } | ||
49 | - | ||
50 | - @Override | ||
51 | - public boolean equals(Object obj) { | ||
52 | - if (this == obj) { | ||
53 | - return true; | ||
54 | - } | ||
55 | - if (!(obj instanceof LinkFragmentId)) { | ||
56 | - return false; | ||
57 | - } | ||
58 | - LinkFragmentId that = (LinkFragmentId) obj; | ||
59 | - return Objects.equals(this.linkKey, that.linkKey) && | ||
60 | - Objects.equals(this.providerId, that.providerId); | ||
61 | - } | ||
62 | - | ||
63 | - @Override | ||
64 | - public String toString() { | ||
65 | - return MoreObjects.toStringHelper(getClass()) | ||
66 | - .add("providerId", providerId) | ||
67 | - .add("linkKey", linkKey) | ||
68 | - .toString(); | ||
69 | - } | ||
70 | - | ||
71 | - // for serializer | ||
72 | - @SuppressWarnings("unused") | ||
73 | - private LinkFragmentId() { | ||
74 | - this.providerId = null; | ||
75 | - this.linkKey = null; | ||
76 | - } | ||
77 | -} |
core/store/dist/src/main/java/org/onosproject/store/link/impl/LinkInjectedEvent.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import com.google.common.base.MoreObjects; | ||
19 | -import org.onosproject.net.link.LinkDescription; | ||
20 | -import org.onosproject.net.provider.ProviderId; | ||
21 | - | ||
22 | -public class LinkInjectedEvent { | ||
23 | - | ||
24 | - ProviderId providerId; | ||
25 | - LinkDescription linkDescription; | ||
26 | - | ||
27 | - public LinkInjectedEvent(ProviderId providerId, LinkDescription linkDescription) { | ||
28 | - this.providerId = providerId; | ||
29 | - this.linkDescription = linkDescription; | ||
30 | - } | ||
31 | - | ||
32 | - public ProviderId providerId() { | ||
33 | - return providerId; | ||
34 | - } | ||
35 | - | ||
36 | - public LinkDescription linkDescription() { | ||
37 | - return linkDescription; | ||
38 | - } | ||
39 | - | ||
40 | - @Override | ||
41 | - public String toString() { | ||
42 | - return MoreObjects.toStringHelper(getClass()) | ||
43 | - .add("providerId", providerId) | ||
44 | - .add("linkDescription", linkDescription) | ||
45 | - .toString(); | ||
46 | - } | ||
47 | - | ||
48 | - // for serializer | ||
49 | - protected LinkInjectedEvent() { | ||
50 | - this.providerId = null; | ||
51 | - this.linkDescription = null; | ||
52 | - } | ||
53 | -} |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Implementation of distributed link store using p2p synchronization protocol. | 18 | + * Implementation of distributed link store using eventually consistent map primitive. |
19 | */ | 19 | */ |
20 | package org.onosproject.store.link.impl; | 20 | package org.onosproject.store.link.impl; | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValue.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.mastership.impl; | ||
17 | - | ||
18 | -import static org.onosproject.net.MastershipRole.MASTER; | ||
19 | -import static org.onosproject.net.MastershipRole.NONE; | ||
20 | -import static org.onosproject.net.MastershipRole.STANDBY; | ||
21 | - | ||
22 | -import java.util.Collections; | ||
23 | -import java.util.EnumMap; | ||
24 | -import java.util.LinkedList; | ||
25 | -import java.util.List; | ||
26 | -import java.util.Map; | ||
27 | - | ||
28 | -import org.onosproject.cluster.NodeId; | ||
29 | -import org.onosproject.cluster.RoleInfo; | ||
30 | -import org.onosproject.net.MastershipRole; | ||
31 | - | ||
32 | -import com.google.common.base.MoreObjects; | ||
33 | -import com.google.common.base.MoreObjects.ToStringHelper; | ||
34 | -import com.google.common.collect.Lists; | ||
35 | - | ||
36 | -/** | ||
37 | - * A structure that holds node mastership roles associated with a | ||
38 | - * {@link org.onosproject.net.DeviceId}. This structure needs to be locked through IMap. | ||
39 | - */ | ||
40 | -final class RoleValue { | ||
41 | - | ||
42 | - protected final Map<MastershipRole, List<NodeId>> value = new EnumMap<>(MastershipRole.class); | ||
43 | - | ||
44 | - /** | ||
45 | - * Constructs empty RoleValue. | ||
46 | - */ | ||
47 | - public RoleValue() { | ||
48 | - value.put(MastershipRole.MASTER, new LinkedList<>()); | ||
49 | - value.put(MastershipRole.STANDBY, new LinkedList<>()); | ||
50 | - value.put(MastershipRole.NONE, new LinkedList<>()); | ||
51 | - } | ||
52 | - | ||
53 | - /** | ||
54 | - * Constructs copy of specified RoleValue. | ||
55 | - * | ||
56 | - * @param original original to create copy from | ||
57 | - */ | ||
58 | - public RoleValue(final RoleValue original) { | ||
59 | - value.put(MASTER, Lists.newLinkedList(original.value.get(MASTER))); | ||
60 | - value.put(STANDBY, Lists.newLinkedList(original.value.get(STANDBY))); | ||
61 | - value.put(NONE, Lists.newLinkedList(original.value.get(NONE))); | ||
62 | - } | ||
63 | - | ||
64 | - // exposing internals for serialization purpose only | ||
65 | - Map<MastershipRole, List<NodeId>> value() { | ||
66 | - return Collections.unmodifiableMap(value); | ||
67 | - } | ||
68 | - | ||
69 | - public List<NodeId> nodesOfRole(MastershipRole type) { | ||
70 | - return value.get(type); | ||
71 | - } | ||
72 | - | ||
73 | - /** | ||
74 | - * Returns the first node to match the MastershipRole, or if there | ||
75 | - * are none, null. | ||
76 | - * | ||
77 | - * @param type the role | ||
78 | - * @return a node ID or null | ||
79 | - */ | ||
80 | - public NodeId get(MastershipRole type) { | ||
81 | - return value.get(type).isEmpty() ? null : value.get(type).get(0); | ||
82 | - } | ||
83 | - | ||
84 | - public boolean contains(MastershipRole type, NodeId nodeId) { | ||
85 | - return value.get(type).contains(nodeId); | ||
86 | - } | ||
87 | - | ||
88 | - public MastershipRole getRole(NodeId nodeId) { | ||
89 | - if (contains(MASTER, nodeId)) { | ||
90 | - return MASTER; | ||
91 | - } | ||
92 | - if (contains(STANDBY, nodeId)) { | ||
93 | - return STANDBY; | ||
94 | - } | ||
95 | - return NONE; | ||
96 | - } | ||
97 | - | ||
98 | - /** | ||
99 | - * Associates a node to a certain role. | ||
100 | - * | ||
101 | - * @param type the role | ||
102 | - * @param nodeId the node ID of the node to associate | ||
103 | - * @return true if modified | ||
104 | - */ | ||
105 | - public boolean add(MastershipRole type, NodeId nodeId) { | ||
106 | - List<NodeId> nodes = value.get(type); | ||
107 | - | ||
108 | - if (!nodes.contains(nodeId)) { | ||
109 | - return nodes.add(nodeId); | ||
110 | - } | ||
111 | - return false; | ||
112 | - } | ||
113 | - | ||
114 | - /** | ||
115 | - * Removes a node from a certain role. | ||
116 | - * | ||
117 | - * @param type the role | ||
118 | - * @param nodeId the ID of the node to remove | ||
119 | - * @return true if modified | ||
120 | - */ | ||
121 | - public boolean remove(MastershipRole type, NodeId nodeId) { | ||
122 | - List<NodeId> nodes = value.get(type); | ||
123 | - if (!nodes.isEmpty()) { | ||
124 | - return nodes.remove(nodeId); | ||
125 | - } else { | ||
126 | - return false; | ||
127 | - } | ||
128 | - } | ||
129 | - | ||
130 | - /** | ||
131 | - * Reassigns a node from one role to another. If the node was not of the | ||
132 | - * old role, it will still be assigned the new role. | ||
133 | - * | ||
134 | - * @param nodeId the Node ID of node changing roles | ||
135 | - * @param from the old role | ||
136 | - * @param to the new role | ||
137 | - * @return true if modified | ||
138 | - */ | ||
139 | - public boolean reassign(NodeId nodeId, MastershipRole from, MastershipRole to) { | ||
140 | - boolean modified = remove(from, nodeId); | ||
141 | - modified |= add(to, nodeId); | ||
142 | - return modified; | ||
143 | - } | ||
144 | - | ||
145 | - /** | ||
146 | - * Replaces a node in one role with another node. Even if there is no node to | ||
147 | - * replace, the new node is associated to the role. | ||
148 | - * | ||
149 | - * @param from the old NodeId to replace | ||
150 | - * @param to the new NodeId | ||
151 | - * @param type the role associated with the old NodeId | ||
152 | - * @return true if modified | ||
153 | - */ | ||
154 | - public boolean replace(NodeId from, NodeId to, MastershipRole type) { | ||
155 | - boolean modified = remove(type, from); | ||
156 | - modified |= add(type, to); | ||
157 | - return modified; | ||
158 | - } | ||
159 | - | ||
160 | - /** | ||
161 | - * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups | ||
162 | - * may be empty, so the values should be checked for safety. | ||
163 | - * | ||
164 | - * @return the RoleInfo. | ||
165 | - */ | ||
166 | - public RoleInfo roleInfo() { | ||
167 | - return new RoleInfo( | ||
168 | - get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY)); | ||
169 | - } | ||
170 | - | ||
171 | - @Override | ||
172 | - public String toString() { | ||
173 | - ToStringHelper helper = MoreObjects.toStringHelper(this.getClass()); | ||
174 | - for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) { | ||
175 | - helper.add(el.getKey().toString(), el.getValue()); | ||
176 | - } | ||
177 | - return helper.toString(); | ||
178 | - } | ||
179 | -} |
core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValueSerializer.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.mastership.impl; | ||
17 | - | ||
18 | -import java.util.List; | ||
19 | -import java.util.Map; | ||
20 | - | ||
21 | -import org.onosproject.cluster.NodeId; | ||
22 | -import org.onosproject.net.MastershipRole; | ||
23 | - | ||
24 | -import com.esotericsoftware.kryo.Kryo; | ||
25 | -import com.esotericsoftware.kryo.Serializer; | ||
26 | -import com.esotericsoftware.kryo.io.Input; | ||
27 | -import com.esotericsoftware.kryo.io.Output; | ||
28 | - | ||
29 | -/** | ||
30 | - * Serializer for RoleValues used by {@link org.onosproject.mastership.MastershipStore}. | ||
31 | - */ | ||
32 | -public class RoleValueSerializer extends Serializer<RoleValue> { | ||
33 | - | ||
34 | - //RoleValues are assumed to hold a Map of MastershipRoles (an enum) | ||
35 | - //to a List of NodeIds. | ||
36 | - | ||
37 | - @Override | ||
38 | - public RoleValue read(Kryo kryo, Input input, Class<RoleValue> type) { | ||
39 | - RoleValue rv = new RoleValue(); | ||
40 | - int size = input.readInt(); | ||
41 | - for (int i = 0; i < size; i++) { | ||
42 | - MastershipRole role = MastershipRole.values()[input.readInt()]; | ||
43 | - int s = input.readInt(); | ||
44 | - for (int j = 0; j < s; j++) { | ||
45 | - rv.add(role, new NodeId(input.readString())); | ||
46 | - } | ||
47 | - } | ||
48 | - return rv; | ||
49 | - } | ||
50 | - | ||
51 | - @Override | ||
52 | - public void write(Kryo kryo, Output output, RoleValue type) { | ||
53 | - final Map<MastershipRole, List<NodeId>> map = type.value(); | ||
54 | - output.writeInt(map.size()); | ||
55 | - | ||
56 | - for (Map.Entry<MastershipRole, List<NodeId>> el : map.entrySet()) { | ||
57 | - output.writeInt(el.getKey().ordinal()); | ||
58 | - | ||
59 | - List<NodeId> nodes = el.getValue(); | ||
60 | - output.writeInt(nodes.size()); | ||
61 | - for (NodeId n : nodes) { | ||
62 | - output.writeString(n.toString()); | ||
63 | - } | ||
64 | - } | ||
65 | - } | ||
66 | - | ||
67 | -} |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Implementation of a distributed mastership store using Hazelcast. | 18 | + * Implementation of a distributed mastership store. |
19 | */ | 19 | */ |
20 | package org.onosproject.store.mastership.impl; | 20 | package org.onosproject.store.mastership.impl; | ... | ... |
1 | -/* | ||
2 | - * Copyright 2015-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.serializers.custom; | ||
17 | - | ||
18 | -import org.onosproject.cluster.NodeId; | ||
19 | -import org.onosproject.store.cluster.messaging.ClusterMessage; | ||
20 | -import org.onosproject.store.cluster.messaging.MessageSubject; | ||
21 | -import com.esotericsoftware.kryo.Kryo; | ||
22 | -import com.esotericsoftware.kryo.Serializer; | ||
23 | -import com.esotericsoftware.kryo.io.Input; | ||
24 | -import com.esotericsoftware.kryo.io.Output; | ||
25 | - | ||
26 | -public final class ClusterMessageSerializer extends Serializer<ClusterMessage> { | ||
27 | - | ||
28 | - /** | ||
29 | - * Creates a serializer for {@link ClusterMessage}. | ||
30 | - */ | ||
31 | - public ClusterMessageSerializer() { | ||
32 | - // does not accept null | ||
33 | - super(false); | ||
34 | - } | ||
35 | - | ||
36 | - @Override | ||
37 | - public void write(Kryo kryo, Output output, ClusterMessage message) { | ||
38 | - kryo.writeClassAndObject(output, message.sender()); | ||
39 | - kryo.writeClassAndObject(output, message.subject()); | ||
40 | - output.writeInt(message.payload().length); | ||
41 | - output.writeBytes(message.payload()); | ||
42 | - } | ||
43 | - | ||
44 | - @Override | ||
45 | - public ClusterMessage read(Kryo kryo, Input input, | ||
46 | - Class<ClusterMessage> type) { | ||
47 | - NodeId sender = (NodeId) kryo.readClassAndObject(input); | ||
48 | - MessageSubject subject = (MessageSubject) kryo.readClassAndObject(input); | ||
49 | - int payloadSize = input.readInt(); | ||
50 | - byte[] payload = input.readBytes(payloadSize); | ||
51 | - return new ClusterMessage(sender, subject, payload); | ||
52 | - } | ||
53 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.serializers.custom; | ||
17 | - | ||
18 | -import org.onosproject.store.cluster.messaging.MessageSubject; | ||
19 | - | ||
20 | -import com.esotericsoftware.kryo.Kryo; | ||
21 | -import com.esotericsoftware.kryo.Serializer; | ||
22 | -import com.esotericsoftware.kryo.io.Input; | ||
23 | -import com.esotericsoftware.kryo.io.Output; | ||
24 | - | ||
25 | -public final class MessageSubjectSerializer extends Serializer<MessageSubject> { | ||
26 | - | ||
27 | - /** | ||
28 | - * Creates a serializer for {@link MessageSubject}. | ||
29 | - */ | ||
30 | - public MessageSubjectSerializer() { | ||
31 | - // non-null, immutable | ||
32 | - super(false, true); | ||
33 | - } | ||
34 | - | ||
35 | - | ||
36 | - @Override | ||
37 | - public void write(Kryo kryo, Output output, MessageSubject object) { | ||
38 | - output.writeString(object.value()); | ||
39 | - } | ||
40 | - | ||
41 | - @Override | ||
42 | - public MessageSubject read(Kryo kryo, Input input, | ||
43 | - Class<MessageSubject> type) { | ||
44 | - return new MessageSubject(input.readString()); | ||
45 | - } | ||
46 | -} |
... | @@ -15,8 +15,6 @@ | ... | @@ -15,8 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Cluster messaging and distributed store serializers. | 18 | + * Distributed store serializers. |
19 | */ | 19 | */ |
20 | -//FIXME what is the right name for this package? | ||
21 | -//FIXME can this be moved to onos-core-serializers? | ||
22 | package org.onosproject.store.serializers.custom; | 20 | package org.onosproject.store.serializers.custom; | ... | ... |
... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
17 | package org.onosproject.store.statistic.impl; | 17 | package org.onosproject.store.statistic.impl; |
18 | 18 | ||
19 | import com.google.common.base.Objects; | 19 | import com.google.common.base.Objects; |
20 | + | ||
20 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
21 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
22 | import org.apache.felix.scr.annotations.Deactivate; | 23 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -38,6 +39,7 @@ import org.onosproject.net.flow.instructions.Instruction; | ... | @@ -38,6 +39,7 @@ import org.onosproject.net.flow.instructions.Instruction; |
38 | import org.onosproject.net.flow.instructions.Instructions; | 39 | import org.onosproject.net.flow.instructions.Instructions; |
39 | import org.onosproject.net.statistic.FlowStatisticStore; | 40 | import org.onosproject.net.statistic.FlowStatisticStore; |
40 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 41 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
42 | +import org.onosproject.store.cluster.messaging.MessageSubject; | ||
41 | import org.onosproject.store.serializers.KryoNamespaces; | 43 | import org.onosproject.store.serializers.KryoNamespaces; |
42 | import org.onosproject.store.serializers.StoreSerializer; | 44 | import org.onosproject.store.serializers.StoreSerializer; |
43 | import org.osgi.service.component.ComponentContext; | 45 | import org.osgi.service.component.ComponentContext; |
... | @@ -59,8 +61,6 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -59,8 +61,6 @@ import static com.google.common.base.Preconditions.checkArgument; |
59 | import static com.google.common.base.Strings.isNullOrEmpty; | 61 | import static com.google.common.base.Strings.isNullOrEmpty; |
60 | import static org.onlab.util.Tools.get; | 62 | import static org.onlab.util.Tools.get; |
61 | import static org.onlab.util.Tools.groupedThreads; | 63 | import static org.onlab.util.Tools.groupedThreads; |
62 | -import static org.onosproject.store.statistic.impl.StatisticStoreMessageSubjects.GET_CURRENT; | ||
63 | -import static org.onosproject.store.statistic.impl.StatisticStoreMessageSubjects.GET_PREVIOUS; | ||
64 | import static org.slf4j.LoggerFactory.getLogger; | 64 | import static org.slf4j.LoggerFactory.getLogger; |
65 | 65 | ||
66 | /** | 66 | /** |
... | @@ -89,6 +89,9 @@ public class DistributedFlowStatisticStore implements FlowStatisticStore { | ... | @@ -89,6 +89,9 @@ public class DistributedFlowStatisticStore implements FlowStatisticStore { |
89 | private Map<ConnectPoint, Set<FlowEntry>> current = | 89 | private Map<ConnectPoint, Set<FlowEntry>> current = |
90 | new ConcurrentHashMap<>(); | 90 | new ConcurrentHashMap<>(); |
91 | 91 | ||
92 | + public static final MessageSubject GET_CURRENT = new MessageSubject("peer-return-current"); | ||
93 | + public static final MessageSubject GET_PREVIOUS = new MessageSubject("peer-return-previous"); | ||
94 | + | ||
92 | protected static final StoreSerializer SERIALIZER = StoreSerializer.using(KryoNamespaces.API); | 95 | protected static final StoreSerializer SERIALIZER = StoreSerializer.using(KryoNamespaces.API); |
93 | 96 | ||
94 | private NodeId local; | 97 | private NodeId local; | ... | ... |
... | @@ -38,6 +38,7 @@ import org.onosproject.net.flow.instructions.Instruction; | ... | @@ -38,6 +38,7 @@ import org.onosproject.net.flow.instructions.Instruction; |
38 | import org.onosproject.net.flow.instructions.Instructions; | 38 | import org.onosproject.net.flow.instructions.Instructions; |
39 | import org.onosproject.net.statistic.StatisticStore; | 39 | import org.onosproject.net.statistic.StatisticStore; |
40 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 40 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
41 | +import org.onosproject.store.cluster.messaging.MessageSubject; | ||
41 | import org.onosproject.store.serializers.KryoNamespaces; | 42 | import org.onosproject.store.serializers.KryoNamespaces; |
42 | import org.onosproject.store.serializers.StoreSerializer; | 43 | import org.onosproject.store.serializers.StoreSerializer; |
43 | import org.osgi.service.component.ComponentContext; | 44 | import org.osgi.service.component.ComponentContext; |
... | @@ -59,8 +60,6 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -59,8 +60,6 @@ import static com.google.common.base.Preconditions.checkArgument; |
59 | import static com.google.common.base.Strings.isNullOrEmpty; | 60 | import static com.google.common.base.Strings.isNullOrEmpty; |
60 | import static org.onlab.util.Tools.get; | 61 | import static org.onlab.util.Tools.get; |
61 | import static org.onlab.util.Tools.groupedThreads; | 62 | import static org.onlab.util.Tools.groupedThreads; |
62 | -import static org.onosproject.store.statistic.impl.StatisticStoreMessageSubjects.GET_CURRENT; | ||
63 | -import static org.onosproject.store.statistic.impl.StatisticStoreMessageSubjects.GET_PREVIOUS; | ||
64 | import static org.slf4j.LoggerFactory.getLogger; | 63 | import static org.slf4j.LoggerFactory.getLogger; |
65 | 64 | ||
66 | 65 | ||
... | @@ -85,6 +84,9 @@ public class DistributedStatisticStore implements StatisticStore { | ... | @@ -85,6 +84,9 @@ public class DistributedStatisticStore implements StatisticStore { |
85 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 84 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
86 | protected ClusterService clusterService; | 85 | protected ClusterService clusterService; |
87 | 86 | ||
87 | + public static final MessageSubject GET_CURRENT = new MessageSubject("peer-return-current"); | ||
88 | + public static final MessageSubject GET_PREVIOUS = new MessageSubject("peer-return-previous"); | ||
89 | + | ||
88 | private Map<ConnectPoint, InternalStatisticRepresentation> representations = | 90 | private Map<ConnectPoint, InternalStatisticRepresentation> representations = |
89 | new ConcurrentHashMap<>(); | 91 | new ConcurrentHashMap<>(); |
90 | 92 | ... | ... |
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.statistic.impl; | ||
17 | - | ||
18 | -import org.onosproject.store.cluster.messaging.MessageSubject; | ||
19 | - | ||
20 | -/** | ||
21 | - * MessageSubjects used by DistributedStatisticStore peer-peer communication. | ||
22 | - */ | ||
23 | -public final class StatisticStoreMessageSubjects { | ||
24 | - private StatisticStoreMessageSubjects() {} | ||
25 | - public static final MessageSubject GET_CURRENT = | ||
26 | - new MessageSubject("peer-return-current"); | ||
27 | - public static final MessageSubject GET_PREVIOUS = | ||
28 | - new MessageSubject("peer-return-previous"); | ||
29 | - | ||
30 | -} |
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.cluster.messaging.impl; | ||
17 | - | ||
18 | -import org.junit.After; | ||
19 | -import org.junit.Before; | ||
20 | -import org.junit.Ignore; | ||
21 | -import org.junit.Test; | ||
22 | -import org.onosproject.cluster.DefaultControllerNode; | ||
23 | -import org.onosproject.cluster.NodeId; | ||
24 | -import org.onosproject.store.cluster.impl.ClusterNodesDelegate; | ||
25 | -import org.onlab.packet.IpAddress; | ||
26 | - | ||
27 | -import java.util.concurrent.CountDownLatch; | ||
28 | -import java.util.concurrent.TimeUnit; | ||
29 | - | ||
30 | -import static org.junit.Assert.assertEquals; | ||
31 | -import static org.junit.Assert.assertTrue; | ||
32 | - | ||
33 | -/** | ||
34 | - * Tests of the cluster communication manager. | ||
35 | - */ | ||
36 | -public class ClusterCommunicationManagerTest { | ||
37 | - | ||
38 | - private static final NodeId N1 = new NodeId("n1"); | ||
39 | - private static final NodeId N2 = new NodeId("n2"); | ||
40 | - | ||
41 | - private static final int P1 = 9881; | ||
42 | - private static final int P2 = 9882; | ||
43 | - | ||
44 | - private static final IpAddress IP = IpAddress.valueOf("127.0.0.1"); | ||
45 | - | ||
46 | - private ClusterCommunicationManager ccm1; | ||
47 | - private ClusterCommunicationManager ccm2; | ||
48 | - | ||
49 | - private TestDelegate cnd1 = new TestDelegate(); | ||
50 | - private TestDelegate cnd2 = new TestDelegate(); | ||
51 | - | ||
52 | - private DefaultControllerNode node1 = new DefaultControllerNode(N1, IP, P1); | ||
53 | - private DefaultControllerNode node2 = new DefaultControllerNode(N2, IP, P2); | ||
54 | - | ||
55 | - @Before | ||
56 | - public void setUp() throws Exception { | ||
57 | - | ||
58 | - NettyMessagingManager messagingService = new NettyMessagingManager(); | ||
59 | - messagingService.activate(); | ||
60 | - | ||
61 | - ccm1 = new ClusterCommunicationManager(); | ||
62 | - ccm1.activate(); | ||
63 | - | ||
64 | - ccm2 = new ClusterCommunicationManager(); | ||
65 | - ccm2.activate(); | ||
66 | - | ||
67 | -// ccm1.initialize(node1, cnd1); | ||
68 | -// ccm2.initialize(node2, cnd2); | ||
69 | - } | ||
70 | - | ||
71 | - @After | ||
72 | - public void tearDown() { | ||
73 | - ccm1.deactivate(); | ||
74 | - ccm2.deactivate(); | ||
75 | - } | ||
76 | - | ||
77 | - @Ignore("FIXME: failing randomly?") | ||
78 | - @Test | ||
79 | - public void connect() throws Exception { | ||
80 | - cnd1.latch = new CountDownLatch(1); | ||
81 | - cnd2.latch = new CountDownLatch(1); | ||
82 | - | ||
83 | -// ccm1.addNode(node2); | ||
84 | - validateDelegateEvent(cnd1, Op.DETECTED, node2.id()); | ||
85 | - validateDelegateEvent(cnd2, Op.DETECTED, node1.id()); | ||
86 | - } | ||
87 | - | ||
88 | - @Test | ||
89 | - @Ignore | ||
90 | - public void disconnect() throws Exception { | ||
91 | - cnd1.latch = new CountDownLatch(1); | ||
92 | - cnd2.latch = new CountDownLatch(1); | ||
93 | - | ||
94 | -// ccm1.addNode(node2); | ||
95 | - validateDelegateEvent(cnd1, Op.DETECTED, node2.id()); | ||
96 | - validateDelegateEvent(cnd2, Op.DETECTED, node1.id()); | ||
97 | - | ||
98 | - cnd1.latch = new CountDownLatch(1); | ||
99 | - cnd2.latch = new CountDownLatch(1); | ||
100 | - ccm1.deactivate(); | ||
101 | -// | ||
102 | -// validateDelegateEvent(cnd2, Op.VANISHED, node1.id()); | ||
103 | - } | ||
104 | - | ||
105 | - private void validateDelegateEvent(TestDelegate delegate, Op op, NodeId nodeId) | ||
106 | - throws InterruptedException { | ||
107 | - assertTrue("did not connect in time", delegate.latch.await(2500, TimeUnit.MILLISECONDS)); | ||
108 | - assertEquals("incorrect event", op, delegate.op); | ||
109 | - assertEquals("incorrect event node", nodeId, delegate.nodeId); | ||
110 | - } | ||
111 | - | ||
112 | - enum Op { DETECTED, VANISHED, REMOVED } | ||
113 | - | ||
114 | - private class TestDelegate implements ClusterNodesDelegate { | ||
115 | - | ||
116 | - Op op; | ||
117 | - CountDownLatch latch; | ||
118 | - NodeId nodeId; | ||
119 | - | ||
120 | - @Override | ||
121 | - public DefaultControllerNode nodeDetected(NodeId nodeId, IpAddress ip, int tcpPort) { | ||
122 | - latch(nodeId, Op.DETECTED); | ||
123 | - return new DefaultControllerNode(nodeId, ip, tcpPort); | ||
124 | - } | ||
125 | - | ||
126 | - @Override | ||
127 | - public void nodeVanished(NodeId nodeId) { | ||
128 | - latch(nodeId, Op.VANISHED); | ||
129 | - } | ||
130 | - | ||
131 | - @Override | ||
132 | - public void nodeRemoved(NodeId nodeId) { | ||
133 | - latch(nodeId, Op.REMOVED); | ||
134 | - } | ||
135 | - | ||
136 | - private void latch(NodeId nodeId, Op op) { | ||
137 | - this.op = op; | ||
138 | - this.nodeId = nodeId; | ||
139 | - latch.countDown(); | ||
140 | - } | ||
141 | - } | ||
142 | -} |
... | @@ -17,7 +17,6 @@ package org.onosproject.store.link.impl; | ... | @@ -17,7 +17,6 @@ package org.onosproject.store.link.impl; |
17 | 17 | ||
18 | import com.google.common.collect.Iterables; | 18 | import com.google.common.collect.Iterables; |
19 | 19 | ||
20 | -import org.easymock.Capture; | ||
21 | import org.junit.After; | 20 | import org.junit.After; |
22 | import org.junit.AfterClass; | 21 | import org.junit.AfterClass; |
23 | import org.junit.Before; | 22 | import org.junit.Before; |
... | @@ -59,8 +58,6 @@ import java.util.concurrent.CountDownLatch; | ... | @@ -59,8 +58,6 @@ import java.util.concurrent.CountDownLatch; |
59 | import java.util.concurrent.ExecutorService; | 58 | import java.util.concurrent.ExecutorService; |
60 | import java.util.concurrent.TimeUnit; | 59 | import java.util.concurrent.TimeUnit; |
61 | import java.util.concurrent.atomic.AtomicLong; | 60 | import java.util.concurrent.atomic.AtomicLong; |
62 | -import java.util.function.Function; | ||
63 | - | ||
64 | import static org.easymock.EasyMock.*; | 61 | import static org.easymock.EasyMock.*; |
65 | import static org.junit.Assert.*; | 62 | import static org.junit.Assert.*; |
66 | import static org.onosproject.cluster.ControllerNode.State.ACTIVE; | 63 | import static org.onosproject.cluster.ControllerNode.State.ACTIVE; |
... | @@ -76,7 +73,8 @@ import static org.onosproject.net.link.LinkEvent.Type.LINK_UPDATED; | ... | @@ -76,7 +73,8 @@ import static org.onosproject.net.link.LinkEvent.Type.LINK_UPDATED; |
76 | /** | 73 | /** |
77 | * Test of the GossipLinkStoreTest implementation. | 74 | * Test of the GossipLinkStoreTest implementation. |
78 | */ | 75 | */ |
79 | -public class GossipLinkStoreTest { | 76 | +@Ignore |
77 | +public class ECLinkStoreTest { | ||
80 | 78 | ||
81 | private static final ProviderId PID = new ProviderId("of", "foo"); | 79 | private static final ProviderId PID = new ProviderId("of", "foo"); |
82 | private static final ProviderId PIDA = new ProviderId("of", "bar", true); | 80 | private static final ProviderId PIDA = new ProviderId("of", "bar", true); |
... | @@ -114,10 +112,9 @@ public class GossipLinkStoreTest { | ... | @@ -114,10 +112,9 @@ public class GossipLinkStoreTest { |
114 | private static final ControllerNode ONOS2 = | 112 | private static final ControllerNode ONOS2 = |
115 | new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.0.2")); | 113 | new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.0.2")); |
116 | 114 | ||
117 | - private GossipLinkStore linkStoreImpl; | 115 | + private ECLinkStore linkStoreImpl; |
118 | private LinkStore linkStore; | 116 | private LinkStore linkStore; |
119 | 117 | ||
120 | - private final AtomicLong ticker = new AtomicLong(); | ||
121 | private DeviceClockService deviceClockService; | 118 | private DeviceClockService deviceClockService; |
122 | private ClusterCommunicationService clusterCommunicator; | 119 | private ClusterCommunicationService clusterCommunicator; |
123 | 120 | ||
... | @@ -139,7 +136,7 @@ public class GossipLinkStoreTest { | ... | @@ -139,7 +136,7 @@ public class GossipLinkStoreTest { |
139 | expectLastCall().anyTimes(); | 136 | expectLastCall().anyTimes(); |
140 | replay(clusterCommunicator); | 137 | replay(clusterCommunicator); |
141 | 138 | ||
142 | - linkStoreImpl = new GossipLinkStore(); | 139 | + linkStoreImpl = new ECLinkStore(); |
143 | linkStoreImpl.deviceClockService = deviceClockService; | 140 | linkStoreImpl.deviceClockService = deviceClockService; |
144 | linkStoreImpl.clusterCommunicator = clusterCommunicator; | 141 | linkStoreImpl.clusterCommunicator = clusterCommunicator; |
145 | linkStoreImpl.clusterService = new TestClusterService(); | 142 | linkStoreImpl.clusterService = new TestClusterService(); |
... | @@ -163,28 +160,10 @@ public class GossipLinkStoreTest { | ... | @@ -163,28 +160,10 @@ public class GossipLinkStoreTest { |
163 | SparseAnnotations... annotations) { | 160 | SparseAnnotations... annotations) { |
164 | ConnectPoint src = new ConnectPoint(srcId, srcNum); | 161 | ConnectPoint src = new ConnectPoint(srcId, srcNum); |
165 | ConnectPoint dst = new ConnectPoint(dstId, dstNum); | 162 | ConnectPoint dst = new ConnectPoint(dstId, dstNum); |
166 | - reset(clusterCommunicator); | ||
167 | - clusterCommunicator.<InternalLinkEvent>broadcast( | ||
168 | - anyObject(InternalLinkEvent.class), anyObject(MessageSubject.class), anyObject(Function.class)); | ||
169 | - expectLastCall().anyTimes(); | ||
170 | - replay(clusterCommunicator); | ||
171 | linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type, annotations)); | 163 | linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type, annotations)); |
172 | verify(clusterCommunicator); | 164 | verify(clusterCommunicator); |
173 | } | 165 | } |
174 | 166 | ||
175 | - private <T> void resetCommunicatorExpectingSingleBroadcast( | ||
176 | - Capture<T> message, | ||
177 | - Capture<MessageSubject> subject, | ||
178 | - Capture<Function<T, byte[]>> encoder) { | ||
179 | - message.reset(); | ||
180 | - subject.reset(); | ||
181 | - encoder.reset(); | ||
182 | - reset(clusterCommunicator); | ||
183 | - clusterCommunicator.broadcast(capture(message), capture(subject), capture(encoder)); | ||
184 | - expectLastCall().once(); | ||
185 | - replay(clusterCommunicator); | ||
186 | - } | ||
187 | - | ||
188 | private void putLink(LinkKey key, Type type, SparseAnnotations... annotations) { | 167 | private void putLink(LinkKey key, Type type, SparseAnnotations... annotations) { |
189 | putLink(key.src().deviceId(), key.src().port(), | 168 | putLink(key.src().deviceId(), key.src().port(), |
190 | key.dst().deviceId(), key.dst().port(), | 169 | key.dst().deviceId(), key.dst().port(), |
... | @@ -358,57 +337,26 @@ public class GossipLinkStoreTest { | ... | @@ -358,57 +337,26 @@ public class GossipLinkStoreTest { |
358 | ConnectPoint src = new ConnectPoint(DID1, P1); | 337 | ConnectPoint src = new ConnectPoint(DID1, P1); |
359 | ConnectPoint dst = new ConnectPoint(DID2, P2); | 338 | ConnectPoint dst = new ConnectPoint(DID2, P2); |
360 | 339 | ||
361 | - Capture<InternalLinkEvent> message = new Capture<>(); | ||
362 | - Capture<MessageSubject> subject = new Capture<>(); | ||
363 | - Capture<Function<InternalLinkEvent, byte[]>> encoder = new Capture<>(); | ||
364 | - | ||
365 | - // add link | ||
366 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
367 | final DefaultLinkDescription linkDescription = new DefaultLinkDescription(src, dst, INDIRECT); | 340 | final DefaultLinkDescription linkDescription = new DefaultLinkDescription(src, dst, INDIRECT); |
368 | LinkEvent event = linkStore.createOrUpdateLink(PID, | 341 | LinkEvent event = linkStore.createOrUpdateLink(PID, |
369 | linkDescription); | 342 | linkDescription); |
370 | - verifyLinkBroadcastMessage(PID, NID1, src, dst, INDIRECT, message, subject, encoder); | ||
371 | 343 | ||
372 | assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject()); | 344 | assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject()); |
373 | assertEquals(LINK_ADDED, event.type()); | 345 | assertEquals(LINK_ADDED, event.type()); |
374 | 346 | ||
375 | - // update link type | ||
376 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
377 | LinkEvent event2 = linkStore.createOrUpdateLink(PID, | 347 | LinkEvent event2 = linkStore.createOrUpdateLink(PID, |
378 | new DefaultLinkDescription(src, dst, DIRECT)); | 348 | new DefaultLinkDescription(src, dst, DIRECT)); |
379 | - verifyLinkBroadcastMessage(PID, NID1, src, dst, DIRECT, message, subject, encoder); | ||
380 | 349 | ||
381 | assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject()); | 350 | assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject()); |
382 | assertEquals(LINK_UPDATED, event2.type()); | 351 | assertEquals(LINK_UPDATED, event2.type()); |
383 | 352 | ||
384 | // no change | 353 | // no change |
385 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
386 | LinkEvent event3 = linkStore.createOrUpdateLink(PID, | 354 | LinkEvent event3 = linkStore.createOrUpdateLink(PID, |
387 | new DefaultLinkDescription(src, dst, DIRECT)); | 355 | new DefaultLinkDescription(src, dst, DIRECT)); |
388 | - verifyNoBroadcastMessage(message); | ||
389 | 356 | ||
390 | assertNull("No change event expected", event3); | 357 | assertNull("No change event expected", event3); |
391 | } | 358 | } |
392 | 359 | ||
393 | - private <T> void verifyNoBroadcastMessage(Capture<T> message) { | ||
394 | - assertFalse("No broadcast expected", message.hasCaptured()); | ||
395 | - } | ||
396 | - | ||
397 | - private void verifyLinkBroadcastMessage(ProviderId providerId, | ||
398 | - NodeId sender, | ||
399 | - ConnectPoint src, | ||
400 | - ConnectPoint dst, | ||
401 | - Type type, | ||
402 | - Capture<InternalLinkEvent> actualLinkEvent, | ||
403 | - Capture<MessageSubject> actualSubject, | ||
404 | - Capture<Function<InternalLinkEvent, byte[]>> actualEncoder) { | ||
405 | - verify(clusterCommunicator); | ||
406 | - assertTrue(actualLinkEvent.hasCaptured()); | ||
407 | - assertEquals(GossipLinkStoreMessageSubjects.LINK_UPDATE, actualSubject.getValue()); | ||
408 | - assertEquals(providerId, actualLinkEvent.getValue().providerId()); | ||
409 | - assertLinkDescriptionEquals(src, dst, type, actualLinkEvent.getValue().linkDescription().value()); | ||
410 | - } | ||
411 | - | ||
412 | private static void assertLinkDescriptionEquals(ConnectPoint src, | 360 | private static void assertLinkDescriptionEquals(ConnectPoint src, |
413 | ConnectPoint dst, | 361 | ConnectPoint dst, |
414 | Type type, | 362 | Type type, |
... | @@ -424,33 +372,23 @@ public class GossipLinkStoreTest { | ... | @@ -424,33 +372,23 @@ public class GossipLinkStoreTest { |
424 | ConnectPoint src = new ConnectPoint(DID1, P1); | 372 | ConnectPoint src = new ConnectPoint(DID1, P1); |
425 | ConnectPoint dst = new ConnectPoint(DID2, P2); | 373 | ConnectPoint dst = new ConnectPoint(DID2, P2); |
426 | 374 | ||
427 | - Capture<InternalLinkEvent> message = new Capture<>(); | ||
428 | - Capture<MessageSubject> subject = new Capture<>(); | ||
429 | - Capture<Function<InternalLinkEvent, byte[]>> encoder = new Capture<>(); | ||
430 | - | ||
431 | // add Ancillary link | 375 | // add Ancillary link |
432 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
433 | LinkEvent event = linkStore.createOrUpdateLink(PIDA, | 376 | LinkEvent event = linkStore.createOrUpdateLink(PIDA, |
434 | new DefaultLinkDescription(src, dst, INDIRECT, A1)); | 377 | new DefaultLinkDescription(src, dst, INDIRECT, A1)); |
435 | - verifyLinkBroadcastMessage(PIDA, NID1, src, dst, INDIRECT, message, subject, encoder); | ||
436 | 378 | ||
437 | assertNotNull("Ancillary only link is ignored", event); | 379 | assertNotNull("Ancillary only link is ignored", event); |
438 | 380 | ||
439 | // add Primary link | 381 | // add Primary link |
440 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
441 | LinkEvent event2 = linkStore.createOrUpdateLink(PID, | 382 | LinkEvent event2 = linkStore.createOrUpdateLink(PID, |
442 | new DefaultLinkDescription(src, dst, INDIRECT, A2)); | 383 | new DefaultLinkDescription(src, dst, INDIRECT, A2)); |
443 | - verifyLinkBroadcastMessage(PID, NID1, src, dst, INDIRECT, message, subject, encoder); | ||
444 | 384 | ||
445 | assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject()); | 385 | assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject()); |
446 | assertAnnotationsEquals(event2.subject().annotations(), A2, A1); | 386 | assertAnnotationsEquals(event2.subject().annotations(), A2, A1); |
447 | assertEquals(LINK_UPDATED, event2.type()); | 387 | assertEquals(LINK_UPDATED, event2.type()); |
448 | 388 | ||
449 | // update link type | 389 | // update link type |
450 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
451 | LinkEvent event3 = linkStore.createOrUpdateLink(PID, | 390 | LinkEvent event3 = linkStore.createOrUpdateLink(PID, |
452 | new DefaultLinkDescription(src, dst, DIRECT, A2)); | 391 | new DefaultLinkDescription(src, dst, DIRECT, A2)); |
453 | - verifyLinkBroadcastMessage(PID, NID1, src, dst, DIRECT, message, subject, encoder); | ||
454 | 392 | ||
455 | assertLink(DID1, P1, DID2, P2, DIRECT, event3.subject()); | 393 | assertLink(DID1, P1, DID2, P2, DIRECT, event3.subject()); |
456 | assertAnnotationsEquals(event3.subject().annotations(), A2, A1); | 394 | assertAnnotationsEquals(event3.subject().annotations(), A2, A1); |
... | @@ -458,38 +396,30 @@ public class GossipLinkStoreTest { | ... | @@ -458,38 +396,30 @@ public class GossipLinkStoreTest { |
458 | 396 | ||
459 | 397 | ||
460 | // no change | 398 | // no change |
461 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
462 | LinkEvent event4 = linkStore.createOrUpdateLink(PID, | 399 | LinkEvent event4 = linkStore.createOrUpdateLink(PID, |
463 | new DefaultLinkDescription(src, dst, DIRECT)); | 400 | new DefaultLinkDescription(src, dst, DIRECT)); |
464 | - verifyNoBroadcastMessage(message); | ||
465 | 401 | ||
466 | assertNull("No change event expected", event4); | 402 | assertNull("No change event expected", event4); |
467 | 403 | ||
468 | // update link annotation (Primary) | 404 | // update link annotation (Primary) |
469 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
470 | LinkEvent event5 = linkStore.createOrUpdateLink(PID, | 405 | LinkEvent event5 = linkStore.createOrUpdateLink(PID, |
471 | new DefaultLinkDescription(src, dst, DIRECT, A2_2)); | 406 | new DefaultLinkDescription(src, dst, DIRECT, A2_2)); |
472 | - verifyLinkBroadcastMessage(PID, NID1, src, dst, DIRECT, message, subject, encoder); | ||
473 | 407 | ||
474 | assertLink(DID1, P1, DID2, P2, DIRECT, event5.subject()); | 408 | assertLink(DID1, P1, DID2, P2, DIRECT, event5.subject()); |
475 | assertAnnotationsEquals(event5.subject().annotations(), A2, A2_2, A1); | 409 | assertAnnotationsEquals(event5.subject().annotations(), A2, A2_2, A1); |
476 | assertEquals(LINK_UPDATED, event5.type()); | 410 | assertEquals(LINK_UPDATED, event5.type()); |
477 | 411 | ||
478 | // update link annotation (Ancillary) | 412 | // update link annotation (Ancillary) |
479 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
480 | LinkEvent event6 = linkStore.createOrUpdateLink(PIDA, | 413 | LinkEvent event6 = linkStore.createOrUpdateLink(PIDA, |
481 | new DefaultLinkDescription(src, dst, DIRECT, A1_2)); | 414 | new DefaultLinkDescription(src, dst, DIRECT, A1_2)); |
482 | - verifyLinkBroadcastMessage(PIDA, NID1, src, dst, DIRECT, message, subject, encoder); | ||
483 | 415 | ||
484 | assertLink(DID1, P1, DID2, P2, DIRECT, event6.subject()); | 416 | assertLink(DID1, P1, DID2, P2, DIRECT, event6.subject()); |
485 | assertAnnotationsEquals(event6.subject().annotations(), A2, A2_2, A1, A1_2); | 417 | assertAnnotationsEquals(event6.subject().annotations(), A2, A2_2, A1, A1_2); |
486 | assertEquals(LINK_UPDATED, event6.type()); | 418 | assertEquals(LINK_UPDATED, event6.type()); |
487 | 419 | ||
488 | // update link type (Ancillary) : ignored | 420 | // update link type (Ancillary) : ignored |
489 | - resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); | ||
490 | LinkEvent event7 = linkStore.createOrUpdateLink(PIDA, | 421 | LinkEvent event7 = linkStore.createOrUpdateLink(PIDA, |
491 | new DefaultLinkDescription(src, dst, EDGE)); | 422 | new DefaultLinkDescription(src, dst, EDGE)); |
492 | - verifyNoBroadcastMessage(message); | ||
493 | assertNull("Ancillary change other than annotation is ignored", event7); | 423 | assertNull("Ancillary change other than annotation is ignored", event7); |
494 | } | 424 | } |
495 | 425 | ... | ... |
core/store/dist/src/test/java/org/onosproject/store/link/impl/LinkFragmentIdTest.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.link.impl; | ||
17 | - | ||
18 | -import static org.onosproject.net.DeviceId.deviceId; | ||
19 | - | ||
20 | -import org.junit.Test; | ||
21 | -import org.onosproject.net.ConnectPoint; | ||
22 | -import org.onosproject.net.DeviceId; | ||
23 | -import org.onosproject.net.LinkKey; | ||
24 | -import org.onosproject.net.PortNumber; | ||
25 | -import org.onosproject.net.provider.ProviderId; | ||
26 | -import com.google.common.testing.EqualsTester; | ||
27 | - | ||
28 | -public class LinkFragmentIdTest { | ||
29 | - | ||
30 | - private static final ProviderId PID = new ProviderId("of", "foo"); | ||
31 | - private static final ProviderId PIDA = new ProviderId("of", "bar", true); | ||
32 | - | ||
33 | - private static final DeviceId DID1 = deviceId("of:foo"); | ||
34 | - private static final DeviceId DID2 = deviceId("of:bar"); | ||
35 | - | ||
36 | - private static final PortNumber P1 = PortNumber.portNumber(1); | ||
37 | - private static final PortNumber P2 = PortNumber.portNumber(2); | ||
38 | - private static final PortNumber P3 = PortNumber.portNumber(3); | ||
39 | - | ||
40 | - private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1); | ||
41 | - private static final ConnectPoint CP2 = new ConnectPoint(DID2, P2); | ||
42 | - | ||
43 | - private static final ConnectPoint CP3 = new ConnectPoint(DID1, P2); | ||
44 | - private static final ConnectPoint CP4 = new ConnectPoint(DID2, P3); | ||
45 | - | ||
46 | - private static final LinkKey L1 = LinkKey.linkKey(CP1, CP2); | ||
47 | - private static final LinkKey L2 = LinkKey.linkKey(CP3, CP4); | ||
48 | - | ||
49 | - @Test | ||
50 | - public void testEquals() { | ||
51 | - new EqualsTester() | ||
52 | - .addEqualityGroup(new LinkFragmentId(L1, PID), | ||
53 | - new LinkFragmentId(L1, PID)) | ||
54 | - .addEqualityGroup(new LinkFragmentId(L2, PID), | ||
55 | - new LinkFragmentId(L2, PID)) | ||
56 | - .addEqualityGroup(new LinkFragmentId(L1, PIDA), | ||
57 | - new LinkFragmentId(L1, PIDA)) | ||
58 | - .addEqualityGroup(new LinkFragmentId(L2, PIDA), | ||
59 | - new LinkFragmentId(L2, PIDA)) | ||
60 | - .testEquals(); | ||
61 | - } | ||
62 | - | ||
63 | -} |
core/store/dist/src/test/java/org/onosproject/store/mastership/impl/RoleValueTest.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2014-present Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.store.mastership.impl; | ||
17 | - | ||
18 | -import static org.junit.Assert.assertEquals; | ||
19 | -import static org.junit.Assert.assertTrue; | ||
20 | -import static org.onosproject.net.MastershipRole.*; | ||
21 | - | ||
22 | -import org.junit.Test; | ||
23 | -import org.onosproject.cluster.NodeId; | ||
24 | - | ||
25 | -import com.google.common.collect.Sets; | ||
26 | - | ||
27 | -public class RoleValueTest { | ||
28 | - | ||
29 | - private static final RoleValue RV = new RoleValue(); | ||
30 | - | ||
31 | - private static final NodeId NID1 = new NodeId("node1"); | ||
32 | - private static final NodeId NID2 = new NodeId("node2"); | ||
33 | - private static final NodeId NID3 = new NodeId("node3"); | ||
34 | - | ||
35 | - @Test | ||
36 | - public void add() { | ||
37 | - assertEquals("faulty initialization: ", 3, RV.value.size()); | ||
38 | - RV.add(MASTER, NID1); | ||
39 | - RV.add(STANDBY, NID2); | ||
40 | - RV.add(STANDBY, NID3); | ||
41 | - | ||
42 | - assertEquals("wrong nodeID: ", NID1, RV.get(MASTER)); | ||
43 | - assertTrue("wrong nodeIDs: ", | ||
44 | - Sets.newHashSet(NID3, NID2).containsAll(RV.nodesOfRole(STANDBY))); | ||
45 | - } | ||
46 | -} |
-
Please register or login to post a comment