blob: 3699df6364154e0a209ac95d99d230e915640848 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.intent.impl;
Brian O'Connor66630c82014-10-02 21:08:19 -070017
Brian O'Connor64a0369d2015-02-20 22:02:59 -080018import com.google.common.collect.ImmutableList;
Brian O'Connor66630c82014-10-02 21:08:19 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.core.CoreService;
26import org.onosproject.core.IdGenerator;
27import org.onosproject.event.AbstractListenerRegistry;
28import org.onosproject.event.EventDeliveryService;
Brian O'Connor0e271dc2015-02-04 18:20:25 -080029import org.onosproject.net.flow.FlowRuleOperations;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.flow.FlowRuleService;
31import org.onosproject.net.intent.Intent;
32import org.onosproject.net.intent.IntentBatchDelegate;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.intent.IntentCompiler;
Brian O'Connorcff03322015-02-03 15:28:59 -080034import org.onosproject.net.intent.IntentData;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.intent.IntentEvent;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.intent.IntentExtensionService;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.intent.IntentInstaller;
38import org.onosproject.net.intent.IntentListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.intent.IntentService;
40import org.onosproject.net.intent.IntentState;
41import org.onosproject.net.intent.IntentStore;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.intent.IntentStoreDelegate;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080043import org.onosproject.net.intent.Key;
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -080044import org.onosproject.net.intent.impl.phase.CompilingFailed;
45import org.onosproject.net.intent.impl.phase.FinalIntentProcessPhase;
46import org.onosproject.net.intent.impl.phase.InstallRequest;
47import org.onosproject.net.intent.impl.phase.IntentProcessPhase;
48import org.onosproject.net.intent.impl.phase.WithdrawRequest;
49import org.onosproject.net.intent.impl.phase.Withdrawn;
Brian O'Connor66630c82014-10-02 21:08:19 -070050import org.slf4j.Logger;
51
Brian O'Connor64a0369d2015-02-20 22:02:59 -080052import java.util.Collection;
Brian O'Connor64a0369d2015-02-20 22:02:59 -080053import java.util.EnumSet;
Brian O'Connor64a0369d2015-02-20 22:02:59 -080054import java.util.List;
55import java.util.Map;
56import java.util.Optional;
57import java.util.concurrent.Callable;
Brian O'Connor64a0369d2015-02-20 22:02:59 -080058import java.util.concurrent.ExecutionException;
59import java.util.concurrent.ExecutorService;
60import java.util.concurrent.Future;
61import java.util.stream.Collectors;
Brian O'Connorfa81eae2014-10-30 13:20:05 -070062
Brian O'Connorfa81eae2014-10-30 13:20:05 -070063import static com.google.common.base.Preconditions.checkNotNull;
Yuta HIGUCHIc2bf3d82014-11-28 18:50:41 -080064import static java.util.concurrent.Executors.newFixedThreadPool;
Brian O'Connordb15b042015-02-04 14:59:28 -080065import static java.util.concurrent.Executors.newSingleThreadExecutor;
Brian O'Connorbdc7f002015-02-18 20:49:41 -080066import static org.onlab.util.Tools.groupedThreads;
Brian O'Connore2eac102015-02-12 18:30:22 -080067import static org.onlab.util.Tools.isNullOrEmpty;
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -080068import static org.onosproject.net.intent.IntentState.FAILED;
69import static org.onosproject.net.intent.IntentState.INSTALL_REQ;
70import static org.onosproject.net.intent.IntentState.WITHDRAWN;
71import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ;
Brian O'Connorfa81eae2014-10-30 13:20:05 -070072import static org.slf4j.LoggerFactory.getLogger;
Brian O'Connor66630c82014-10-02 21:08:19 -070073
74/**
75 * An implementation of Intent Manager.
76 */
77@Component(immediate = true)
78@Service
79public class IntentManager
80 implements IntentService, IntentExtensionService {
Sho SHIMIZU8b5051d2014-11-05 11:24:13 -080081 private static final Logger log = getLogger(IntentManager.class);
Brian O'Connor66630c82014-10-02 21:08:19 -070082
83 public static final String INTENT_NULL = "Intent cannot be null";
Ray Milkeyf9af43c2015-02-09 16:45:48 -080084 public static final String INTENT_ID_NULL = "Intent key cannot be null";
Brian O'Connor66630c82014-10-02 21:08:19 -070085
Yuta HIGUCHIc2bf3d82014-11-28 18:50:41 -080086 private static final int NUM_THREADS = 12;
87
Brian O'Connor7a71d5d2014-12-02 00:12:27 -080088 private static final EnumSet<IntentState> RECOMPILE
89 = EnumSet.of(INSTALL_REQ, FAILED, WITHDRAW_REQ);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -080090
Brian O'Connor66630c82014-10-02 21:08:19 -070091 private final AbstractListenerRegistry<IntentEvent, IntentListener>
tom95329eb2014-10-06 08:40:06 -070092 listenerRegistry = new AbstractListenerRegistry<>();
Brian O'Connor66630c82014-10-02 21:08:19 -070093
Brian O'Connor520c0522014-11-23 23:50:47 -080094 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected CoreService coreService;
Brian O'Connor66630c82014-10-02 21:08:19 -070096
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected IntentStore store;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom85258ee2014-10-07 00:10:02 -0700101 protected ObjectiveTrackerService trackerService;
tom95329eb2014-10-06 08:40:06 -0700102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Brian O'Connor66630c82014-10-02 21:08:19 -0700104 protected EventDeliveryService eventDispatcher;
105
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800106 // TODO: make this protected due to short term hack for ONOS-1051
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800108 public FlowRuleService flowRuleService;
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700109
Brian O'Connor520c0522014-11-23 23:50:47 -0800110
Brian O'Connordb15b042015-02-04 14:59:28 -0800111 private ExecutorService batchExecutor;
112 private ExecutorService workerExecutor;
Brian O'Connor520c0522014-11-23 23:50:47 -0800113
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800114 private final CompilerRegistry compilerRegistry = new CompilerRegistry();
115 private final InstallerRegistry installerRegistry = new InstallerRegistry();
116 private final InternalIntentProcessor processor = new InternalIntentProcessor();
Brian O'Connor520c0522014-11-23 23:50:47 -0800117 private final IntentStoreDelegate delegate = new InternalStoreDelegate();
118 private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate();
119 private final IntentBatchDelegate batchDelegate = new InternalBatchDelegate();
120 private IdGenerator idGenerator;
121
Brian O'Connorb499b352015-02-03 16:46:15 -0800122 private final IntentAccumulator accumulator = new IntentAccumulator(batchDelegate);
Brian O'Connorcff03322015-02-03 15:28:59 -0800123
Brian O'Connor66630c82014-10-02 21:08:19 -0700124 @Activate
125 public void activate() {
126 store.setDelegate(delegate);
tom95329eb2014-10-06 08:40:06 -0700127 trackerService.setDelegate(topoDelegate);
Brian O'Connor66630c82014-10-02 21:08:19 -0700128 eventDispatcher.addSink(IntentEvent.class, listenerRegistry);
Brian O'Connorbdc7f002015-02-18 20:49:41 -0800129 batchExecutor = newSingleThreadExecutor(groupedThreads("onos/intent", "batch"));
130 workerExecutor = newFixedThreadPool(NUM_THREADS, groupedThreads("onos/intent", "worker-%d"));
Brian O'Connor520c0522014-11-23 23:50:47 -0800131 idGenerator = coreService.getIdGenerator("intent-ids");
132 Intent.bindIdGenerator(idGenerator);
Brian O'Connor66630c82014-10-02 21:08:19 -0700133 log.info("Started");
134 }
135
136 @Deactivate
137 public void deactivate() {
138 store.unsetDelegate(delegate);
tom95329eb2014-10-06 08:40:06 -0700139 trackerService.unsetDelegate(topoDelegate);
Brian O'Connor66630c82014-10-02 21:08:19 -0700140 eventDispatcher.removeSink(IntentEvent.class);
Brian O'Connordb15b042015-02-04 14:59:28 -0800141 batchExecutor.shutdown();
Brian O'Connor520c0522014-11-23 23:50:47 -0800142 Intent.unbindIdGenerator(idGenerator);
Brian O'Connor66630c82014-10-02 21:08:19 -0700143 log.info("Stopped");
144 }
145
146 @Override
147 public void submit(Intent intent) {
148 checkNotNull(intent, INTENT_NULL);
Brian O'Connorcff03322015-02-03 15:28:59 -0800149 IntentData data = new IntentData(intent, IntentState.INSTALL_REQ, null);
Brian O'Connorcff03322015-02-03 15:28:59 -0800150 store.addPending(data);
Brian O'Connor66630c82014-10-02 21:08:19 -0700151 }
152
153 @Override
154 public void withdraw(Intent intent) {
155 checkNotNull(intent, INTENT_NULL);
Brian O'Connorcff03322015-02-03 15:28:59 -0800156 IntentData data = new IntentData(intent, IntentState.WITHDRAW_REQ, null);
Brian O'Connorcff03322015-02-03 15:28:59 -0800157 store.addPending(data);
Brian O'Connor66630c82014-10-02 21:08:19 -0700158 }
159
Brian O'Connor66630c82014-10-02 21:08:19 -0700160 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800161 public Intent getIntent(Key key) {
162 return store.getIntent(key);
163 }
164
165 @Override
Brian O'Connor66630c82014-10-02 21:08:19 -0700166 public Iterable<Intent> getIntents() {
167 return store.getIntents();
168 }
169
170 @Override
171 public long getIntentCount() {
172 return store.getIntentCount();
173 }
174
175 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800176 public IntentState getIntentState(Key intentKey) {
177 checkNotNull(intentKey, INTENT_ID_NULL);
178 return store.getIntentState(intentKey);
Brian O'Connor66630c82014-10-02 21:08:19 -0700179 }
180
181 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800182 public List<Intent> getInstallableIntents(Key intentKey) {
183 checkNotNull(intentKey, INTENT_ID_NULL);
184 return store.getInstallableIntents(intentKey);
Thomas Vachuska10d4abc2014-10-21 12:47:26 -0700185 }
186
187 @Override
Brian O'Connorbe28a872015-02-19 21:44:37 -0800188 public boolean isLocal(Key intentKey) {
189 return store.isMaster(intentKey);
190 }
191
192 @Override
Brian O'Connor66630c82014-10-02 21:08:19 -0700193 public void addListener(IntentListener listener) {
194 listenerRegistry.addListener(listener);
195 }
196
197 @Override
198 public void removeListener(IntentListener listener) {
199 listenerRegistry.removeListener(listener);
200 }
201
202 @Override
203 public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800204 compilerRegistry.registerCompiler(cls, compiler);
Brian O'Connor66630c82014-10-02 21:08:19 -0700205 }
206
207 @Override
208 public <T extends Intent> void unregisterCompiler(Class<T> cls) {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800209 compilerRegistry.unregisterCompiler(cls);
Brian O'Connor66630c82014-10-02 21:08:19 -0700210 }
211
212 @Override
213 public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800214 return compilerRegistry.getCompilers();
Brian O'Connor66630c82014-10-02 21:08:19 -0700215 }
216
217 @Override
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700218 public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800219 installerRegistry.registerInstaller(cls, installer);
Brian O'Connor66630c82014-10-02 21:08:19 -0700220 }
221
222 @Override
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700223 public <T extends Intent> void unregisterInstaller(Class<T> cls) {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800224 installerRegistry.unregisterInstaller(cls);
Brian O'Connor66630c82014-10-02 21:08:19 -0700225 }
226
227 @Override
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700228 public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800229 return installerRegistry.getInstallers();
Brian O'Connor66630c82014-10-02 21:08:19 -0700230 }
231
Brian O'Connor66630c82014-10-02 21:08:19 -0700232 // Store delegate to re-post events emitted from the store.
233 private class InternalStoreDelegate implements IntentStoreDelegate {
234 @Override
235 public void notify(IntentEvent event) {
tom85258ee2014-10-07 00:10:02 -0700236 eventDispatcher.post(event);
Brian O'Connor66630c82014-10-02 21:08:19 -0700237 }
Brian O'Connorea4d7d12015-01-28 16:37:46 -0800238
239 @Override
Brian O'Connorcff03322015-02-03 15:28:59 -0800240 public void process(IntentData data) {
241 accumulator.add(data);
Brian O'Connorea4d7d12015-01-28 16:37:46 -0800242 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700243 }
244
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800245 private void buildAndSubmitBatches(Iterable<Key> intentKeys,
Brian O'Connor72a034c2014-11-26 18:24:23 -0800246 boolean compileAllFailed) {
Brian O'Connor72a034c2014-11-26 18:24:23 -0800247 // Attempt recompilation of the specified intents first.
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800248 for (Key key : intentKeys) {
249 Intent intent = store.getIntent(key);
Brian O'Connor72a034c2014-11-26 18:24:23 -0800250 if (intent == null) {
251 continue;
252 }
Brian O'Connor03406a42015-02-03 17:28:57 -0800253 submit(intent);
Brian O'Connor72a034c2014-11-26 18:24:23 -0800254 }
255
256 if (compileAllFailed) {
257 // If required, compile all currently failed intents.
258 for (Intent intent : getIntents()) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800259 IntentState state = getIntentState(intent.key());
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800260 if (RECOMPILE.contains(state)) {
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800261 if (state == WITHDRAW_REQ) {
Brian O'Connor03406a42015-02-03 17:28:57 -0800262 withdraw(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800263 } else {
Brian O'Connor03406a42015-02-03 17:28:57 -0800264 submit(intent);
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800265 }
Brian O'Connor72a034c2014-11-26 18:24:23 -0800266 }
267 }
268 }
269
Brian O'Connorb499b352015-02-03 16:46:15 -0800270 //FIXME
271// for (ApplicationId appId : batches.keySet()) {
272// if (batchService.isLocalLeader(appId)) {
273// execute(batches.get(appId).build());
274// }
275// }
Brian O'Connor72a034c2014-11-26 18:24:23 -0800276 }
277
tom95329eb2014-10-06 08:40:06 -0700278 // Topology change delegate
279 private class InternalTopoChangeDelegate implements TopologyChangeDelegate {
280 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800281 public void triggerCompile(Iterable<Key> intentKeys,
tom85258ee2014-10-07 00:10:02 -0700282 boolean compileAllFailed) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800283 buildAndSubmitBatches(intentKeys, compileAllFailed);
tom95329eb2014-10-06 08:40:06 -0700284 }
tom95329eb2014-10-06 08:40:06 -0700285 }
tom85258ee2014-10-07 00:10:02 -0700286
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800287 private IntentProcessPhase createIntentUpdate(IntentData intentData) {
Sho SHIMIZU95a7baf2015-02-12 09:15:57 -0800288 IntentData current = store.getIntentData(intentData.key());
Brian O'Connorb499b352015-02-03 16:46:15 -0800289 switch (intentData.state()) {
290 case INSTALL_REQ:
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800291 return new InstallRequest(processor, intentData, Optional.ofNullable(current));
Brian O'Connorb499b352015-02-03 16:46:15 -0800292 case WITHDRAW_REQ:
Brian O'Connore2eac102015-02-12 18:30:22 -0800293 if (current == null || isNullOrEmpty(current.installables())) {
Brian O'Connorab8ef822015-02-17 18:08:54 -0800294 return new Withdrawn(intentData, WITHDRAWN);
Sho SHIMIZU95a7baf2015-02-12 09:15:57 -0800295 } else {
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800296 return new WithdrawRequest(processor, intentData, current);
Sho SHIMIZU95a7baf2015-02-12 09:15:57 -0800297 }
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800298 default:
299 // illegal state
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800300 return new CompilingFailed(intentData);
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700301 }
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700302 }
303
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800304 private Future<FinalIntentProcessPhase> submitIntentData(IntentData data) {
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800305 return workerExecutor.submit(new IntentWorker(data));
Sho SHIMIZU8d9d1362015-02-04 12:28:15 -0800306 }
307
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800308 private class IntentBatchPreprocess implements Runnable {
309
310 // TODO make this configurable
311 private static final int TIMEOUT_PER_OP = 500; // ms
312 protected static final int MAX_ATTEMPTS = 3;
313
Sho SHIMIZU5f281a42015-02-04 15:29:11 -0800314 protected final Collection<IntentData> data;
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800315
316 // future holding current FlowRuleBatch installation result
317 protected final long startTime = System.currentTimeMillis();
318 protected final long endTime;
319
Sho SHIMIZU5f281a42015-02-04 15:29:11 -0800320 private IntentBatchPreprocess(Collection<IntentData> data, long endTime) {
321 this.data = checkNotNull(data);
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800322 this.endTime = endTime;
323 }
324
Sho SHIMIZU5f281a42015-02-04 15:29:11 -0800325 public IntentBatchPreprocess(Collection<IntentData> data) {
326 this(data, System.currentTimeMillis() + data.size() * TIMEOUT_PER_OP);
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800327 }
328
329 // FIXME compute reasonable timeouts
330 protected long calculateTimeoutLimit() {
Sho SHIMIZU5f281a42015-02-04 15:29:11 -0800331 return System.currentTimeMillis() + data.size() * TIMEOUT_PER_OP;
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800332 }
333
334 @Override
335 public void run() {
336 try {
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800337 /*
338 1. wrap each intentdata in a runnable and submit
339 2. wait for completion of all the work
340 3. accumulate results and submit batch write of IntentData to store
341 (we can also try to update these individually)
342 */
343 submitUpdates(waitForFutures(createIntentUpdates()));
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800344 } catch (Exception e) {
345 log.error("Error submitting batches:", e);
346 // FIXME incomplete Intents should be cleaned up
347 // (transition to FAILED, etc.)
348
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800349 // the batch has failed
350 // TODO: maybe we should do more?
351 log.error("Walk the plank, matey...");
Brian O'Connorb499b352015-02-03 16:46:15 -0800352 //FIXME
Sho SHIMIZU5f281a42015-02-04 15:29:11 -0800353// batchService.removeIntentOperations(data);
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800354 }
355 }
356
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800357 private List<Future<FinalIntentProcessPhase>> createIntentUpdates() {
Sho SHIMIZU5f281a42015-02-04 15:29:11 -0800358 return data.stream()
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800359 .map(IntentManager.this::submitIntentData)
360 .collect(Collectors.toList());
361 }
362
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800363 private List<FinalIntentProcessPhase> waitForFutures(List<Future<FinalIntentProcessPhase>> futures) {
364 ImmutableList.Builder<FinalIntentProcessPhase> updateBuilder = ImmutableList.builder();
365 for (Future<FinalIntentProcessPhase> future : futures) {
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800366 try {
367 updateBuilder.add(future.get());
368 } catch (InterruptedException | ExecutionException e) {
369 //FIXME
370 log.warn("Future failed: {}", e);
371 }
372 }
373 return updateBuilder.build();
374 }
375
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800376 private void submitUpdates(List<FinalIntentProcessPhase> updates) {
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800377 store.batchWrite(updates.stream()
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800378 .map(FinalIntentProcessPhase::data)
Brian O'Connor0e271dc2015-02-04 18:20:25 -0800379 .collect(Collectors.toList()));
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800380 }
Sho SHIMIZUadf8c482014-12-12 18:23:29 -0800381 }
Yuta HIGUCHIc2bf3d82014-11-28 18:50:41 -0800382
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800383 private final class IntentWorker implements Callable<FinalIntentProcessPhase> {
Brian O'Connordb15b042015-02-04 14:59:28 -0800384
385 private final IntentData data;
386
387 private IntentWorker(IntentData data) {
388 this.data = data;
389 }
390
391 @Override
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800392 public FinalIntentProcessPhase call() throws Exception {
393 IntentProcessPhase update = createIntentUpdate(data);
394 Optional<IntentProcessPhase> currentPhase = Optional.of(update);
395 IntentProcessPhase previousPhase = update;
Brian O'Connordb15b042015-02-04 14:59:28 -0800396
397 while (currentPhase.isPresent()) {
398 previousPhase = currentPhase.get();
399 currentPhase = previousPhase.execute();
400 }
Sho SHIMIZU36a8a6e2015-02-13 15:38:45 -0800401 return (FinalIntentProcessPhase) previousPhase;
Brian O'Connor427a1762014-11-19 18:40:32 -0800402 }
Brian O'Connorcb900f42014-10-07 21:55:33 -0700403 }
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700404
405 private class InternalBatchDelegate implements IntentBatchDelegate {
406 @Override
Brian O'Connorb499b352015-02-03 16:46:15 -0800407 public void execute(Collection<IntentData> operations) {
Brian O'Connorab8ef822015-02-17 18:08:54 -0800408 log.debug("Execute {} operation(s).", operations.size());
409 log.trace("Execute operations: {}", operations);
Brian O'Connordb15b042015-02-04 14:59:28 -0800410 batchExecutor.execute(new IntentBatchPreprocess(operations));
411 // TODO ensure that only one batch is in flight at a time
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700412 }
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700413 }
Sho SHIMIZUb0a47d42015-02-19 13:26:30 -0800414
415 private class InternalIntentProcessor implements IntentProcessor {
416 @Override
417 public List<Intent> compile(Intent intent, List<Intent> previousInstallables) {
418 return compilerRegistry.compile(intent, previousInstallables);
419 }
420
421 @Override
422 public FlowRuleOperations coordinate(IntentData current, IntentData pending) {
423 return installerRegistry.coordinate(current, pending, store, trackerService);
424 }
425
426 @Override
427 public FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending) {
428 return installerRegistry.uninstallCoordinate(current, pending, store, trackerService);
429 }
430
431 @Override
432 public void applyFlowRules(FlowRuleOperations flowRules) {
433 flowRuleService.apply(flowRules);
434 }
435 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700436}