Committed by
Ray Milkey
Implemented a Builder pattern for EventuallyConsistentMaps.
EventuallyConsistentMap has been moved to the API package so is now available outside the stores. ONOS-1357 Change-Id: I1c892eb3dbefa72cb3f3eb3ccc74e9a02c7e2ac9
Showing
17 changed files
with
569 additions
and
217 deletions
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.store.impl; | 16 | +package org.onosproject.store.service; |
17 | 17 | ||
18 | import org.onosproject.store.Timestamp; | 18 | import org.onosproject.store.Timestamp; |
19 | 19 | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.store.ecmap; | 16 | +package org.onosproject.store.service; |
17 | 17 | ||
18 | import java.util.Collection; | 18 | import java.util.Collection; |
19 | import java.util.Map; | 19 | import java.util.Map; |
... | @@ -114,7 +114,7 @@ public interface EventuallyConsistentMap<K, V> { | ... | @@ -114,7 +114,7 @@ public interface EventuallyConsistentMap<K, V> { |
114 | * Removes the given key-value mapping from the map, if it exists. | 114 | * Removes the given key-value mapping from the map, if it exists. |
115 | * <p> | 115 | * <p> |
116 | * This actually means remove any values up to and including the timestamp | 116 | * This actually means remove any values up to and including the timestamp |
117 | - * given by {@link org.onosproject.store.impl.ClockService#getTimestamp(Object, Object)}. | 117 | + * given by {@link org.onosproject.store.service.ClockService#getTimestamp(Object, Object)}. |
118 | * Any mappings that produce an earlier timestamp than this given key-value | 118 | * Any mappings that produce an earlier timestamp than this given key-value |
119 | * pair will be removed, and any mappings that produce a later timestamp | 119 | * pair will be removed, and any mappings that produce a later timestamp |
120 | * will supersede this remove. | 120 | * will supersede this remove. | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.store.service; | ||
18 | + | ||
19 | +import org.onlab.util.KryoNamespace; | ||
20 | +import org.onosproject.cluster.NodeId; | ||
21 | + | ||
22 | +import java.util.Collection; | ||
23 | +import java.util.concurrent.ExecutorService; | ||
24 | +import java.util.concurrent.ScheduledExecutorService; | ||
25 | +import java.util.concurrent.TimeUnit; | ||
26 | +import java.util.function.BiFunction; | ||
27 | + | ||
28 | +/** | ||
29 | + * Builder for eventually consistent maps. | ||
30 | + * | ||
31 | + * @param <K> type for map keys | ||
32 | + * @param <V> type for map values | ||
33 | + */ | ||
34 | +public interface EventuallyConsistentMapBuilder<K, V> { | ||
35 | + | ||
36 | + /** | ||
37 | + * Sets the name of the map. | ||
38 | + * <p> | ||
39 | + * Each map is identified by a string map name. EventuallyConsistentMapImpl | ||
40 | + * objects in different JVMs that use the same map name will form a | ||
41 | + * distributed map across JVMs (provided the cluster service is aware of | ||
42 | + * both nodes). | ||
43 | + * </p> | ||
44 | + * <p> | ||
45 | + * Note: This is a mandatory parameter. | ||
46 | + * </p> | ||
47 | + * | ||
48 | + * @param name name of the map | ||
49 | + * @return this EventuallyConsistentMapBuilder | ||
50 | + */ | ||
51 | + public EventuallyConsistentMapBuilder<K, V> withName(String name); | ||
52 | + | ||
53 | + /** | ||
54 | + * Sets a serializer builder that can be used to create a serializer that | ||
55 | + * can serialize both the keys and values put into the map. The serializer | ||
56 | + * builder should be pre-populated with any classes that will be put into | ||
57 | + * the map. | ||
58 | + * <p> | ||
59 | + * Note: This is a mandatory parameter. | ||
60 | + * </p> | ||
61 | + * | ||
62 | + * @param serializerBuilder serializer builder | ||
63 | + * @return this EventuallyConsistentMapBuilder | ||
64 | + */ | ||
65 | + public EventuallyConsistentMapBuilder<K, V> withSerializer( | ||
66 | + KryoNamespace.Builder serializerBuilder); | ||
67 | + | ||
68 | + /** | ||
69 | + * Sets the clock service to use for generating timestamps for map updates. | ||
70 | + * <p> | ||
71 | + * The client must provide an {@link org.onosproject.store.service.ClockService} | ||
72 | + * which can generate timestamps for a given key. The clock service is free | ||
73 | + * to generate timestamps however it wishes, however these timestamps will | ||
74 | + * be used to serialize updates to the map so they must be strict enough | ||
75 | + * to ensure updates are properly ordered for the use case (i.e. in some | ||
76 | + * cases wallclock time will suffice, whereas in other cases logical time | ||
77 | + * will be necessary). | ||
78 | + * </p> | ||
79 | + * <p> | ||
80 | + * Note: This is a mandatory parameter. | ||
81 | + * </p> | ||
82 | + * | ||
83 | + * @param clockService clock service | ||
84 | + * @return this EventuallyConsistentMapBuilder | ||
85 | + */ | ||
86 | + public EventuallyConsistentMapBuilder<K, V> withClockService( | ||
87 | + ClockService<K, V> clockService); | ||
88 | + | ||
89 | + /** | ||
90 | + * Sets the executor to use for processing events coming in from peers. | ||
91 | + * | ||
92 | + * @param executor event executor | ||
93 | + * @return this EventuallyConsistentMapBuilder | ||
94 | + */ | ||
95 | + public EventuallyConsistentMapBuilder<K, V> withEventExecutor( | ||
96 | + ExecutorService executor); | ||
97 | + | ||
98 | + /** | ||
99 | + * Sets the executor to use for sending events to peers. | ||
100 | + * | ||
101 | + * @param executor event executor | ||
102 | + * @return this EventuallyConsistentMapBuilder | ||
103 | + */ | ||
104 | + public EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor( | ||
105 | + ExecutorService executor); | ||
106 | + | ||
107 | + /** | ||
108 | + * Sets the executor to use for background anti-entropy tasks. | ||
109 | + * | ||
110 | + * @param executor event executor | ||
111 | + * @return this EventuallyConsistentMapBuilder | ||
112 | + */ | ||
113 | + public EventuallyConsistentMapBuilder<K, V> withBackgroundExecutor( | ||
114 | + ScheduledExecutorService executor); | ||
115 | + | ||
116 | + /** | ||
117 | + * Sets a function that can determine which peers to replicate updates to. | ||
118 | + * <p> | ||
119 | + * The default function replicates to all nodes. | ||
120 | + * </p> | ||
121 | + * | ||
122 | + * @param peerUpdateFunction function that takes a K, V input and returns | ||
123 | + * a collection of NodeIds to replicate the event | ||
124 | + * to | ||
125 | + * @return this EventuallyConsistentMapBuilder | ||
126 | + */ | ||
127 | + public EventuallyConsistentMapBuilder<K, V> withPeerUpdateFunction( | ||
128 | + BiFunction<K, V, Collection<NodeId>> peerUpdateFunction); | ||
129 | + | ||
130 | + /** | ||
131 | + * Prevents this map from writing tombstones of items that have been | ||
132 | + * removed. This may result in zombie items reappearing after they have | ||
133 | + * been removed. | ||
134 | + * <p> | ||
135 | + * The default behavior is tombstones are enabled. | ||
136 | + * </p> | ||
137 | + * | ||
138 | + * @return this EventuallyConsistentMapBuilder | ||
139 | + */ | ||
140 | + public EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled(); | ||
141 | + | ||
142 | + /** | ||
143 | + * Configures how often to run the anti-entropy background task. | ||
144 | + * <p> | ||
145 | + * The default anti-entropy period is 5 seconds. | ||
146 | + * </p> | ||
147 | + * | ||
148 | + * @param period anti-entropy period | ||
149 | + * @param unit time unit for the period | ||
150 | + * @return this EventuallyConsistentMapBuilder | ||
151 | + */ | ||
152 | + public EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod( | ||
153 | + long period, TimeUnit unit); | ||
154 | + | ||
155 | + /** | ||
156 | + * Configure anti-entropy to converge faster at the cost of doing more work | ||
157 | + * for each anti-entropy cycle. Suited to maps with low update rate where | ||
158 | + * convergence time is more important than throughput. | ||
159 | + * <p> | ||
160 | + * The default behavior is to do less anti-entropy work at the cost of | ||
161 | + * slower convergence. | ||
162 | + * </p> | ||
163 | + * | ||
164 | + * @return this EventuallyConsistentMapBuilder | ||
165 | + */ | ||
166 | + public EventuallyConsistentMapBuilder<K, V> withFasterConvergence(); | ||
167 | + | ||
168 | + /** | ||
169 | + * Builds an eventually consistent map based on the configuration options | ||
170 | + * supplied to this builder. | ||
171 | + * | ||
172 | + * @return new eventually consistent map | ||
173 | + * @throws java.lang.RuntimeException if a mandatory parameter is missing | ||
174 | + */ | ||
175 | + public EventuallyConsistentMap<K, V> build(); | ||
176 | +} |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.store.ecmap; | 16 | +package org.onosproject.store.service; |
17 | 17 | ||
18 | import com.google.common.base.MoreObjects; | 18 | import com.google.common.base.MoreObjects; |
19 | 19 | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.store.ecmap; | 16 | +package org.onosproject.store.service; |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * Listener interested in receiving modification events for an | 19 | * Listener interested in receiving modification events for an | ... | ... |
... | @@ -30,6 +30,7 @@ public interface StorageService { | ... | @@ -30,6 +30,7 @@ public interface StorageService { |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * Creates a ConsistentMap. | 32 | * Creates a ConsistentMap. |
33 | + * | ||
33 | * @param name map name | 34 | * @param name map name |
34 | * @param serializer serializer to use for serializing keys and values | 35 | * @param serializer serializer to use for serializing keys and values |
35 | * @return consistent map. | 36 | * @return consistent map. |
... | @@ -40,6 +41,7 @@ public interface StorageService { | ... | @@ -40,6 +41,7 @@ public interface StorageService { |
40 | 41 | ||
41 | /** | 42 | /** |
42 | * Creates a AsyncConsistentMap. | 43 | * Creates a AsyncConsistentMap. |
44 | + * | ||
43 | * @param name map name | 45 | * @param name map name |
44 | * @param serializer serializer to use for serializing keys and values | 46 | * @param serializer serializer to use for serializing keys and values |
45 | * @return async consistent map | 47 | * @return async consistent map |
... | @@ -50,7 +52,18 @@ public interface StorageService { | ... | @@ -50,7 +52,18 @@ public interface StorageService { |
50 | 52 | ||
51 | /** | 53 | /** |
52 | * Creates a new transaction context. | 54 | * Creates a new transaction context. |
55 | + * | ||
53 | * @return transaction context | 56 | * @return transaction context |
54 | */ | 57 | */ |
55 | TransactionContext createTransactionContext(); | 58 | TransactionContext createTransactionContext(); |
59 | + | ||
60 | + /** | ||
61 | + * Creates a new EventuallyConsistentMapBuilder. | ||
62 | + * | ||
63 | + * @param <K> key type | ||
64 | + * @param <V> value type | ||
65 | + * @return builder for an eventually consistent map | ||
66 | + */ | ||
67 | + <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder(); | ||
68 | + | ||
56 | } | 69 | } | ... | ... |
... | @@ -43,14 +43,14 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ... | @@ -43,14 +43,14 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
43 | import org.onosproject.store.cluster.messaging.ClusterMessage; | 43 | import org.onosproject.store.cluster.messaging.ClusterMessage; |
44 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | 44 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; |
45 | import org.onosproject.store.cluster.messaging.MessageSubject; | 45 | import org.onosproject.store.cluster.messaging.MessageSubject; |
46 | -import org.onosproject.store.ecmap.EventuallyConsistentMap; | ||
47 | -import org.onosproject.store.ecmap.EventuallyConsistentMapEvent; | ||
48 | -import org.onosproject.store.ecmap.EventuallyConsistentMapImpl; | ||
49 | -import org.onosproject.store.ecmap.EventuallyConsistentMapListener; | ||
50 | -import org.onosproject.store.impl.ClockService; | ||
51 | import org.onosproject.store.impl.MultiValuedTimestamp; | 46 | import org.onosproject.store.impl.MultiValuedTimestamp; |
52 | import org.onosproject.store.impl.WallclockClockManager; | 47 | import org.onosproject.store.impl.WallclockClockManager; |
53 | import org.onosproject.store.serializers.KryoNamespaces; | 48 | import org.onosproject.store.serializers.KryoNamespaces; |
49 | +import org.onosproject.store.service.ClockService; | ||
50 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
51 | +import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
52 | +import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
53 | +import org.onosproject.store.service.StorageService; | ||
54 | import org.slf4j.Logger; | 54 | import org.slf4j.Logger; |
55 | 55 | ||
56 | import java.io.ByteArrayInputStream; | 56 | import java.io.ByteArrayInputStream; |
... | @@ -66,10 +66,16 @@ import java.util.concurrent.atomic.AtomicLong; | ... | @@ -66,10 +66,16 @@ import java.util.concurrent.atomic.AtomicLong; |
66 | import static com.google.common.io.ByteStreams.toByteArray; | 66 | import static com.google.common.io.ByteStreams.toByteArray; |
67 | import static java.util.concurrent.TimeUnit.MILLISECONDS; | 67 | import static java.util.concurrent.TimeUnit.MILLISECONDS; |
68 | import static org.onlab.util.Tools.groupedThreads; | 68 | import static org.onlab.util.Tools.groupedThreads; |
69 | -import static org.onosproject.app.ApplicationEvent.Type.*; | 69 | +import static org.onosproject.app.ApplicationEvent.Type.APP_ACTIVATED; |
70 | -import static org.onosproject.store.app.GossipApplicationStore.InternalState.*; | 70 | +import static org.onosproject.app.ApplicationEvent.Type.APP_DEACTIVATED; |
71 | -import static org.onosproject.store.ecmap.EventuallyConsistentMapEvent.Type.PUT; | 71 | +import static org.onosproject.app.ApplicationEvent.Type.APP_INSTALLED; |
72 | -import static org.onosproject.store.ecmap.EventuallyConsistentMapEvent.Type.REMOVE; | 72 | +import static org.onosproject.app.ApplicationEvent.Type.APP_PERMISSIONS_CHANGED; |
73 | +import static org.onosproject.app.ApplicationEvent.Type.APP_UNINSTALLED; | ||
74 | +import static org.onosproject.store.app.GossipApplicationStore.InternalState.ACTIVATED; | ||
75 | +import static org.onosproject.store.app.GossipApplicationStore.InternalState.DEACTIVATED; | ||
76 | +import static org.onosproject.store.app.GossipApplicationStore.InternalState.INSTALLED; | ||
77 | +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT; | ||
78 | +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE; | ||
73 | import static org.slf4j.LoggerFactory.getLogger; | 79 | import static org.slf4j.LoggerFactory.getLogger; |
74 | 80 | ||
75 | /** | 81 | /** |
... | @@ -106,6 +112,9 @@ public class GossipApplicationStore extends ApplicationArchive | ... | @@ -106,6 +112,9 @@ public class GossipApplicationStore extends ApplicationArchive |
106 | protected ClusterService clusterService; | 112 | protected ClusterService clusterService; |
107 | 113 | ||
108 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 114 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
115 | + protected StorageService storageService; | ||
116 | + | ||
117 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
109 | protected ApplicationIdStore idStore; | 118 | protected ApplicationIdStore idStore; |
110 | 119 | ||
111 | private final AtomicLong sequence = new AtomicLong(); | 120 | private final AtomicLong sequence = new AtomicLong(); |
... | @@ -130,27 +139,29 @@ public class GossipApplicationStore extends ApplicationArchive | ... | @@ -130,27 +139,29 @@ public class GossipApplicationStore extends ApplicationArchive |
130 | new MultiValuedTimestamp<>(getUpdateTime(appId.name()), | 139 | new MultiValuedTimestamp<>(getUpdateTime(appId.name()), |
131 | sequence.incrementAndGet()); | 140 | sequence.incrementAndGet()); |
132 | 141 | ||
133 | - apps = new EventuallyConsistentMapImpl<>("apps", clusterService, | 142 | + apps = storageService.<ApplicationId, Application>eventuallyConsistentMapBuilder() |
134 | - clusterCommunicator, | 143 | + .withName("apps") |
135 | - serializer, | 144 | + .withSerializer(serializer) |
136 | - appsClockService); | 145 | + .withClockService(appsClockService) |
146 | + .build(); | ||
137 | 147 | ||
138 | ClockService<Application, InternalState> statesClockService = (app, state) -> | 148 | ClockService<Application, InternalState> statesClockService = (app, state) -> |
139 | new MultiValuedTimestamp<>(getUpdateTime(app.id().name()), | 149 | new MultiValuedTimestamp<>(getUpdateTime(app.id().name()), |
140 | sequence.incrementAndGet()); | 150 | sequence.incrementAndGet()); |
141 | 151 | ||
142 | - states = new EventuallyConsistentMapImpl<>("app-states", | 152 | + states = storageService.<Application, InternalState>eventuallyConsistentMapBuilder() |
143 | - clusterService, | 153 | + .withName("app-states") |
144 | - clusterCommunicator, | 154 | + .withSerializer(serializer) |
145 | - serializer, | 155 | + .withClockService(statesClockService) |
146 | - statesClockService); | 156 | + .build(); |
157 | + | ||
147 | states.addListener(new InternalAppStatesListener()); | 158 | states.addListener(new InternalAppStatesListener()); |
148 | 159 | ||
149 | - permissions = new EventuallyConsistentMapImpl<>("app-permissions", | 160 | + permissions = storageService.<Application, Set<Permission>>eventuallyConsistentMapBuilder() |
150 | - clusterService, | 161 | + .withName("app-permissions") |
151 | - clusterCommunicator, | 162 | + .withSerializer(serializer) |
152 | - serializer, | 163 | + .withClockService(new WallclockClockManager<>()) |
153 | - new WallclockClockManager<>()); | 164 | + .build(); |
154 | 165 | ||
155 | log.info("Started"); | 166 | log.info("Started"); |
156 | } | 167 | } | ... | ... |
... | @@ -25,21 +25,19 @@ import org.onlab.util.KryoNamespace; | ... | @@ -25,21 +25,19 @@ import org.onlab.util.KryoNamespace; |
25 | import org.onosproject.cfg.ComponentConfigEvent; | 25 | import org.onosproject.cfg.ComponentConfigEvent; |
26 | import org.onosproject.cfg.ComponentConfigStore; | 26 | import org.onosproject.cfg.ComponentConfigStore; |
27 | import org.onosproject.cfg.ComponentConfigStoreDelegate; | 27 | import org.onosproject.cfg.ComponentConfigStoreDelegate; |
28 | -import org.onosproject.cluster.ClusterService; | ||
29 | import org.onosproject.store.AbstractStore; | 28 | import org.onosproject.store.AbstractStore; |
30 | -import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
31 | -import org.onosproject.store.ecmap.EventuallyConsistentMap; | ||
32 | -import org.onosproject.store.ecmap.EventuallyConsistentMapEvent; | ||
33 | -import org.onosproject.store.ecmap.EventuallyConsistentMapImpl; | ||
34 | -import org.onosproject.store.ecmap.EventuallyConsistentMapListener; | ||
35 | import org.onosproject.store.impl.WallclockClockManager; | 29 | import org.onosproject.store.impl.WallclockClockManager; |
36 | import org.onosproject.store.serializers.KryoNamespaces; | 30 | import org.onosproject.store.serializers.KryoNamespaces; |
31 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
32 | +import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
33 | +import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
34 | +import org.onosproject.store.service.StorageService; | ||
37 | import org.slf4j.Logger; | 35 | import org.slf4j.Logger; |
38 | 36 | ||
39 | import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_SET; | 37 | import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_SET; |
40 | import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_UNSET; | 38 | import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_UNSET; |
41 | -import static org.onosproject.store.ecmap.EventuallyConsistentMapEvent.Type.PUT; | 39 | +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT; |
42 | -import static org.onosproject.store.ecmap.EventuallyConsistentMapEvent.Type.REMOVE; | 40 | +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE; |
43 | import static org.slf4j.LoggerFactory.getLogger; | 41 | import static org.slf4j.LoggerFactory.getLogger; |
44 | 42 | ||
45 | /** | 43 | /** |
... | @@ -59,20 +57,19 @@ public class GossipComponentConfigStore | ... | @@ -59,20 +57,19 @@ public class GossipComponentConfigStore |
59 | private EventuallyConsistentMap<String, String> properties; | 57 | private EventuallyConsistentMap<String, String> properties; |
60 | 58 | ||
61 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 59 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
62 | - protected ClusterCommunicationService clusterCommunicator; | 60 | + protected StorageService storageService; |
63 | - | ||
64 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
65 | - protected ClusterService clusterService; | ||
66 | 61 | ||
67 | @Activate | 62 | @Activate |
68 | public void activate() { | 63 | public void activate() { |
69 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | 64 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() |
70 | .register(KryoNamespaces.API); | 65 | .register(KryoNamespaces.API); |
71 | 66 | ||
72 | - properties = new EventuallyConsistentMapImpl<>("cfg", clusterService, | 67 | + properties = storageService.<String, String>eventuallyConsistentMapBuilder() |
73 | - clusterCommunicator, | 68 | + .withName("cfg") |
74 | - serializer, | 69 | + .withSerializer(serializer) |
75 | - new WallclockClockManager<>()); | 70 | + .withClockService(new WallclockClockManager<>()) |
71 | + .build(); | ||
72 | + | ||
76 | properties.addListener(new InternalPropertiesListener()); | 73 | properties.addListener(new InternalPropertiesListener()); |
77 | log.info("Started"); | 74 | log.info("Started"); |
78 | } | 75 | } | ... | ... |
... | @@ -17,13 +17,11 @@ | ... | @@ -17,13 +17,11 @@ |
17 | package org.onosproject.store.consistent.impl; | 17 | package org.onosproject.store.consistent.impl; |
18 | 18 | ||
19 | import com.google.common.collect.Sets; | 19 | import com.google.common.collect.Sets; |
20 | - | ||
21 | import net.kuujo.copycat.cluster.ClusterConfig; | 20 | import net.kuujo.copycat.cluster.ClusterConfig; |
22 | import net.kuujo.copycat.cluster.Member; | 21 | import net.kuujo.copycat.cluster.Member; |
23 | import net.kuujo.copycat.log.FileLog; | 22 | import net.kuujo.copycat.log.FileLog; |
24 | import net.kuujo.copycat.netty.NettyTcpProtocol; | 23 | import net.kuujo.copycat.netty.NettyTcpProtocol; |
25 | import net.kuujo.copycat.protocol.Consistency; | 24 | import net.kuujo.copycat.protocol.Consistency; |
26 | - | ||
27 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
28 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
29 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -32,8 +30,11 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -32,8 +30,11 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
32 | import org.apache.felix.scr.annotations.Service; | 30 | import org.apache.felix.scr.annotations.Service; |
33 | import org.onosproject.cluster.ClusterService; | 31 | import org.onosproject.cluster.ClusterService; |
34 | import org.onosproject.store.cluster.impl.NodeInfo; | 32 | import org.onosproject.store.cluster.impl.NodeInfo; |
33 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
34 | +import org.onosproject.store.ecmap.EventuallyConsistentMapBuilderImpl; | ||
35 | import org.onosproject.store.service.AsyncConsistentMap; | 35 | import org.onosproject.store.service.AsyncConsistentMap; |
36 | import org.onosproject.store.service.ConsistentMap; | 36 | import org.onosproject.store.service.ConsistentMap; |
37 | +import org.onosproject.store.service.EventuallyConsistentMapBuilder; | ||
37 | import org.onosproject.store.service.PartitionInfo; | 38 | import org.onosproject.store.service.PartitionInfo; |
38 | import org.onosproject.store.service.Serializer; | 39 | import org.onosproject.store.service.Serializer; |
39 | import org.onosproject.store.service.StorageAdminService; | 40 | import org.onosproject.store.service.StorageAdminService; |
... | @@ -71,6 +72,9 @@ public class DatabaseManager implements StorageService, StorageAdminService { | ... | @@ -71,6 +72,9 @@ public class DatabaseManager implements StorageService, StorageAdminService { |
71 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 72 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
72 | protected ClusterService clusterService; | 73 | protected ClusterService clusterService; |
73 | 74 | ||
75 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
76 | + protected ClusterCommunicationService clusterCommunicator; | ||
77 | + | ||
74 | protected String nodeToUri(NodeInfo node) { | 78 | protected String nodeToUri(NodeInfo node) { |
75 | return String.format("tcp://%s:%d", node.getIp(), COPYCAT_TCP_PORT); | 79 | return String.format("tcp://%s:%d", node.getIp(), COPYCAT_TCP_PORT); |
76 | } | 80 | } |
... | @@ -169,12 +173,12 @@ public class DatabaseManager implements StorageService, StorageAdminService { | ... | @@ -169,12 +173,12 @@ public class DatabaseManager implements StorageService, StorageAdminService { |
169 | 173 | ||
170 | @Override | 174 | @Override |
171 | public <K, V> ConsistentMap<K , V> createConsistentMap(String name, Serializer serializer) { | 175 | public <K, V> ConsistentMap<K , V> createConsistentMap(String name, Serializer serializer) { |
172 | - return new DefaultConsistentMap<K, V>(name, partitionedDatabase, serializer); | 176 | + return new DefaultConsistentMap<>(name, partitionedDatabase, serializer); |
173 | } | 177 | } |
174 | 178 | ||
175 | @Override | 179 | @Override |
176 | public <K, V> AsyncConsistentMap<K , V> createAsyncConsistentMap(String name, Serializer serializer) { | 180 | public <K, V> AsyncConsistentMap<K , V> createAsyncConsistentMap(String name, Serializer serializer) { |
177 | - return new DefaultAsyncConsistentMap<K, V>(name, partitionedDatabase, serializer); | 181 | + return new DefaultAsyncConsistentMap<>(name, partitionedDatabase, serializer); |
178 | } | 182 | } |
179 | 183 | ||
180 | @Override | 184 | @Override |
... | @@ -207,4 +211,12 @@ public class DatabaseManager implements StorageService, StorageAdminService { | ... | @@ -207,4 +211,12 @@ public class DatabaseManager implements StorageService, StorageAdminService { |
207 | database.cluster().leader() != null ? | 211 | database.cluster().leader() != null ? |
208 | database.cluster().leader().uri() : null); | 212 | database.cluster().leader().uri() : null); |
209 | } | 213 | } |
214 | + | ||
215 | + | ||
216 | + @Override | ||
217 | + public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() { | ||
218 | + return new EventuallyConsistentMapBuilderImpl<>(clusterService, | ||
219 | + clusterCommunicator); | ||
220 | + } | ||
221 | + | ||
210 | } | 222 | } | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapBuilderImpl.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.store.ecmap; | ||
17 | + | ||
18 | +import org.onlab.util.KryoNamespace; | ||
19 | +import org.onosproject.cluster.ClusterService; | ||
20 | +import org.onosproject.cluster.NodeId; | ||
21 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
22 | +import org.onosproject.store.service.ClockService; | ||
23 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
24 | +import org.onosproject.store.service.EventuallyConsistentMapBuilder; | ||
25 | + | ||
26 | +import java.util.Collection; | ||
27 | +import java.util.concurrent.ExecutorService; | ||
28 | +import java.util.concurrent.ScheduledExecutorService; | ||
29 | +import java.util.concurrent.TimeUnit; | ||
30 | +import java.util.function.BiFunction; | ||
31 | + | ||
32 | +import static com.google.common.base.Preconditions.checkArgument; | ||
33 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
34 | + | ||
35 | +/** | ||
36 | + * Eventually consistent map builder. | ||
37 | + */ | ||
38 | +public class EventuallyConsistentMapBuilderImpl<K, V> | ||
39 | + implements EventuallyConsistentMapBuilder<K, V> { | ||
40 | + private final ClusterService clusterService; | ||
41 | + private final ClusterCommunicationService clusterCommunicator; | ||
42 | + | ||
43 | + private String name; | ||
44 | + private KryoNamespace.Builder serializerBuilder; | ||
45 | + private ExecutorService eventExecutor; | ||
46 | + private ExecutorService communicationExecutor; | ||
47 | + private ScheduledExecutorService backgroundExecutor; | ||
48 | + private ClockService<K, V> clockService; | ||
49 | + private BiFunction<K, V, Collection<NodeId>> peerUpdateFunction; | ||
50 | + private boolean tombstonesDisabled = false; | ||
51 | + private long antiEntropyPeriod = 5; | ||
52 | + private TimeUnit antiEntropyTimeUnit = TimeUnit.SECONDS; | ||
53 | + private boolean convergeFaster = false; | ||
54 | + | ||
55 | + /** | ||
56 | + * Creates a new eventually consistent map builder. | ||
57 | + * | ||
58 | + * @param clusterService cluster service | ||
59 | + * @param clusterCommunicator cluster communication service | ||
60 | + */ | ||
61 | + public EventuallyConsistentMapBuilderImpl(ClusterService clusterService, | ||
62 | + ClusterCommunicationService clusterCommunicator) { | ||
63 | + this.clusterService = checkNotNull(clusterService); | ||
64 | + this.clusterCommunicator = checkNotNull(clusterCommunicator); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public EventuallyConsistentMapBuilder withName(String name) { | ||
69 | + this.name = checkNotNull(name); | ||
70 | + return this; | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
74 | + public EventuallyConsistentMapBuilder withSerializer( | ||
75 | + KryoNamespace.Builder serializerBuilder) { | ||
76 | + this.serializerBuilder = checkNotNull(serializerBuilder); | ||
77 | + return this; | ||
78 | + } | ||
79 | + | ||
80 | + @Override | ||
81 | + public EventuallyConsistentMapBuilder withClockService( | ||
82 | + ClockService<K, V> clockService) { | ||
83 | + this.clockService = checkNotNull(clockService); | ||
84 | + return this; | ||
85 | + } | ||
86 | + | ||
87 | + @Override | ||
88 | + public EventuallyConsistentMapBuilder withEventExecutor(ExecutorService executor) { | ||
89 | + this.eventExecutor = checkNotNull(executor); | ||
90 | + return this; | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor( | ||
95 | + ExecutorService executor) { | ||
96 | + communicationExecutor = checkNotNull(executor); | ||
97 | + return this; | ||
98 | + } | ||
99 | + | ||
100 | + @Override | ||
101 | + public EventuallyConsistentMapBuilder withBackgroundExecutor(ScheduledExecutorService executor) { | ||
102 | + this.backgroundExecutor = checkNotNull(executor); | ||
103 | + return this; | ||
104 | + } | ||
105 | + | ||
106 | + @Override | ||
107 | + public EventuallyConsistentMapBuilder withPeerUpdateFunction( | ||
108 | + BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) { | ||
109 | + this.peerUpdateFunction = checkNotNull(peerUpdateFunction); | ||
110 | + return this; | ||
111 | + } | ||
112 | + | ||
113 | + @Override | ||
114 | + public EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled() { | ||
115 | + tombstonesDisabled = true; | ||
116 | + return this; | ||
117 | + } | ||
118 | + | ||
119 | + @Override | ||
120 | + public EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod(long period, TimeUnit unit) { | ||
121 | + checkArgument(period > 0, "anti-entropy period must be greater than 0"); | ||
122 | + antiEntropyPeriod = period; | ||
123 | + antiEntropyTimeUnit = checkNotNull(unit); | ||
124 | + return this; | ||
125 | + } | ||
126 | + | ||
127 | + @Override | ||
128 | + public EventuallyConsistentMapBuilder<K, V> withFasterConvergence() { | ||
129 | + convergeFaster = true; | ||
130 | + return this; | ||
131 | + } | ||
132 | + | ||
133 | + @Override | ||
134 | + public EventuallyConsistentMap<K, V> build() { | ||
135 | + checkNotNull(name, "name is a mandatory parameter"); | ||
136 | + checkNotNull(serializerBuilder, "serializerBuilder is a mandatory parameter"); | ||
137 | + checkNotNull(clockService, "clockService is a mandatory parameter"); | ||
138 | + | ||
139 | + return new EventuallyConsistentMapImpl<>(name, | ||
140 | + clusterService, | ||
141 | + clusterCommunicator, | ||
142 | + serializerBuilder, | ||
143 | + clockService, | ||
144 | + peerUpdateFunction, | ||
145 | + eventExecutor, | ||
146 | + communicationExecutor, | ||
147 | + backgroundExecutor, | ||
148 | + tombstonesDisabled, | ||
149 | + antiEntropyPeriod, | ||
150 | + antiEntropyTimeUnit, | ||
151 | + convergeFaster); | ||
152 | + } | ||
153 | +} |
... | @@ -32,10 +32,13 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ... | @@ -32,10 +32,13 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
32 | import org.onosproject.store.cluster.messaging.ClusterMessage; | 32 | import org.onosproject.store.cluster.messaging.ClusterMessage; |
33 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | 33 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; |
34 | import org.onosproject.store.cluster.messaging.MessageSubject; | 34 | import org.onosproject.store.cluster.messaging.MessageSubject; |
35 | -import org.onosproject.store.impl.ClockService; | ||
36 | import org.onosproject.store.impl.Timestamped; | 35 | import org.onosproject.store.impl.Timestamped; |
37 | import org.onosproject.store.impl.WallClockTimestamp; | 36 | import org.onosproject.store.impl.WallClockTimestamp; |
38 | import org.onosproject.store.serializers.KryoSerializer; | 37 | import org.onosproject.store.serializers.KryoSerializer; |
38 | +import org.onosproject.store.service.ClockService; | ||
39 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
40 | +import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
41 | +import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
39 | import org.slf4j.Logger; | 42 | import org.slf4j.Logger; |
40 | import org.slf4j.LoggerFactory; | 43 | import org.slf4j.LoggerFactory; |
41 | 44 | ||
... | @@ -54,7 +57,6 @@ import java.util.concurrent.ExecutorService; | ... | @@ -54,7 +57,6 @@ import java.util.concurrent.ExecutorService; |
54 | import java.util.concurrent.Executors; | 57 | import java.util.concurrent.Executors; |
55 | import java.util.concurrent.ScheduledExecutorService; | 58 | import java.util.concurrent.ScheduledExecutorService; |
56 | import java.util.concurrent.TimeUnit; | 59 | import java.util.concurrent.TimeUnit; |
57 | -import java.util.concurrent.atomic.AtomicLong; | ||
58 | import java.util.function.BiFunction; | 60 | import java.util.function.BiFunction; |
59 | import java.util.stream.Collectors; | 61 | import java.util.stream.Collectors; |
60 | 62 | ||
... | @@ -93,8 +95,8 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -93,8 +95,8 @@ public class EventuallyConsistentMapImpl<K, V> |
93 | private final ScheduledExecutorService backgroundExecutor; | 95 | private final ScheduledExecutorService backgroundExecutor; |
94 | private final BiFunction<K, V, Collection<NodeId>> peerUpdateFunction; | 96 | private final BiFunction<K, V, Collection<NodeId>> peerUpdateFunction; |
95 | 97 | ||
96 | - private ExecutorService communicationExecutor; | 98 | + private final ExecutorService communicationExecutor; |
97 | - private Map<NodeId, EventAccumulator> senderPending; | 99 | + private final Map<NodeId, EventAccumulator> senderPending; |
98 | 100 | ||
99 | private volatile boolean destroyed = false; | 101 | private volatile boolean destroyed = false; |
100 | private static final String ERROR_DESTROYED = " map is already destroyed"; | 102 | private static final String ERROR_DESTROYED = " map is already destroyed"; |
... | @@ -103,41 +105,20 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -103,41 +105,20 @@ public class EventuallyConsistentMapImpl<K, V> |
103 | private static final String ERROR_NULL_KEY = "Key cannot be null"; | 105 | private static final String ERROR_NULL_KEY = "Key cannot be null"; |
104 | private static final String ERROR_NULL_VALUE = "Null values are not allowed"; | 106 | private static final String ERROR_NULL_VALUE = "Null values are not allowed"; |
105 | 107 | ||
106 | - // TODO: Make these anti-entropy params configurable | 108 | + private final long initialDelaySec = 5; |
107 | - private long initialDelaySec = 5; | 109 | + private final boolean lightweightAntiEntropy; |
108 | - private long periodSec = 5; | 110 | + private final boolean tombstonesDisabled; |
109 | - private boolean lightweightAntiEntropy = true; | ||
110 | - private boolean tombstonesDisabled = false; | ||
111 | 111 | ||
112 | private static final int WINDOW_SIZE = 5; | 112 | private static final int WINDOW_SIZE = 5; |
113 | private static final int HIGH_LOAD_THRESHOLD = 0; | 113 | private static final int HIGH_LOAD_THRESHOLD = 0; |
114 | private static final int LOAD_WINDOW = 2; | 114 | private static final int LOAD_WINDOW = 2; |
115 | - SlidingWindowCounter counter = new SlidingWindowCounter(WINDOW_SIZE); | 115 | + private SlidingWindowCounter counter = new SlidingWindowCounter(WINDOW_SIZE); |
116 | - AtomicLong operations = new AtomicLong(); | ||
117 | 116 | ||
118 | /** | 117 | /** |
119 | * Creates a new eventually consistent map shared amongst multiple instances. | 118 | * Creates a new eventually consistent map shared amongst multiple instances. |
120 | * <p> | 119 | * <p> |
121 | - * Each map is identified by a string map name. EventuallyConsistentMapImpl | 120 | + * See {@link org.onosproject.store.service.EventuallyConsistentMapBuilder} |
122 | - * objects in different JVMs that use the same map name will form a | 121 | + * for more description of the parameters expected by the map. |
123 | - * distributed map across JVMs (provided the cluster service is aware of | ||
124 | - * both nodes). | ||
125 | - * </p> | ||
126 | - * <p> | ||
127 | - * The client is expected to provide an | ||
128 | - * {@link org.onlab.util.KryoNamespace.Builder} with which all classes that | ||
129 | - * will be stored in this map have been registered (including referenced | ||
130 | - * classes). This serializer will be used to serialize both K and V for | ||
131 | - * inter-node notifications. | ||
132 | - * </p> | ||
133 | - * <p> | ||
134 | - * The client must provide an {@link org.onosproject.store.impl.ClockService} | ||
135 | - * which can generate timestamps for a given key. The clock service is free | ||
136 | - * to generate timestamps however it wishes, however these timestamps will | ||
137 | - * be used to serialize updates to the map so they must be strict enough | ||
138 | - * to ensure updates are properly ordered for the use case (i.e. in some | ||
139 | - * cases wallclock time will suffice, whereas in other cases logical time | ||
140 | - * will be necessary). | ||
141 | * </p> | 122 | * </p> |
142 | * | 123 | * |
143 | * @param mapName a String identifier for the map. | 124 | * @param mapName a String identifier for the map. |
... | @@ -146,87 +127,93 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -146,87 +127,93 @@ public class EventuallyConsistentMapImpl<K, V> |
146 | * @param serializerBuilder a Kryo namespace builder that can serialize | 127 | * @param serializerBuilder a Kryo namespace builder that can serialize |
147 | * both K and V | 128 | * both K and V |
148 | * @param clockService a clock service able to generate timestamps | 129 | * @param clockService a clock service able to generate timestamps |
149 | - * for K | 130 | + * for K and V |
150 | * @param peerUpdateFunction function that provides a set of nodes to immediately | 131 | * @param peerUpdateFunction function that provides a set of nodes to immediately |
151 | * update to when there writes to the map | 132 | * update to when there writes to the map |
133 | + * @param eventExecutor executor to use for processing incoming | ||
134 | + * events from peers | ||
135 | + * @param communicationExecutor executor to use for sending events to peers | ||
136 | + * @param backgroundExecutor executor to use for background anti-entropy | ||
137 | + * tasks | ||
138 | + * @param tombstonesDisabled true if this map should not maintain | ||
139 | + * tombstones | ||
140 | + * @param antiEntropyPeriod period that the anti-entropy task should run | ||
141 | + * in seconds | ||
142 | + * @param convergeFaster make anti-entropy try to converge faster | ||
152 | */ | 143 | */ |
153 | - public EventuallyConsistentMapImpl(String mapName, | 144 | + EventuallyConsistentMapImpl(String mapName, |
154 | ClusterService clusterService, | 145 | ClusterService clusterService, |
155 | ClusterCommunicationService clusterCommunicator, | 146 | ClusterCommunicationService clusterCommunicator, |
156 | KryoNamespace.Builder serializerBuilder, | 147 | KryoNamespace.Builder serializerBuilder, |
157 | ClockService<K, V> clockService, | 148 | ClockService<K, V> clockService, |
158 | - BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) { | 149 | + BiFunction<K, V, Collection<NodeId>> peerUpdateFunction, |
159 | - this.clusterService = checkNotNull(clusterService); | 150 | + ExecutorService eventExecutor, |
160 | - this.clusterCommunicator = checkNotNull(clusterCommunicator); | 151 | + ExecutorService communicationExecutor, |
161 | - this.peerUpdateFunction = checkNotNull(peerUpdateFunction); | 152 | + ScheduledExecutorService backgroundExecutor, |
162 | - | 153 | + boolean tombstonesDisabled, |
163 | - serializer = createSerializer(checkNotNull(serializerBuilder)); | 154 | + long antiEntropyPeriod, |
155 | + TimeUnit antiEntropyTimeUnit, | ||
156 | + boolean convergeFaster) { | ||
157 | + items = new ConcurrentHashMap<>(); | ||
158 | + removedItems = new ConcurrentHashMap<>(); | ||
159 | + senderPending = Maps.newConcurrentMap(); | ||
164 | destroyedMessage = mapName + ERROR_DESTROYED; | 160 | destroyedMessage = mapName + ERROR_DESTROYED; |
165 | 161 | ||
166 | - this.clockService = checkNotNull(clockService); | 162 | + this.clusterService = clusterService; |
163 | + this.clusterCommunicator = clusterCommunicator; | ||
167 | 164 | ||
168 | - items = new ConcurrentHashMap<>(); | 165 | + this.serializer = createSerializer(serializerBuilder); |
169 | - removedItems = new ConcurrentHashMap<>(); | ||
170 | 166 | ||
167 | + this.clockService = clockService; | ||
168 | + | ||
169 | + if (peerUpdateFunction != null) { | ||
170 | + this.peerUpdateFunction = peerUpdateFunction; | ||
171 | + } else { | ||
172 | + this.peerUpdateFunction = (key, value) -> clusterService.getNodes().stream() | ||
173 | + .map(ControllerNode::id) | ||
174 | + .filter(nodeId -> !nodeId.equals(clusterService.getLocalNode().id())) | ||
175 | + .collect(Collectors.toList()); | ||
176 | + } | ||
177 | + | ||
178 | + if (eventExecutor != null) { | ||
179 | + this.executor = eventExecutor; | ||
180 | + } else { | ||
171 | // should be a normal executor; it's used for receiving messages | 181 | // should be a normal executor; it's used for receiving messages |
172 | - //TODO make # of threads configurable | 182 | + this.executor = |
173 | - executor = Executors.newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-fg-%d")); | 183 | + Executors.newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-fg-%d")); |
184 | + } | ||
174 | 185 | ||
186 | + if (communicationExecutor != null) { | ||
187 | + this.communicationExecutor = communicationExecutor; | ||
188 | + } else { | ||
175 | // sending executor; should be capped | 189 | // sending executor; should be capped |
176 | - //TODO make # of threads configurable | ||
177 | //TODO this probably doesn't need to be bounded anymore | 190 | //TODO this probably doesn't need to be bounded anymore |
178 | - communicationExecutor = | 191 | + this.communicationExecutor = |
179 | newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-publish-%d")); | 192 | newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-publish-%d")); |
180 | - senderPending = Maps.newConcurrentMap(); | 193 | + } |
181 | 194 | ||
182 | - backgroundExecutor = | 195 | + if (backgroundExecutor != null) { |
196 | + this.backgroundExecutor = backgroundExecutor; | ||
197 | + } else { | ||
198 | + this.backgroundExecutor = | ||
183 | newSingleThreadScheduledExecutor(groupedThreads("onos/ecm", mapName + "-bg-%d")); | 199 | newSingleThreadScheduledExecutor(groupedThreads("onos/ecm", mapName + "-bg-%d")); |
200 | + } | ||
184 | 201 | ||
185 | // start anti-entropy thread | 202 | // start anti-entropy thread |
186 | - backgroundExecutor.scheduleAtFixedRate(new SendAdvertisementTask(), | 203 | + this.backgroundExecutor.scheduleAtFixedRate(new SendAdvertisementTask(), |
187 | - initialDelaySec, periodSec, | 204 | + initialDelaySec, antiEntropyPeriod, |
188 | - TimeUnit.SECONDS); | 205 | + antiEntropyTimeUnit); |
189 | 206 | ||
190 | updateMessageSubject = new MessageSubject("ecm-" + mapName + "-update"); | 207 | updateMessageSubject = new MessageSubject("ecm-" + mapName + "-update"); |
191 | clusterCommunicator.addSubscriber(updateMessageSubject, | 208 | clusterCommunicator.addSubscriber(updateMessageSubject, |
192 | - new InternalEventListener(), executor); | 209 | + new InternalEventListener(), this.executor); |
193 | 210 | ||
194 | antiEntropyAdvertisementSubject = new MessageSubject("ecm-" + mapName + "-anti-entropy"); | 211 | antiEntropyAdvertisementSubject = new MessageSubject("ecm-" + mapName + "-anti-entropy"); |
195 | clusterCommunicator.addSubscriber(antiEntropyAdvertisementSubject, | 212 | clusterCommunicator.addSubscriber(antiEntropyAdvertisementSubject, |
196 | - new InternalAntiEntropyListener(), backgroundExecutor); | 213 | + new InternalAntiEntropyListener(), this.backgroundExecutor); |
197 | - } | ||
198 | 214 | ||
199 | - /** | 215 | + this.tombstonesDisabled = tombstonesDisabled; |
200 | - * Creates a new eventually consistent map shared amongst multiple instances. | 216 | + this.lightweightAntiEntropy = !convergeFaster; |
201 | - * <p> | ||
202 | - * Take a look at the other constructor for usage information. The only difference | ||
203 | - * is that a BiFunction is provided that returns all nodes in the cluster, so | ||
204 | - * all nodes will be sent write updates immediately. | ||
205 | - * </p> | ||
206 | - * | ||
207 | - * @param mapName a String identifier for the map. | ||
208 | - * @param clusterService the cluster service | ||
209 | - * @param clusterCommunicator the cluster communications service | ||
210 | - * @param serializerBuilder a Kryo namespace builder that can serialize | ||
211 | - * both K and V | ||
212 | - * @param clockService a clock service able to generate timestamps | ||
213 | - * for K | ||
214 | - */ | ||
215 | - public EventuallyConsistentMapImpl(String mapName, | ||
216 | - ClusterService clusterService, | ||
217 | - ClusterCommunicationService clusterCommunicator, | ||
218 | - KryoNamespace.Builder serializerBuilder, | ||
219 | - ClockService<K, V> clockService) { | ||
220 | - this(mapName, clusterService, clusterCommunicator, serializerBuilder, clockService, | ||
221 | - (key, value) -> clusterService.getNodes().stream() | ||
222 | - .map(ControllerNode::id) | ||
223 | - .filter(nodeId -> !nodeId.equals(clusterService.getLocalNode().id())) | ||
224 | - .collect(Collectors.toList())); | ||
225 | - } | ||
226 | - | ||
227 | - public EventuallyConsistentMapImpl<K, V> withTombstonesDisabled(boolean status) { | ||
228 | - tombstonesDisabled = status; | ||
229 | - return this; | ||
230 | } | 217 | } |
231 | 218 | ||
232 | private KryoSerializer createSerializer(KryoNamespace.Builder builder) { | 219 | private KryoSerializer createSerializer(KryoNamespace.Builder builder) { |
... | @@ -246,19 +233,6 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -246,19 +233,6 @@ public class EventuallyConsistentMapImpl<K, V> |
246 | }; | 233 | }; |
247 | } | 234 | } |
248 | 235 | ||
249 | - /** | ||
250 | - * Sets the executor to use for broadcasting messages and returns this | ||
251 | - * instance for method chaining. | ||
252 | - * | ||
253 | - * @param executor executor service | ||
254 | - * @return this instance | ||
255 | - */ | ||
256 | - public EventuallyConsistentMapImpl<K, V> withBroadcastMessageExecutor(ExecutorService executor) { | ||
257 | - checkNotNull(executor, "Null executor"); | ||
258 | - communicationExecutor = executor; | ||
259 | - return this; | ||
260 | - } | ||
261 | - | ||
262 | @Override | 236 | @Override |
263 | public int size() { | 237 | public int size() { |
264 | checkState(!destroyed, destroyedMessage); | 238 | checkState(!destroyed, destroyedMessage); | ... | ... |
... | @@ -15,23 +15,8 @@ | ... | @@ -15,23 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.store.group.impl; | 16 | package org.onosproject.store.group.impl; |
17 | 17 | ||
18 | -import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; | 18 | +import com.google.common.collect.FluentIterable; |
19 | -import static org.onlab.util.Tools.groupedThreads; | 19 | +import com.google.common.collect.Iterables; |
20 | -import static org.slf4j.LoggerFactory.getLogger; | ||
21 | - | ||
22 | -import java.net.URI; | ||
23 | -import java.util.ArrayList; | ||
24 | -import java.util.HashMap; | ||
25 | -import java.util.List; | ||
26 | -import java.util.Objects; | ||
27 | -import java.util.concurrent.ConcurrentHashMap; | ||
28 | -import java.util.concurrent.ConcurrentMap; | ||
29 | -import java.util.concurrent.ExecutorService; | ||
30 | -import java.util.concurrent.Executors; | ||
31 | -import java.util.concurrent.atomic.AtomicInteger; | ||
32 | -import java.util.concurrent.atomic.AtomicLong; | ||
33 | -import java.util.stream.Collectors; | ||
34 | - | ||
35 | import org.apache.felix.scr.annotations.Activate; | 20 | import org.apache.felix.scr.annotations.Activate; |
36 | import org.apache.felix.scr.annotations.Component; | 21 | import org.apache.felix.scr.annotations.Component; |
37 | import org.apache.felix.scr.annotations.Deactivate; | 22 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -75,17 +60,32 @@ import org.onosproject.store.Timestamp; | ... | @@ -75,17 +60,32 @@ import org.onosproject.store.Timestamp; |
75 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 60 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
76 | import org.onosproject.store.cluster.messaging.ClusterMessage; | 61 | import org.onosproject.store.cluster.messaging.ClusterMessage; |
77 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | 62 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; |
78 | -import org.onosproject.store.ecmap.EventuallyConsistentMap; | ||
79 | -import org.onosproject.store.ecmap.EventuallyConsistentMapEvent; | ||
80 | -import org.onosproject.store.ecmap.EventuallyConsistentMapImpl; | ||
81 | -import org.onosproject.store.ecmap.EventuallyConsistentMapListener; | ||
82 | -import org.onosproject.store.impl.ClockService; | ||
83 | import org.onosproject.store.impl.MultiValuedTimestamp; | 63 | import org.onosproject.store.impl.MultiValuedTimestamp; |
84 | import org.onosproject.store.serializers.KryoNamespaces; | 64 | import org.onosproject.store.serializers.KryoNamespaces; |
65 | +import org.onosproject.store.service.ClockService; | ||
66 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
67 | +import org.onosproject.store.service.EventuallyConsistentMapBuilder; | ||
68 | +import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
69 | +import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
70 | +import org.onosproject.store.service.StorageService; | ||
85 | import org.slf4j.Logger; | 71 | import org.slf4j.Logger; |
86 | 72 | ||
87 | -import com.google.common.collect.FluentIterable; | 73 | +import java.net.URI; |
88 | -import com.google.common.collect.Iterables; | 74 | +import java.util.ArrayList; |
75 | +import java.util.HashMap; | ||
76 | +import java.util.List; | ||
77 | +import java.util.Objects; | ||
78 | +import java.util.concurrent.ConcurrentHashMap; | ||
79 | +import java.util.concurrent.ConcurrentMap; | ||
80 | +import java.util.concurrent.ExecutorService; | ||
81 | +import java.util.concurrent.Executors; | ||
82 | +import java.util.concurrent.atomic.AtomicInteger; | ||
83 | +import java.util.concurrent.atomic.AtomicLong; | ||
84 | +import java.util.stream.Collectors; | ||
85 | + | ||
86 | +import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; | ||
87 | +import static org.onlab.util.Tools.groupedThreads; | ||
88 | +import static org.slf4j.LoggerFactory.getLogger; | ||
89 | 89 | ||
90 | /** | 90 | /** |
91 | * Manages inventory of group entries using trivial in-memory implementation. | 91 | * Manages inventory of group entries using trivial in-memory implementation. |
... | @@ -108,6 +108,9 @@ public class DistributedGroupStore | ... | @@ -108,6 +108,9 @@ public class DistributedGroupStore |
108 | protected ClusterService clusterService; | 108 | protected ClusterService clusterService; |
109 | 109 | ||
110 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 110 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
111 | + protected StorageService storageService; | ||
112 | + | ||
113 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
111 | protected MastershipService mastershipService; | 114 | protected MastershipService mastershipService; |
112 | 115 | ||
113 | // Per device group table with (device id + app cookie) as key | 116 | // Per device group table with (device id + app cookie) as key |
... | @@ -192,31 +195,38 @@ public class DistributedGroupStore | ... | @@ -192,31 +195,38 @@ public class DistributedGroupStore |
192 | messageHandlingExecutor); | 195 | messageHandlingExecutor); |
193 | 196 | ||
194 | log.debug("Creating EC map groupstorekeymap"); | 197 | log.debug("Creating EC map groupstorekeymap"); |
195 | - groupStoreEntriesByKey = | 198 | + EventuallyConsistentMapBuilder<GroupStoreKeyMapKey, StoredGroupEntry> |
196 | - new EventuallyConsistentMapImpl<>("groupstorekeymap", | 199 | + keyMapBuilder = storageService.eventuallyConsistentMapBuilder(); |
197 | - clusterService, | 200 | + |
198 | - clusterCommunicator, | 201 | + groupStoreEntriesByKey = keyMapBuilder |
199 | - kryoBuilder, | 202 | + .withName("groupstorekeymap") |
200 | - new GroupStoreLogicalClockManager<>()); | 203 | + .withSerializer(kryoBuilder) |
204 | + .withClockService(new GroupStoreLogicalClockManager<>()) | ||
205 | + .build(); | ||
201 | log.trace("Current size {}", groupStoreEntriesByKey.size()); | 206 | log.trace("Current size {}", groupStoreEntriesByKey.size()); |
202 | 207 | ||
203 | log.debug("Creating EC map groupstoreidmap"); | 208 | log.debug("Creating EC map groupstoreidmap"); |
204 | - groupStoreEntriesById = | 209 | + EventuallyConsistentMapBuilder<GroupStoreIdMapKey, StoredGroupEntry> |
205 | - new EventuallyConsistentMapImpl<>("groupstoreidmap", | 210 | + idMapBuilder = storageService.eventuallyConsistentMapBuilder(); |
206 | - clusterService, | 211 | + |
207 | - clusterCommunicator, | 212 | + groupStoreEntriesById = idMapBuilder |
208 | - kryoBuilder, | 213 | + .withName("groupstoreidmap") |
209 | - new GroupStoreLogicalClockManager<>()); | 214 | + .withSerializer(kryoBuilder) |
215 | + .withClockService(new GroupStoreLogicalClockManager<>()) | ||
216 | + .build(); | ||
217 | + | ||
210 | groupStoreEntriesById.addListener(new GroupStoreIdMapListener()); | 218 | groupStoreEntriesById.addListener(new GroupStoreIdMapListener()); |
211 | log.trace("Current size {}", groupStoreEntriesById.size()); | 219 | log.trace("Current size {}", groupStoreEntriesById.size()); |
212 | 220 | ||
213 | log.debug("Creating EC map pendinggroupkeymap"); | 221 | log.debug("Creating EC map pendinggroupkeymap"); |
214 | - auditPendingReqQueue = | 222 | + EventuallyConsistentMapBuilder<GroupStoreKeyMapKey, StoredGroupEntry> |
215 | - new EventuallyConsistentMapImpl<>("pendinggroupkeymap", | 223 | + auditMapBuilder = storageService.eventuallyConsistentMapBuilder(); |
216 | - clusterService, | 224 | + |
217 | - clusterCommunicator, | 225 | + auditPendingReqQueue = auditMapBuilder |
218 | - kryoBuilder, | 226 | + .withName("pendinggroupkeymap") |
219 | - new GroupStoreLogicalClockManager<>()); | 227 | + .withSerializer(kryoBuilder) |
228 | + .withClockService(new GroupStoreLogicalClockManager<>()) | ||
229 | + .build(); | ||
220 | log.trace("Current size {}", auditPendingReqQueue.size()); | 230 | log.trace("Current size {}", auditPendingReqQueue.size()); |
221 | 231 | ||
222 | log.info("Started"); | 232 | log.info("Started"); | ... | ... |
... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
16 | package org.onosproject.store.impl; | 16 | package org.onosproject.store.impl; |
17 | 17 | ||
18 | import org.onosproject.store.Timestamp; | 18 | import org.onosproject.store.Timestamp; |
19 | +import org.onosproject.store.service.ClockService; | ||
19 | 20 | ||
20 | /** | 21 | /** |
21 | * A clock service which hands out wallclock-based timestamps. | 22 | * A clock service which hands out wallclock-based timestamps. | ... | ... |
... | @@ -36,14 +36,13 @@ import org.onosproject.net.intent.IntentStoreDelegate; | ... | @@ -36,14 +36,13 @@ import org.onosproject.net.intent.IntentStoreDelegate; |
36 | import org.onosproject.net.intent.Key; | 36 | import org.onosproject.net.intent.Key; |
37 | import org.onosproject.net.intent.PartitionService; | 37 | import org.onosproject.net.intent.PartitionService; |
38 | import org.onosproject.store.AbstractStore; | 38 | import org.onosproject.store.AbstractStore; |
39 | -import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
40 | -import org.onosproject.store.ecmap.EventuallyConsistentMap; | ||
41 | -import org.onosproject.store.ecmap.EventuallyConsistentMapEvent; | ||
42 | -import org.onosproject.store.ecmap.EventuallyConsistentMapImpl; | ||
43 | -import org.onosproject.store.ecmap.EventuallyConsistentMapListener; | ||
44 | import org.onosproject.store.impl.MultiValuedTimestamp; | 39 | import org.onosproject.store.impl.MultiValuedTimestamp; |
45 | import org.onosproject.store.impl.WallClockTimestamp; | 40 | import org.onosproject.store.impl.WallClockTimestamp; |
46 | import org.onosproject.store.serializers.KryoNamespaces; | 41 | import org.onosproject.store.serializers.KryoNamespaces; |
42 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
43 | +import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
44 | +import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
45 | +import org.onosproject.store.service.StorageService; | ||
47 | import org.slf4j.Logger; | 46 | import org.slf4j.Logger; |
48 | 47 | ||
49 | import java.util.Collection; | 48 | import java.util.Collection; |
... | @@ -52,7 +51,7 @@ import java.util.Objects; | ... | @@ -52,7 +51,7 @@ import java.util.Objects; |
52 | import java.util.stream.Collectors; | 51 | import java.util.stream.Collectors; |
53 | 52 | ||
54 | import static com.google.common.base.Preconditions.checkNotNull; | 53 | import static com.google.common.base.Preconditions.checkNotNull; |
55 | -import static org.onosproject.net.intent.IntentState.*; | 54 | +import static org.onosproject.net.intent.IntentState.PURGE_REQ; |
56 | import static org.slf4j.LoggerFactory.getLogger; | 55 | import static org.slf4j.LoggerFactory.getLogger; |
57 | 56 | ||
58 | /** | 57 | /** |
... | @@ -61,7 +60,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -61,7 +60,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
61 | */ | 60 | */ |
62 | //FIXME we should listen for leadership changes. if the local instance has just | 61 | //FIXME we should listen for leadership changes. if the local instance has just |
63 | // ... become a leader, scan the pending map and process those | 62 | // ... become a leader, scan the pending map and process those |
64 | -@Component(immediate = false, enabled = true) | 63 | +@Component(immediate = true, enabled = true) |
65 | @Service | 64 | @Service |
66 | public class GossipIntentStore | 65 | public class GossipIntentStore |
67 | extends AbstractStore<IntentEvent, IntentStoreDelegate> | 66 | extends AbstractStore<IntentEvent, IntentStoreDelegate> |
... | @@ -76,10 +75,10 @@ public class GossipIntentStore | ... | @@ -76,10 +75,10 @@ public class GossipIntentStore |
76 | private EventuallyConsistentMap<Key, IntentData> pendingMap; | 75 | private EventuallyConsistentMap<Key, IntentData> pendingMap; |
77 | 76 | ||
78 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 77 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
79 | - protected ClusterCommunicationService clusterCommunicator; | 78 | + protected ClusterService clusterService; |
80 | 79 | ||
81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 80 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
82 | - protected ClusterService clusterService; | 81 | + protected StorageService storageService; |
83 | 82 | ||
84 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 83 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
85 | protected PartitionService partitionService; | 84 | protected PartitionService partitionService; |
... | @@ -92,19 +91,19 @@ public class GossipIntentStore | ... | @@ -92,19 +91,19 @@ public class GossipIntentStore |
92 | .register(MultiValuedTimestamp.class) | 91 | .register(MultiValuedTimestamp.class) |
93 | .register(WallClockTimestamp.class); | 92 | .register(WallClockTimestamp.class); |
94 | 93 | ||
95 | - currentMap = new EventuallyConsistentMapImpl<>("intent-current", | 94 | + currentMap = storageService.<Key, IntentData>eventuallyConsistentMapBuilder() |
96 | - clusterService, | 95 | + .withName("intent-current") |
97 | - clusterCommunicator, | 96 | + .withSerializer(intentSerializer) |
98 | - intentSerializer, | 97 | + .withClockService(new IntentDataLogicalClockManager<>()) |
99 | - new IntentDataLogicalClockManager<>(), | 98 | + .withPeerUpdateFunction((key, intentData) -> getPeerNodes(key, intentData)) |
100 | - (key, intentData) -> getPeerNodes(key, intentData)); | 99 | + .build(); |
101 | - | 100 | + |
102 | - pendingMap = new EventuallyConsistentMapImpl<>("intent-pending", | 101 | + pendingMap = storageService.<Key, IntentData>eventuallyConsistentMapBuilder() |
103 | - clusterService, | 102 | + .withName("intent-pending") |
104 | - clusterCommunicator, | 103 | + .withSerializer(intentSerializer) |
105 | - intentSerializer, | 104 | + .withClockService(new IntentDataClockManager<>()) |
106 | - new IntentDataClockManager<>(), | 105 | + .withPeerUpdateFunction((key, intentData) -> getPeerNodes(key, intentData)) |
107 | - (key, intentData) -> getPeerNodes(key, intentData)); | 106 | + .build(); |
108 | 107 | ||
109 | currentMap.addListener(new InternalCurrentListener()); | 108 | currentMap.addListener(new InternalCurrentListener()); |
110 | pendingMap.addListener(new InternalPendingListener()); | 109 | pendingMap.addListener(new InternalPendingListener()); | ... | ... |
... | @@ -17,7 +17,7 @@ package org.onosproject.store.intent.impl; | ... | @@ -17,7 +17,7 @@ package org.onosproject.store.intent.impl; |
17 | 17 | ||
18 | import org.onosproject.net.intent.IntentData; | 18 | import org.onosproject.net.intent.IntentData; |
19 | import org.onosproject.store.Timestamp; | 19 | import org.onosproject.store.Timestamp; |
20 | -import org.onosproject.store.impl.ClockService; | 20 | +import org.onosproject.store.service.ClockService; |
21 | import org.onosproject.store.impl.MultiValuedTimestamp; | 21 | import org.onosproject.store.impl.MultiValuedTimestamp; |
22 | 22 | ||
23 | /** | 23 | /** | ... | ... |
... | @@ -17,7 +17,7 @@ package org.onosproject.store.intent.impl; | ... | @@ -17,7 +17,7 @@ package org.onosproject.store.intent.impl; |
17 | 17 | ||
18 | import org.onosproject.net.intent.IntentData; | 18 | import org.onosproject.net.intent.IntentData; |
19 | import org.onosproject.store.Timestamp; | 19 | import org.onosproject.store.Timestamp; |
20 | -import org.onosproject.store.impl.ClockService; | 20 | +import org.onosproject.store.service.ClockService; |
21 | import org.onosproject.store.impl.MultiValuedTimestamp; | 21 | import org.onosproject.store.impl.MultiValuedTimestamp; |
22 | 22 | ||
23 | import java.util.concurrent.atomic.AtomicLong; | 23 | import java.util.concurrent.atomic.AtomicLong; | ... | ... |
... | @@ -34,10 +34,13 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ... | @@ -34,10 +34,13 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
34 | import org.onosproject.store.cluster.messaging.ClusterMessage; | 34 | import org.onosproject.store.cluster.messaging.ClusterMessage; |
35 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | 35 | import org.onosproject.store.cluster.messaging.ClusterMessageHandler; |
36 | import org.onosproject.store.cluster.messaging.MessageSubject; | 36 | import org.onosproject.store.cluster.messaging.MessageSubject; |
37 | -import org.onosproject.store.impl.ClockService; | 37 | +import org.onosproject.store.service.ClockService; |
38 | import org.onosproject.store.impl.WallClockTimestamp; | 38 | import org.onosproject.store.impl.WallClockTimestamp; |
39 | import org.onosproject.store.serializers.KryoNamespaces; | 39 | import org.onosproject.store.serializers.KryoNamespaces; |
40 | import org.onosproject.store.serializers.KryoSerializer; | 40 | import org.onosproject.store.serializers.KryoSerializer; |
41 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
42 | +import org.onosproject.store.service.EventuallyConsistentMapEvent; | ||
43 | +import org.onosproject.store.service.EventuallyConsistentMapListener; | ||
41 | 44 | ||
42 | import java.io.IOException; | 45 | import java.io.IOException; |
43 | import java.util.ArrayList; | 46 | import java.util.ArrayList; |
... | @@ -134,10 +137,13 @@ public class EventuallyConsistentMapImplTest { | ... | @@ -134,10 +137,13 @@ public class EventuallyConsistentMapImplTest { |
134 | .register(KryoNamespaces.API) | 137 | .register(KryoNamespaces.API) |
135 | .register(TestTimestamp.class); | 138 | .register(TestTimestamp.class); |
136 | 139 | ||
137 | - ecMap = new EventuallyConsistentMapImpl<>(MAP_NAME, clusterService, | 140 | + ecMap = new EventuallyConsistentMapBuilderImpl<>( |
138 | - clusterCommunicator, | 141 | + clusterService, clusterCommunicator) |
139 | - serializer, clockService) | 142 | + .withName(MAP_NAME) |
140 | - .withBroadcastMessageExecutor(MoreExecutors.newDirectExecutorService()); | 143 | + .withSerializer(serializer) |
144 | + .withClockService(clockService) | ||
145 | + .withCommunicationExecutor(MoreExecutors.newDirectExecutorService()) | ||
146 | + .build(); | ||
141 | 147 | ||
142 | // Reset ready for tests to add their own expectations | 148 | // Reset ready for tests to add their own expectations |
143 | reset(clusterCommunicator); | 149 | reset(clusterCommunicator); | ... | ... |
-
Please register or login to post a comment