blob: 2fc6fd833f8129be8b57e0455263d7a80c11b1a0 [file] [log] [blame]
Jonathan Hart5573d322015-01-21 10:13:25 -08001/*
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 */
16package org.onosproject.store.intent.impl;
17
Jonathan Hart5573d322015-01-21 10:13:25 -080018import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onlab.util.KryoNamespace;
25import org.onosproject.cluster.ClusterService;
Jonathan Hart5573d322015-01-21 10:13:25 -080026import org.onosproject.net.intent.BatchWrite;
27import org.onosproject.net.intent.Intent;
Jonathan Hart74c83132015-02-02 18:37:57 -080028import org.onosproject.net.intent.IntentData;
Jonathan Hart5573d322015-01-21 10:13:25 -080029import org.onosproject.net.intent.IntentEvent;
Jonathan Hart5573d322015-01-21 10:13:25 -080030import org.onosproject.net.intent.IntentState;
31import org.onosproject.net.intent.IntentStore;
32import org.onosproject.net.intent.IntentStoreDelegate;
Jonathan Hart74c83132015-02-02 18:37:57 -080033import org.onosproject.net.intent.Key;
Jonathan Hart5573d322015-01-21 10:13:25 -080034import org.onosproject.store.AbstractStore;
Jonathan Hart5573d322015-01-21 10:13:25 -080035import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
Jonathan Hart539a6462015-01-27 17:05:43 -080036import org.onosproject.store.impl.EventuallyConsistentMap;
37import org.onosproject.store.impl.EventuallyConsistentMapEvent;
38import org.onosproject.store.impl.EventuallyConsistentMapImpl;
39import org.onosproject.store.impl.EventuallyConsistentMapListener;
40import org.onosproject.store.impl.WallclockClockManager;
41import org.onosproject.store.serializers.KryoNamespaces;
Jonathan Hart5573d322015-01-21 10:13:25 -080042import org.slf4j.Logger;
43
Jonathan Hart5573d322015-01-21 10:13:25 -080044import java.util.List;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080045import java.util.stream.Collectors;
Jonathan Hart5573d322015-01-21 10:13:25 -080046
Jonathan Hart5573d322015-01-21 10:13:25 -080047import static org.slf4j.LoggerFactory.getLogger;
48
49/**
50 * Manages inventory of Intents in a distributed data store that uses optimistic
51 * replication and gossip based techniques.
52 */
Brian O'Connorb488b192015-02-06 17:58:58 -080053@Component(immediate = false, enabled = false)
Jonathan Hart5573d322015-01-21 10:13:25 -080054@Service
55public class GossipIntentStore
56 extends AbstractStore<IntentEvent, IntentStoreDelegate>
57 implements IntentStore {
58
59 private final Logger log = getLogger(getClass());
60
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080061 /*private EventuallyConsistentMap<IntentId, Intent> intents;
Jonathan Hart5573d322015-01-21 10:13:25 -080062
Jonathan Hart539a6462015-01-27 17:05:43 -080063 private EventuallyConsistentMap<IntentId, IntentState> intentStates;
Jonathan Hart5573d322015-01-21 10:13:25 -080064
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080065 private EventuallyConsistentMap<IntentId, List<Intent>> installables;*/
66
67 // Map of intent key => current intent state
68 private EventuallyConsistentMap<Key, IntentData> currentState;
Jonathan Hart5573d322015-01-21 10:13:25 -080069
Jonathan Hart74c83132015-02-02 18:37:57 -080070 // Map of intent key => pending intent operation
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080071 private EventuallyConsistentMap<Key, IntentData> pending;
Jonathan Hart74c83132015-02-02 18:37:57 -080072
Jonathan Hart5573d322015-01-21 10:13:25 -080073 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 protected ClusterCommunicationService clusterCommunicator;
75
76 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
77 protected ClusterService clusterService;
78
Jonathan Hart74c83132015-02-02 18:37:57 -080079 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 protected PartitionService partitionService;
81
Jonathan Hart5573d322015-01-21 10:13:25 -080082 @Activate
83 public void activate() {
Jonathan Hart539a6462015-01-27 17:05:43 -080084 KryoNamespace.Builder intentSerializer = KryoNamespace.newBuilder()
Jonathan Hart45727852015-01-28 13:35:54 -080085 .register(KryoNamespaces.API);
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080086 /*intents = new EventuallyConsistentMapImpl<>("intents", clusterService,
Jonathan Hart539a6462015-01-27 17:05:43 -080087 clusterCommunicator,
88 intentSerializer,
89 new WallclockClockManager<>());
Jonathan Hart5573d322015-01-21 10:13:25 -080090
Jonathan Hart539a6462015-01-27 17:05:43 -080091 intentStates = new EventuallyConsistentMapImpl<>("intent-states",
92 clusterService,
93 clusterCommunicator,
94 intentSerializer,
95 new WallclockClockManager<>());
Jonathan Hart5573d322015-01-21 10:13:25 -080096
Jonathan Hart539a6462015-01-27 17:05:43 -080097 installables = new EventuallyConsistentMapImpl<>("intent-installables",
98 clusterService,
99 clusterCommunicator,
100 intentSerializer,
101 new WallclockClockManager<>());
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800102 */
103
104 currentState = new EventuallyConsistentMapImpl<>("intent-current",
105 clusterService,
106 clusterCommunicator,
107 intentSerializer,
108 new WallclockClockManager<>());
Jonathan Hart5573d322015-01-21 10:13:25 -0800109
Jonathan Hart74c83132015-02-02 18:37:57 -0800110 pending = new EventuallyConsistentMapImpl<>("intent-pending",
111 clusterService,
112 clusterCommunicator,
113 intentSerializer, // TODO
114 new WallclockClockManager<>());
115
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800116 currentState.addListener(new InternalIntentStatesListener());
Jonathan Hart74c83132015-02-02 18:37:57 -0800117 pending.addListener(new InternalPendingListener());
Jonathan Hart5573d322015-01-21 10:13:25 -0800118
119 log.info("Started");
120 }
121
122 @Deactivate
123 public void deactivate() {
Jonathan Hart74c83132015-02-02 18:37:57 -0800124
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800125 /*intents.destroy();
Jonathan Hart539a6462015-01-27 17:05:43 -0800126 intentStates.destroy();
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800127 installables.destroy();*/
128 currentState.destroy();
Jonathan Hart74c83132015-02-02 18:37:57 -0800129 pending.destroy();
Jonathan Hart5573d322015-01-21 10:13:25 -0800130
131 log.info("Stopped");
132 }
133
134 @Override
135 public long getIntentCount() {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800136 //return intents.size();
137 return currentState.size();
Jonathan Hart5573d322015-01-21 10:13:25 -0800138 }
139
140 @Override
141 public Iterable<Intent> getIntents() {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800142 return currentState.values().stream()
143 .map(IntentData::intent)
144 .collect(Collectors.toList());
Jonathan Hart5573d322015-01-21 10:13:25 -0800145 }
146
147 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800148 public IntentState getIntentState(Key intentKey) {
149 // TODO: implement this
150 return IntentState.FAILED;
Jonathan Hart5573d322015-01-21 10:13:25 -0800151 }
152
153 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800154 public List<Intent> getInstallableIntents(Key intentKey) {
155 // TODO: implement this or delete class
156 return null;
157 /*
Jonathan Hart539a6462015-01-27 17:05:43 -0800158 return installables.get(intentId);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800159 */
Jonathan Hart5573d322015-01-21 10:13:25 -0800160 }
161
162 @Override
Jonathan Hart5573d322015-01-21 10:13:25 -0800163 public List<BatchWrite.Operation> batchWrite(BatchWrite batch) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800164 /*
Jonathan Hart5573d322015-01-21 10:13:25 -0800165 List<BatchWrite.Operation> failed = new ArrayList<>();
166
167 for (BatchWrite.Operation op : batch.operations()) {
168 switch (op.type()) {
169 case CREATE_INTENT:
170 checkArgument(op.args().size() == 1,
171 "CREATE_INTENT takes 1 argument. %s", op);
172 Intent intent = op.arg(0);
173
Jonathan Hart539a6462015-01-27 17:05:43 -0800174 intents.put(intent.id(), intent);
175 intentStates.put(intent.id(), INSTALL_REQ);
Jonathan Hart5573d322015-01-21 10:13:25 -0800176
Jonathan Hart74c83132015-02-02 18:37:57 -0800177 // TODO remove from pending?
178
179
Jonathan Hart5573d322015-01-21 10:13:25 -0800180 break;
181 case REMOVE_INTENT:
182 checkArgument(op.args().size() == 1,
183 "REMOVE_INTENT takes 1 argument. %s", op);
Jonathan Hart539a6462015-01-27 17:05:43 -0800184 IntentId intentId = op.arg(0);
185
186 intents.remove(intentId);
187 intentStates.remove(intentId);
188 installables.remove(intentId);
Jonathan Hart5573d322015-01-21 10:13:25 -0800189
190 break;
191 case SET_STATE:
192 checkArgument(op.args().size() == 2,
193 "SET_STATE takes 2 arguments. %s", op);
194 intent = op.arg(0);
195 IntentState newState = op.arg(1);
196
Jonathan Hart539a6462015-01-27 17:05:43 -0800197 intentStates.put(intent.id(), newState);
Jonathan Hart5573d322015-01-21 10:13:25 -0800198
199 break;
200 case SET_INSTALLABLE:
201 checkArgument(op.args().size() == 2,
202 "SET_INSTALLABLE takes 2 arguments. %s", op);
203 intentId = op.arg(0);
204 List<Intent> installableIntents = op.arg(1);
205
Jonathan Hart539a6462015-01-27 17:05:43 -0800206 installables.put(intentId, installableIntents);
Jonathan Hart5573d322015-01-21 10:13:25 -0800207
208 break;
209 case REMOVE_INSTALLED:
210 checkArgument(op.args().size() == 1,
211 "REMOVE_INSTALLED takes 1 argument. %s", op);
212 intentId = op.arg(0);
Jonathan Hart539a6462015-01-27 17:05:43 -0800213 installables.remove(intentId);
Jonathan Hart5573d322015-01-21 10:13:25 -0800214 break;
215 default:
216 log.warn("Unknown Operation encountered: {}", op);
217 failed.add(op);
218 break;
219 }
220 }
221
Jonathan Hart5573d322015-01-21 10:13:25 -0800222 return failed;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800223 */
224 return null;
Jonathan Hart5573d322015-01-21 10:13:25 -0800225 }
226
Jonathan Hart74c83132015-02-02 18:37:57 -0800227 @Override
228 public void write(IntentData newData) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800229 // Only the master is modifying the current state. Therefore assume
230 // this always succeeds
231 currentState.put(newData.key(), newData);
232
233 // if current.put succeeded
234 //pending.remove(newData.key(), newData);
235
236 try {
237 notifyDelegate(IntentEvent.getEvent(newData));
238 } catch (IllegalArgumentException e) {
239 //no-op
240 log.trace("ignore this exception: {}", e);
241 }
Jonathan Hart74c83132015-02-02 18:37:57 -0800242 }
243
244 @Override
245 public void batchWrite(Iterable<IntentData> updates) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800246 updates.forEach(this::write);
247 }
248
249 @Override
250 public Intent getIntent(Key key) {
251 IntentData data = currentState.get(key);
252 if (data != null) {
253 return data.intent();
254 }
255 return null;
Jonathan Hart74c83132015-02-02 18:37:57 -0800256 }
257
258 @Override
Jonathan Hart74c83132015-02-02 18:37:57 -0800259 public IntentData getIntentData(Key key) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800260 return currentState.get(key);
Jonathan Hart74c83132015-02-02 18:37:57 -0800261 }
262
263 @Override
264 public void addPending(IntentData data) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800265 pending.put(data.key(), data);
Jonathan Hart74c83132015-02-02 18:37:57 -0800266 }
267
268 @Override
269 public boolean isMaster(Intent intent) {
270 // TODO
271 //return partitionService.isMine(intent.key());
272 return false;
273 }
274
Jonathan Hart5573d322015-01-21 10:13:25 -0800275 private void notifyDelegateIfNotNull(IntentEvent event) {
276 if (event != null) {
277 notifyDelegate(event);
278 }
279 }
280
Jonathan Hart539a6462015-01-27 17:05:43 -0800281 private final class InternalIntentStatesListener implements
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800282 EventuallyConsistentMapListener<Key, IntentData> {
Jonathan Hart5573d322015-01-21 10:13:25 -0800283 @Override
Jonathan Hart539a6462015-01-27 17:05:43 -0800284 public void event(
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800285 EventuallyConsistentMapEvent<Key, IntentData> event) {
Jonathan Hart539a6462015-01-27 17:05:43 -0800286 if (event.type() == EventuallyConsistentMapEvent.Type.PUT) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800287 // TODO check event send logic
Jonathan Hart539a6462015-01-27 17:05:43 -0800288 IntentEvent externalEvent;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800289 IntentData intentData = currentState.get(event.key()); // TODO OK if this is null?
Jonathan Hart5573d322015-01-21 10:13:25 -0800290
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800291 /*
Jonathan Hart5573d322015-01-21 10:13:25 -0800292 try {
Jonathan Hart539a6462015-01-27 17:05:43 -0800293 externalEvent = IntentEvent.getEvent(event.value(), intent);
294 } catch (IllegalArgumentException e) {
295 externalEvent = null;
Jonathan Hart5573d322015-01-21 10:13:25 -0800296 }
Jonathan Hart539a6462015-01-27 17:05:43 -0800297
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800298 notifyDelegateIfNotNull(externalEvent);*/
Jonathan Hart539a6462015-01-27 17:05:43 -0800299 }
Jonathan Hart5573d322015-01-21 10:13:25 -0800300 }
301 }
302
Jonathan Hart74c83132015-02-02 18:37:57 -0800303 private final class InternalPendingListener implements
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800304 EventuallyConsistentMapListener<Key, IntentData> {
Jonathan Hart74c83132015-02-02 18:37:57 -0800305 @Override
306 public void event(
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800307 EventuallyConsistentMapEvent<Key, IntentData> event) {
Jonathan Hart74c83132015-02-02 18:37:57 -0800308 if (event.type() == EventuallyConsistentMapEvent.Type.PUT) {
309 // The pending intents map has been updated. If we are master for
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800310 // this intent's partition, notify the Manager that it should do
Jonathan Hart74c83132015-02-02 18:37:57 -0800311 // some work.
312 if (isMaster(event.value().intent())) {
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -0800313 if (delegate != null) {
314 delegate.process(event.value());
315 }
Jonathan Hart74c83132015-02-02 18:37:57 -0800316 }
317 }
318 }
319 }
320
Jonathan Hart5573d322015-01-21 10:13:25 -0800321}
322