Committed by
Gerrit Code Review
fix intent issues yuta observed
Change-Id: I7dc4a19d49a1b3fc18ecce02a4018cbc9a3043fc
Showing
13 changed files
with
207 additions
and
106 deletions
| ... | @@ -14,6 +14,7 @@ public interface DemoAPI { | ... | @@ -14,6 +14,7 @@ public interface DemoAPI { |
| 14 | /** | 14 | /** |
| 15 | * Installs intents based on the installation type. | 15 | * Installs intents based on the installation type. |
| 16 | * @param type the installation type. | 16 | * @param type the installation type. |
| 17 | + * @param runParams run params | ||
| 17 | */ | 18 | */ |
| 18 | void setup(InstallType type, Optional<JsonNode> runParams); | 19 | void setup(InstallType type, Optional<JsonNode> runParams); |
| 19 | 20 | ... | ... |
| ... | @@ -199,6 +199,7 @@ public class IntentPushTestCommand extends AbstractShellCommand | ... | @@ -199,6 +199,7 @@ public class IntentPushTestCommand extends AbstractShellCommand |
| 199 | /** | 199 | /** |
| 200 | * Returns application ID for the CLI. | 200 | * Returns application ID for the CLI. |
| 201 | * | 201 | * |
| 202 | + * @param id application id | ||
| 202 | * @return command-line application identifier | 203 | * @return command-line application identifier |
| 203 | */ | 204 | */ |
| 204 | protected ApplicationId appId(Integer id) { | 205 | protected ApplicationId appId(Integer id) { | ... | ... |
| ... | @@ -56,8 +56,8 @@ public interface IntentBatchService { | ... | @@ -56,8 +56,8 @@ public interface IntentBatchService { |
| 56 | * Return true if this instance is the local leader for batch | 56 | * Return true if this instance is the local leader for batch |
| 57 | * processing a given application id. | 57 | * processing a given application id. |
| 58 | * | 58 | * |
| 59 | - * @param applicationId | 59 | + * @param applicationId an application id |
| 60 | - * @return | 60 | + * @return true if this instance is the local leader for batch |
| 61 | */ | 61 | */ |
| 62 | boolean isLocalLeader(ApplicationId applicationId); | 62 | boolean isLocalLeader(ApplicationId applicationId); |
| 63 | 63 | ... | ... |
| ... | @@ -67,4 +67,32 @@ public class IntentEvent extends AbstractEvent<IntentEvent.Type, Intent> { | ... | @@ -67,4 +67,32 @@ public class IntentEvent extends AbstractEvent<IntentEvent.Type, Intent> { |
| 67 | super(type, intent); | 67 | super(type, intent); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | + public static IntentEvent getEvent(IntentState state, Intent intent) { | ||
| 71 | + Type type; | ||
| 72 | + switch (state) { | ||
| 73 | + case SUBMITTED: | ||
| 74 | + type = Type.SUBMITTED; | ||
| 75 | + break; | ||
| 76 | + case INSTALLED: | ||
| 77 | + type = Type.INSTALLED; | ||
| 78 | + break; | ||
| 79 | + case WITHDRAWN: | ||
| 80 | + type = Type.WITHDRAWN; | ||
| 81 | + break; | ||
| 82 | + case FAILED: | ||
| 83 | + type = Type.FAILED; | ||
| 84 | + break; | ||
| 85 | + | ||
| 86 | + //fallthrough to default from here | ||
| 87 | + case COMPILING: | ||
| 88 | + case INSTALLING: | ||
| 89 | + case RECOMPILING: | ||
| 90 | + case WITHDRAWING: | ||
| 91 | + default: | ||
| 92 | + throw new IllegalArgumentException( | ||
| 93 | + "Intent event cannot have transient state: " + state); | ||
| 94 | + } | ||
| 95 | + return new IntentEvent(type, intent); | ||
| 96 | + } | ||
| 97 | + | ||
| 70 | } | 98 | } | ... | ... |
| ... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onlab.onos.net.intent; | 16 | package org.onlab.onos.net.intent; |
| 17 | 17 | ||
| 18 | -import static com.google.common.base.Preconditions.checkArgument; | ||
| 19 | import static com.google.common.base.Preconditions.checkNotNull; | 18 | import static com.google.common.base.Preconditions.checkNotNull; |
| 20 | 19 | ||
| 21 | import org.onlab.onos.net.intent.IntentStore.BatchWrite.Operation; | 20 | import org.onlab.onos.net.intent.IntentStore.BatchWrite.Operation; |
| ... | @@ -42,16 +41,16 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { | ... | @@ -42,16 +41,16 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { |
| 42 | * mechanism. | 41 | * mechanism. |
| 43 | * | 42 | * |
| 44 | * @param intent intent to be submitted | 43 | * @param intent intent to be submitted |
| 45 | - * @return event indicating the intent was submitted or null if no | ||
| 46 | - * change resulted, e.g. duplicate intent | ||
| 47 | */ | 44 | */ |
| 48 | - IntentEvent createIntent(Intent intent); | 45 | + @Deprecated |
| 46 | + void createIntent(Intent intent); | ||
| 49 | 47 | ||
| 50 | /** | 48 | /** |
| 51 | * Removes the specified intent from the inventory. | 49 | * Removes the specified intent from the inventory. |
| 52 | * | 50 | * |
| 53 | * @param intentId intent identification | 51 | * @param intentId intent identification |
| 54 | */ | 52 | */ |
| 53 | + @Deprecated | ||
| 55 | void removeIntent(IntentId intentId); | 54 | void removeIntent(IntentId intentId); |
| 56 | 55 | ||
| 57 | /** | 56 | /** |
| ... | @@ -89,9 +88,8 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { | ... | @@ -89,9 +88,8 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { |
| 89 | * | 88 | * |
| 90 | * @param intent intent whose state is to be changed | 89 | * @param intent intent whose state is to be changed |
| 91 | * @param newState new state | 90 | * @param newState new state |
| 92 | - * @return state transition event | ||
| 93 | */ | 91 | */ |
| 94 | - IntentEvent setState(Intent intent, IntentState newState); | 92 | + void setState(Intent intent, IntentState newState); |
| 95 | 93 | ||
| 96 | /** | 94 | /** |
| 97 | * Sets the installable intents which resulted from compilation of the | 95 | * Sets the installable intents which resulted from compilation of the |
| ... | @@ -129,64 +127,13 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { | ... | @@ -129,64 +127,13 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { |
| 129 | return new BatchWrite(); | 127 | return new BatchWrite(); |
| 130 | } | 128 | } |
| 131 | 129 | ||
| 132 | - // default implementation simply executes them sequentially. | ||
| 133 | - // Store implementation should override and implement actual batch write. | ||
| 134 | /** | 130 | /** |
| 135 | * Execute writes in a batch. | 131 | * Execute writes in a batch. |
| 136 | * | 132 | * |
| 137 | * @param batch BatchWrite to execute | 133 | * @param batch BatchWrite to execute |
| 138 | * @return failed operations | 134 | * @return failed operations |
| 139 | */ | 135 | */ |
| 140 | - default List<Operation> batchWrite(BatchWrite batch) { | 136 | + List<Operation> batchWrite(BatchWrite batch); |
| 141 | - List<Operation> failed = new ArrayList<>(); | ||
| 142 | - for (Operation op : batch.operations) { | ||
| 143 | - switch (op.type) { | ||
| 144 | - case CREATE_INTENT: | ||
| 145 | - checkArgument(op.args.size() == 1, | ||
| 146 | - "CREATE_INTENT takes 1 argument. %s", op); | ||
| 147 | - Intent intent = (Intent) op.args.get(0); | ||
| 148 | - if (createIntent(intent) == null) { | ||
| 149 | - failed.add(op); | ||
| 150 | - } | ||
| 151 | - break; | ||
| 152 | - | ||
| 153 | - case REMOVE_INTENT: | ||
| 154 | - checkArgument(op.args.size() == 1, | ||
| 155 | - "REMOVE_INTENT takes 1 argument. %s", op); | ||
| 156 | - IntentId intentId = (IntentId) op.args.get(0); | ||
| 157 | - removeIntent(intentId); | ||
| 158 | - break; | ||
| 159 | - | ||
| 160 | - case REMOVE_INSTALLED: | ||
| 161 | - checkArgument(op.args.size() == 1, | ||
| 162 | - "REMOVE_INSTALLED takes 1 argument. %s", op); | ||
| 163 | - intentId = (IntentId) op.args.get(0); | ||
| 164 | - removeInstalledIntents(intentId); | ||
| 165 | - break; | ||
| 166 | - | ||
| 167 | - case SET_INSTALLABLE: | ||
| 168 | - checkArgument(op.args.size() == 2, | ||
| 169 | - "SET_INSTALLABLE takes 2 arguments. %s", op); | ||
| 170 | - intentId = (IntentId) op.args.get(0); | ||
| 171 | - @SuppressWarnings("unchecked") | ||
| 172 | - List<Intent> installableIntents = (List<Intent>) op.args.get(1); | ||
| 173 | - setInstallableIntents(intentId, installableIntents); | ||
| 174 | - break; | ||
| 175 | - | ||
| 176 | - case SET_STATE: | ||
| 177 | - checkArgument(op.args.size() == 2, | ||
| 178 | - "SET_STATE takes 2 arguments. %s", op); | ||
| 179 | - intent = (Intent) op.args.get(0); | ||
| 180 | - IntentState newState = (IntentState) op.args.get(1); | ||
| 181 | - setState(intent, newState); | ||
| 182 | - break; | ||
| 183 | - | ||
| 184 | - default: | ||
| 185 | - break; | ||
| 186 | - } | ||
| 187 | - } | ||
| 188 | - return failed; | ||
| 189 | - } | ||
| 190 | 137 | ||
| 191 | public static class BatchWrite { | 138 | public static class BatchWrite { |
| 192 | 139 | ... | ... |
| ... | @@ -128,7 +128,7 @@ public class IntentManager | ... | @@ -128,7 +128,7 @@ public class IntentManager |
| 128 | trackerService.setDelegate(topoDelegate); | 128 | trackerService.setDelegate(topoDelegate); |
| 129 | batchService.setDelegate(batchDelegate); | 129 | batchService.setDelegate(batchDelegate); |
| 130 | eventDispatcher.addSink(IntentEvent.class, listenerRegistry); | 130 | eventDispatcher.addSink(IntentEvent.class, listenerRegistry); |
| 131 | - executor = newFixedThreadPool(NUM_THREADS, namedThreads("onos-intent-monitor")); | 131 | + executor = newFixedThreadPool(NUM_THREADS, namedThreads("onos-intent")); |
| 132 | idGenerator = coreService.getIdGenerator("intent-ids"); | 132 | idGenerator = coreService.getIdGenerator("intent-ids"); |
| 133 | Intent.bindIdGenerator(idGenerator); | 133 | Intent.bindIdGenerator(idGenerator); |
| 134 | log.info("Started"); | 134 | log.info("Started"); |
| ... | @@ -646,12 +646,11 @@ public class IntentManager | ... | @@ -646,12 +646,11 @@ public class IntentManager |
| 646 | return !isComplete() ? batches.get(currentBatch) : null; | 646 | return !isComplete() ? batches.get(currentBatch) : null; |
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | - List<IntentEvent> batchSuccess(BatchWrite batchWrite) { | 649 | + void batchSuccess(BatchWrite batchWrite) { |
| 650 | // move on to next Batch | 650 | // move on to next Batch |
| 651 | if (++currentBatch == batches.size()) { | 651 | if (++currentBatch == batches.size()) { |
| 652 | - return finalizeStates(batchWrite); | 652 | + finalizeStates(batchWrite); |
| 653 | } | 653 | } |
| 654 | - return Collections.emptyList(); | ||
| 655 | } | 654 | } |
| 656 | 655 | ||
| 657 | void batchFailed() { | 656 | void batchFailed() { |
| ... | @@ -673,19 +672,16 @@ public class IntentManager | ... | @@ -673,19 +672,16 @@ public class IntentManager |
| 673 | } | 672 | } |
| 674 | 673 | ||
| 675 | // FIXME make sure this is called!!! | 674 | // FIXME make sure this is called!!! |
| 676 | - private List<IntentEvent> finalizeStates(BatchWrite batchWrite) { | 675 | + private void finalizeStates(BatchWrite batchWrite) { |
| 677 | // events to be triggered on successful write | 676 | // events to be triggered on successful write |
| 678 | - List<IntentEvent> events = new ArrayList<>(); | ||
| 679 | for (Intent intent : stateMap.keySet()) { | 677 | for (Intent intent : stateMap.keySet()) { |
| 680 | switch (getInflightState(intent)) { | 678 | switch (getInflightState(intent)) { |
| 681 | case INSTALLING: | 679 | case INSTALLING: |
| 682 | batchWrite.setState(intent, INSTALLED); | 680 | batchWrite.setState(intent, INSTALLED); |
| 683 | batchWrite.setInstallableIntents(newIntent.id(), newInstallables); | 681 | batchWrite.setInstallableIntents(newIntent.id(), newInstallables); |
| 684 | - events.add(new IntentEvent(Type.INSTALLED, intent)); | ||
| 685 | break; | 682 | break; |
| 686 | case WITHDRAWING: | 683 | case WITHDRAWING: |
| 687 | batchWrite.setState(intent, WITHDRAWN); | 684 | batchWrite.setState(intent, WITHDRAWN); |
| 688 | - events.add(new IntentEvent(Type.WITHDRAWN, intent)); | ||
| 689 | batchWrite.removeInstalledIntents(intent.id()); | 685 | batchWrite.removeInstalledIntents(intent.id()); |
| 690 | batchWrite.removeIntent(intent.id()); | 686 | batchWrite.removeIntent(intent.id()); |
| 691 | break; | 687 | break; |
| ... | @@ -705,7 +701,6 @@ public class IntentManager | ... | @@ -705,7 +701,6 @@ public class IntentManager |
| 705 | break; | 701 | break; |
| 706 | } | 702 | } |
| 707 | } | 703 | } |
| 708 | - return events; | ||
| 709 | } | 704 | } |
| 710 | 705 | ||
| 711 | List<FlowRuleBatchOperation> batches() { | 706 | List<FlowRuleBatchOperation> batches() { |
| ... | @@ -737,10 +732,10 @@ public class IntentManager | ... | @@ -737,10 +732,10 @@ public class IntentManager |
| 737 | intent.id(), oldState, newState); | 732 | intent.id(), oldState, newState); |
| 738 | 733 | ||
| 739 | stateMap.put(intent, newState); | 734 | stateMap.put(intent, newState); |
| 740 | - IntentEvent event = store.setState(intent, newState); | 735 | +// IntentEvent event = store.setState(intent, newState); |
| 741 | - if (event != null) { | 736 | +// if (event != null) { |
| 742 | - eventDispatcher.post(event); | 737 | +// eventDispatcher.post(event); |
| 743 | - } | 738 | +// } |
| 744 | } | 739 | } |
| 745 | 740 | ||
| 746 | Map<Intent, IntentState> stateMap() { | 741 | Map<Intent, IntentState> stateMap() { |
| ... | @@ -822,7 +817,7 @@ public class IntentManager | ... | @@ -822,7 +817,7 @@ public class IntentManager |
| 822 | BatchWrite batchWrite = store.newBatchWrite(); | 817 | BatchWrite batchWrite = store.newBatchWrite(); |
| 823 | List<IntentEvent> events = new ArrayList<>(); | 818 | List<IntentEvent> events = new ArrayList<>(); |
| 824 | for (IntentUpdate update : intentUpdates) { | 819 | for (IntentUpdate update : intentUpdates) { |
| 825 | - events.addAll(update.batchSuccess(batchWrite)); | 820 | + update.batchSuccess(batchWrite); |
| 826 | } | 821 | } |
| 827 | if (!batchWrite.isEmpty()) { | 822 | if (!batchWrite.isEmpty()) { |
| 828 | store.batchWrite(batchWrite); | 823 | store.batchWrite(batchWrite); | ... | ... |
| ... | @@ -5,6 +5,7 @@ import com.google.common.collect.Lists; | ... | @@ -5,6 +5,7 @@ import com.google.common.collect.Lists; |
| 5 | import com.google.common.collect.Maps; | 5 | import com.google.common.collect.Maps; |
| 6 | import com.google.common.collect.Multimap; | 6 | import com.google.common.collect.Multimap; |
| 7 | import com.google.common.collect.Sets; | 7 | import com.google.common.collect.Sets; |
| 8 | + | ||
| 8 | import org.hamcrest.Description; | 9 | import org.hamcrest.Description; |
| 9 | import org.hamcrest.Matchers; | 10 | import org.hamcrest.Matchers; |
| 10 | import org.hamcrest.TypeSafeMatcher; | 11 | import org.hamcrest.TypeSafeMatcher; |
| ... | @@ -40,6 +41,7 @@ import java.util.List; | ... | @@ -40,6 +41,7 @@ import java.util.List; |
| 40 | import java.util.Map; | 41 | import java.util.Map; |
| 41 | import java.util.Set; | 42 | import java.util.Set; |
| 42 | import java.util.concurrent.CountDownLatch; | 43 | import java.util.concurrent.CountDownLatch; |
| 44 | +import java.util.concurrent.TimeUnit; | ||
| 43 | import java.util.concurrent.atomic.AtomicLong; | 45 | import java.util.concurrent.atomic.AtomicLong; |
| 44 | 46 | ||
| 45 | import static org.hamcrest.Matchers.equalTo; | 47 | import static org.hamcrest.Matchers.equalTo; |
| ... | @@ -229,7 +231,8 @@ public class IntentManagerTest { | ... | @@ -229,7 +231,8 @@ public class IntentManagerTest { |
| 229 | 231 | ||
| 230 | public void await(IntentEvent.Type type) { | 232 | public void await(IntentEvent.Type type) { |
| 231 | try { | 233 | try { |
| 232 | - latchMap.get(type).await(); | 234 | + assertTrue("Timed out waiting for: " + type, |
| 235 | + latchMap.get(type).await(5, TimeUnit.SECONDS)); | ||
| 233 | } catch (InterruptedException e) { | 236 | } catch (InterruptedException e) { |
| 234 | e.printStackTrace(); | 237 | e.printStackTrace(); |
| 235 | } | 238 | } | ... | ... |
| ... | @@ -18,6 +18,7 @@ package org.onlab.onos.store.hz; | ... | @@ -18,6 +18,7 @@ package org.onlab.onos.store.hz; |
| 18 | import com.google.common.base.Function; | 18 | import com.google.common.base.Function; |
| 19 | import com.google.common.collect.FluentIterable; | 19 | import com.google.common.collect.FluentIterable; |
| 20 | import com.hazelcast.core.IQueue; | 20 | import com.hazelcast.core.IQueue; |
| 21 | +import com.hazelcast.core.ItemEvent; | ||
| 21 | import com.hazelcast.core.ItemListener; | 22 | import com.hazelcast.core.ItemListener; |
| 22 | import com.hazelcast.monitor.LocalQueueStats; | 23 | import com.hazelcast.monitor.LocalQueueStats; |
| 23 | 24 | ||
| ... | @@ -201,16 +202,39 @@ public class SQueue<T> implements IQueue<T> { | ... | @@ -201,16 +202,39 @@ public class SQueue<T> implements IQueue<T> { |
| 201 | return q.getLocalQueueStats(); | 202 | return q.getLocalQueueStats(); |
| 202 | } | 203 | } |
| 203 | 204 | ||
| 204 | - @Deprecated // not implemented yet | 205 | + |
| 205 | @Override | 206 | @Override |
| 206 | - public String addItemListener(ItemListener<T> itemListener, boolean b) { | 207 | + public String addItemListener(ItemListener<T> itemListener, boolean withValue) { |
| 207 | - throw new UnsupportedOperationException(); | 208 | + ItemListener<byte[]> il = new ItemListener<byte[]>() { |
| 209 | + @Override | ||
| 210 | + public void itemAdded(ItemEvent<byte[]> item) { | ||
| 211 | + itemListener.itemAdded(new ItemEvent<T>(getName(item), | ||
| 212 | + item.getEventType(), | ||
| 213 | + deserialize(item.getItem()), | ||
| 214 | + item.getMember())); | ||
| 208 | } | 215 | } |
| 209 | 216 | ||
| 210 | - @Deprecated // not implemented yet | ||
| 211 | @Override | 217 | @Override |
| 212 | - public boolean removeItemListener(String s) { | 218 | + public void itemRemoved(ItemEvent<byte[]> item) { |
| 213 | - throw new UnsupportedOperationException(); | 219 | + itemListener.itemRemoved(new ItemEvent<T>(getName(item), |
| 220 | + item.getEventType(), | ||
| 221 | + deserialize(item.getItem()), | ||
| 222 | + item.getMember())); | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + private String getName(ItemEvent<byte[]> item) { | ||
| 226 | + return (item.getSource() instanceof String) ? | ||
| 227 | + (String) item.getSource() : item.getSource().toString(); | ||
| 228 | + | ||
| 229 | + } | ||
| 230 | + }; | ||
| 231 | + return q.addItemListener(il, withValue); | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + | ||
| 235 | + @Override | ||
| 236 | + public boolean removeItemListener(String registrationId) { | ||
| 237 | + return q.removeItemListener(registrationId); | ||
| 214 | } | 238 | } |
| 215 | 239 | ||
| 216 | @Deprecated | 240 | @Deprecated | ... | ... |
| ... | @@ -23,6 +23,7 @@ import com.google.common.cache.CacheLoader; | ... | @@ -23,6 +23,7 @@ import com.google.common.cache.CacheLoader; |
| 23 | import com.google.common.cache.LoadingCache; | 23 | import com.google.common.cache.LoadingCache; |
| 24 | import com.google.common.collect.ImmutableSet; | 24 | import com.google.common.collect.ImmutableSet; |
| 25 | 25 | ||
| 26 | +import com.google.common.collect.Lists; | ||
| 26 | import org.apache.felix.scr.annotations.Activate; | 27 | import org.apache.felix.scr.annotations.Activate; |
| 27 | import org.apache.felix.scr.annotations.Component; | 28 | import org.apache.felix.scr.annotations.Component; |
| 28 | import org.apache.felix.scr.annotations.Deactivate; | 29 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -187,15 +188,16 @@ public class DistributedIntentStore | ... | @@ -187,15 +188,16 @@ public class DistributedIntentStore |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | @Override | 190 | @Override |
| 190 | - public IntentEvent createIntent(Intent intent) { | 191 | + public void createIntent(Intent intent) { |
| 191 | Context timer = startTimer(createIntentTimer); | 192 | Context timer = startTimer(createIntentTimer); |
| 192 | try { | 193 | try { |
| 193 | boolean absent = intents.putIfAbsent(intent.id(), intent); | 194 | boolean absent = intents.putIfAbsent(intent.id(), intent); |
| 194 | if (!absent) { | 195 | if (!absent) { |
| 195 | // duplicate, ignore | 196 | // duplicate, ignore |
| 196 | - return null; | 197 | + return; |
| 197 | } else { | 198 | } else { |
| 198 | - return this.setState(intent, IntentState.SUBMITTED); | 199 | + this.setState(intent, IntentState.SUBMITTED); |
| 200 | + return; | ||
| 199 | } | 201 | } |
| 200 | } finally { | 202 | } finally { |
| 201 | stopTimer(timer); | 203 | stopTimer(timer); |
| ... | @@ -273,7 +275,7 @@ public class DistributedIntentStore | ... | @@ -273,7 +275,7 @@ public class DistributedIntentStore |
| 273 | } | 275 | } |
| 274 | 276 | ||
| 275 | @Override | 277 | @Override |
| 276 | - public IntentEvent setState(Intent intent, IntentState state) { | 278 | + public void setState(Intent intent, IntentState state) { |
| 277 | Context timer = startTimer(setStateTimer); | 279 | Context timer = startTimer(setStateTimer); |
| 278 | try { | 280 | try { |
| 279 | final IntentId id = intent.id(); | 281 | final IntentId id = intent.id(); |
| ... | @@ -341,10 +343,10 @@ public class DistributedIntentStore | ... | @@ -341,10 +343,10 @@ public class DistributedIntentStore |
| 341 | log.debug("Transient State change: {} {}=>{}", id, prevTransient, state); | 343 | log.debug("Transient State change: {} {}=>{}", id, prevTransient, state); |
| 342 | } | 344 | } |
| 343 | 345 | ||
| 344 | - if (evtType == null) { | 346 | + if (evtType != null) { |
| 345 | - return null; | 347 | + notifyDelegate(new IntentEvent(evtType, intent)); |
| 346 | } | 348 | } |
| 347 | - return new IntentEvent(evtType, intent); | 349 | + return; |
| 348 | } finally { | 350 | } finally { |
| 349 | stopTimer(timer); | 351 | stopTimer(timer); |
| 350 | } | 352 | } |
| ... | @@ -417,6 +419,7 @@ public class DistributedIntentStore | ... | @@ -417,6 +419,7 @@ public class DistributedIntentStore |
| 417 | 419 | ||
| 418 | List<Operation> failed = new ArrayList<>(); | 420 | List<Operation> failed = new ArrayList<>(); |
| 419 | final Builder builder = BatchWriteRequest.newBuilder(); | 421 | final Builder builder = BatchWriteRequest.newBuilder(); |
| 422 | + List<IntentEvent> events = Lists.newArrayList(); | ||
| 420 | 423 | ||
| 421 | final Set<IntentId> transitionedToParking = new HashSet<>(); | 424 | final Set<IntentId> transitionedToParking = new HashSet<>(); |
| 422 | 425 | ||
| ... | @@ -428,6 +431,7 @@ public class DistributedIntentStore | ... | @@ -428,6 +431,7 @@ public class DistributedIntentStore |
| 428 | Intent intent = op.arg(0); | 431 | Intent intent = op.arg(0); |
| 429 | builder.putIfAbsent(INTENTS_TABLE, strIntentId(intent.id()), serializer.encode(intent)); | 432 | builder.putIfAbsent(INTENTS_TABLE, strIntentId(intent.id()), serializer.encode(intent)); |
| 430 | builder.putIfAbsent(STATES_TABLE, strIntentId(intent.id()), serializer.encode(SUBMITTED)); | 433 | builder.putIfAbsent(STATES_TABLE, strIntentId(intent.id()), serializer.encode(SUBMITTED)); |
| 434 | + events.add(IntentEvent.getEvent(SUBMITTED, intent)); | ||
| 431 | break; | 435 | break; |
| 432 | 436 | ||
| 433 | case REMOVE_INTENT: | 437 | case REMOVE_INTENT: |
| ... | @@ -450,6 +454,7 @@ public class DistributedIntentStore | ... | @@ -450,6 +454,7 @@ public class DistributedIntentStore |
| 450 | } else { | 454 | } else { |
| 451 | transitionedToParking.remove(intent.id()); | 455 | transitionedToParking.remove(intent.id()); |
| 452 | } | 456 | } |
| 457 | + events.add(IntentEvent.getEvent(newState, intent)); | ||
| 453 | break; | 458 | break; |
| 454 | 459 | ||
| 455 | case SET_INSTALLABLE: | 460 | case SET_INSTALLABLE: |
| ... | @@ -478,9 +483,11 @@ public class DistributedIntentStore | ... | @@ -478,9 +483,11 @@ public class DistributedIntentStore |
| 478 | if (batchWriteResult.isSuccessful()) { | 483 | if (batchWriteResult.isSuccessful()) { |
| 479 | // no-failure (except for invalid input) | 484 | // no-failure (except for invalid input) |
| 480 | transitionedToParking.forEach((intentId) -> transientStates.remove(intentId)); | 485 | transitionedToParking.forEach((intentId) -> transientStates.remove(intentId)); |
| 486 | + notifyDelegate(events); | ||
| 481 | return failed; | 487 | return failed; |
| 482 | } else { | 488 | } else { |
| 483 | // everything failed | 489 | // everything failed |
| 490 | + // FIXME what to do with events? | ||
| 484 | return batch.operations(); | 491 | return batch.operations(); |
| 485 | } | 492 | } |
| 486 | } | 493 | } | ... | ... |
| ... | @@ -19,6 +19,9 @@ import com.google.common.collect.Maps; | ... | @@ -19,6 +19,9 @@ import com.google.common.collect.Maps; |
| 19 | import com.google.common.collect.Sets; | 19 | import com.google.common.collect.Sets; |
| 20 | import com.hazelcast.core.HazelcastInstance; | 20 | import com.hazelcast.core.HazelcastInstance; |
| 21 | import com.hazelcast.core.IQueue; | 21 | import com.hazelcast.core.IQueue; |
| 22 | +import com.hazelcast.core.ItemEvent; | ||
| 23 | +import com.hazelcast.core.ItemListener; | ||
| 24 | + | ||
| 22 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
| 23 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
| 24 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -47,7 +50,6 @@ import java.util.Collections; | ... | @@ -47,7 +50,6 @@ import java.util.Collections; |
| 47 | import java.util.Map; | 50 | import java.util.Map; |
| 48 | import java.util.Set; | 51 | import java.util.Set; |
| 49 | 52 | ||
| 50 | - | ||
| 51 | import static com.google.common.base.Preconditions.checkNotNull; | 53 | import static com.google.common.base.Preconditions.checkNotNull; |
| 52 | import static com.google.common.base.Preconditions.checkState; | 54 | import static com.google.common.base.Preconditions.checkState; |
| 53 | import static org.slf4j.LoggerFactory.getLogger; | 55 | import static org.slf4j.LoggerFactory.getLogger; |
| ... | @@ -107,6 +109,9 @@ public class HazelcastIntentBatchQueue | ... | @@ -107,6 +109,9 @@ public class HazelcastIntentBatchQueue |
| 107 | @Deactivate | 109 | @Deactivate |
| 108 | public void deactivate() { | 110 | public void deactivate() { |
| 109 | leadershipService.removeListener(leaderListener); | 111 | leadershipService.removeListener(leaderListener); |
| 112 | + for (ApplicationId appId: batchQueues.keySet()) { | ||
| 113 | + leadershipService.withdraw(getTopic(appId)); | ||
| 114 | + } | ||
| 110 | log.info("Stopped"); | 115 | log.info("Stopped"); |
| 111 | } | 116 | } |
| 112 | 117 | ||
| ... | @@ -125,12 +130,11 @@ public class HazelcastIntentBatchQueue | ... | @@ -125,12 +130,11 @@ public class HazelcastIntentBatchQueue |
| 125 | SQueue<IntentOperations> queue = batchQueues.get(appId); | 130 | SQueue<IntentOperations> queue = batchQueues.get(appId); |
| 126 | if (queue == null) { | 131 | if (queue == null) { |
| 127 | synchronized (this) { | 132 | synchronized (this) { |
| 128 | - // FIXME how will other instances find out about new queues | ||
| 129 | String topic = getTopic(appId); | 133 | String topic = getTopic(appId); |
| 130 | IQueue<byte[]> rawQueue = theInstance.getQueue(topic); | 134 | IQueue<byte[]> rawQueue = theInstance.getQueue(topic); |
| 131 | queue = new SQueue<>(rawQueue, serializer); | 135 | queue = new SQueue<>(rawQueue, serializer); |
| 136 | + queue.addItemListener(new InternalItemListener(appId), false); | ||
| 132 | batchQueues.putIfAbsent(appId, queue); | 137 | batchQueues.putIfAbsent(appId, queue); |
| 133 | - // TODO others should run for leadership when they hear about this topic | ||
| 134 | leadershipService.runForLeadership(topic); | 138 | leadershipService.runForLeadership(topic); |
| 135 | } | 139 | } |
| 136 | } | 140 | } |
| ... | @@ -209,6 +213,25 @@ public class HazelcastIntentBatchQueue | ... | @@ -209,6 +213,25 @@ public class HazelcastIntentBatchQueue |
| 209 | } | 213 | } |
| 210 | } | 214 | } |
| 211 | 215 | ||
| 216 | + private class InternalItemListener implements ItemListener<IntentOperations> { | ||
| 217 | + | ||
| 218 | + private final ApplicationId appId; | ||
| 219 | + | ||
| 220 | + public InternalItemListener(ApplicationId appId) { | ||
| 221 | + this.appId = appId; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + @Override | ||
| 225 | + public void itemAdded(ItemEvent<IntentOperations> item) { | ||
| 226 | + dispatchNextOperation(appId); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + @Override | ||
| 230 | + public void itemRemoved(ItemEvent<IntentOperations> item) { | ||
| 231 | + // no-op | ||
| 232 | + } | ||
| 233 | + } | ||
| 234 | + | ||
| 212 | private class InternalLeaderListener implements LeadershipEventListener { | 235 | private class InternalLeaderListener implements LeadershipEventListener { |
| 213 | @Override | 236 | @Override |
| 214 | public void event(LeadershipEvent event) { | 237 | public void event(LeadershipEvent event) { |
| ... | @@ -220,6 +243,8 @@ public class HazelcastIntentBatchQueue | ... | @@ -220,6 +243,8 @@ public class HazelcastIntentBatchQueue |
| 220 | return; // Not our topic: ignore | 243 | return; // Not our topic: ignore |
| 221 | } | 244 | } |
| 222 | if (!event.subject().leader().id().equals(localControllerNode.id())) { | 245 | if (!event.subject().leader().id().equals(localControllerNode.id())) { |
| 246 | + // run for leadership | ||
| 247 | + getQueue(getAppId(topic)); | ||
| 223 | return; // The event is not about this instance: ignore | 248 | return; // The event is not about this instance: ignore |
| 224 | } | 249 | } |
| 225 | 250 | ... | ... |
| ... | @@ -20,6 +20,7 @@ import com.codahale.metrics.Timer.Context; | ... | @@ -20,6 +20,7 @@ import com.codahale.metrics.Timer.Context; |
| 20 | import com.google.common.base.Verify; | 20 | import com.google.common.base.Verify; |
| 21 | import com.google.common.collect.ImmutableList; | 21 | import com.google.common.collect.ImmutableList; |
| 22 | import com.google.common.collect.ImmutableSet; | 22 | import com.google.common.collect.ImmutableSet; |
| 23 | +import com.google.common.collect.Lists; | ||
| 23 | import com.hazelcast.core.EntryAdapter; | 24 | import com.hazelcast.core.EntryAdapter; |
| 24 | import com.hazelcast.core.EntryEvent; | 25 | import com.hazelcast.core.EntryEvent; |
| 25 | import com.hazelcast.core.EntryListener; | 26 | import com.hazelcast.core.EntryListener; |
| ... | @@ -171,15 +172,16 @@ public class HazelcastIntentStore | ... | @@ -171,15 +172,16 @@ public class HazelcastIntentStore |
| 171 | } | 172 | } |
| 172 | 173 | ||
| 173 | @Override | 174 | @Override |
| 174 | - public IntentEvent createIntent(Intent intent) { | 175 | + public void createIntent(Intent intent) { |
| 175 | Context timer = startTimer(createIntentTimer); | 176 | Context timer = startTimer(createIntentTimer); |
| 176 | try { | 177 | try { |
| 177 | Intent existing = intents.putIfAbsent(intent.id(), intent); | 178 | Intent existing = intents.putIfAbsent(intent.id(), intent); |
| 178 | if (existing != null) { | 179 | if (existing != null) { |
| 179 | // duplicate, ignore | 180 | // duplicate, ignore |
| 180 | - return null; | 181 | + return; |
| 181 | } else { | 182 | } else { |
| 182 | - return this.setState(intent, IntentState.SUBMITTED); | 183 | + this.setState(intent, IntentState.SUBMITTED); |
| 184 | + return; | ||
| 183 | } | 185 | } |
| 184 | } finally { | 186 | } finally { |
| 185 | stopTimer(timer); | 187 | stopTimer(timer); |
| ... | @@ -256,7 +258,7 @@ public class HazelcastIntentStore | ... | @@ -256,7 +258,7 @@ public class HazelcastIntentStore |
| 256 | } | 258 | } |
| 257 | 259 | ||
| 258 | @Override | 260 | @Override |
| 259 | - public IntentEvent setState(Intent intent, IntentState state) { | 261 | + public void setState(Intent intent, IntentState state) { |
| 260 | Context timer = startTimer(setStateTimer); | 262 | Context timer = startTimer(setStateTimer); |
| 261 | try { | 263 | try { |
| 262 | 264 | ||
| ... | @@ -311,10 +313,10 @@ public class HazelcastIntentStore | ... | @@ -311,10 +313,10 @@ public class HazelcastIntentStore |
| 311 | final IntentState prevTransient = transientStates.put(id, state); | 313 | final IntentState prevTransient = transientStates.put(id, state); |
| 312 | log.debug("Transient State change: {} {}=>{}", id, prevTransient, state); | 314 | log.debug("Transient State change: {} {}=>{}", id, prevTransient, state); |
| 313 | 315 | ||
| 314 | - if (type == null) { | 316 | + if (type != null) { |
| 315 | - return null; | 317 | + notifyDelegate(new IntentEvent(type, intent)); |
| 316 | } | 318 | } |
| 317 | - return new IntentEvent(type, intent); | 319 | + return; |
| 318 | } finally { | 320 | } finally { |
| 319 | stopTimer(timer); | 321 | stopTimer(timer); |
| 320 | } | 322 | } |
| ... | @@ -358,6 +360,7 @@ public class HazelcastIntentStore | ... | @@ -358,6 +360,7 @@ public class HazelcastIntentStore |
| 358 | List<Operation> failed = new ArrayList<>(); | 360 | List<Operation> failed = new ArrayList<>(); |
| 359 | 361 | ||
| 360 | List<Pair<Operation, List<Future<?>>>> futures = new ArrayList<>(batch.operations().size()); | 362 | List<Pair<Operation, List<Future<?>>>> futures = new ArrayList<>(batch.operations().size()); |
| 363 | + List<IntentEvent> events = Lists.newArrayList(); | ||
| 361 | 364 | ||
| 362 | for (Operation op : batch.operations()) { | 365 | for (Operation op : batch.operations()) { |
| 363 | switch (op.type()) { | 366 | switch (op.type()) { |
| ... | @@ -434,6 +437,7 @@ public class HazelcastIntentStore | ... | @@ -434,6 +437,7 @@ public class HazelcastIntentStore |
| 434 | prevIntent, prevIntentState, | 437 | prevIntent, prevIntentState, |
| 435 | intent, newIntentState); | 438 | intent, newIntentState); |
| 436 | } | 439 | } |
| 440 | + events.add(IntentEvent.getEvent(SUBMITTED, intent)); | ||
| 437 | } catch (InterruptedException e) { | 441 | } catch (InterruptedException e) { |
| 438 | log.error("Batch write was interrupted while processing {}", op, e); | 442 | log.error("Batch write was interrupted while processing {}", op, e); |
| 439 | failed.add(op); | 443 | failed.add(op); |
| ... | @@ -487,6 +491,8 @@ public class HazelcastIntentStore | ... | @@ -487,6 +491,8 @@ public class HazelcastIntentStore |
| 487 | if (PARKING.contains(newState)) { | 491 | if (PARKING.contains(newState)) { |
| 488 | transientStates.remove(intentId); | 492 | transientStates.remove(intentId); |
| 489 | } | 493 | } |
| 494 | + events.add(IntentEvent.getEvent(newState, intent)); | ||
| 495 | + | ||
| 490 | log.trace("{} - {} -> {}", intentId, prevIntentState, newState); | 496 | log.trace("{} - {} -> {}", intentId, prevIntentState, newState); |
| 491 | // TODO sanity check and log? | 497 | // TODO sanity check and log? |
| 492 | } catch (InterruptedException e) { | 498 | } catch (InterruptedException e) { |
| ... | @@ -554,6 +560,9 @@ public class HazelcastIntentStore | ... | @@ -554,6 +560,9 @@ public class HazelcastIntentStore |
| 554 | break; | 560 | break; |
| 555 | } | 561 | } |
| 556 | } | 562 | } |
| 563 | + | ||
| 564 | + notifyDelegate(events); | ||
| 565 | + | ||
| 557 | return failed; | 566 | return failed; |
| 558 | } | 567 | } |
| 559 | 568 | ||
| ... | @@ -571,6 +580,8 @@ public class HazelcastIntentStore | ... | @@ -571,6 +580,8 @@ public class HazelcastIntentStore |
| 571 | log.debug("{} state updated remotely, removing transient state {}", | 580 | log.debug("{} state updated remotely, removing transient state {}", |
| 572 | intentId, oldState); | 581 | intentId, oldState); |
| 573 | } | 582 | } |
| 583 | + | ||
| 584 | + notifyDelegate(IntentEvent.getEvent(event.getValue(), getIntent(intentId))); | ||
| 574 | } | 585 | } |
| 575 | } | 586 | } |
| 576 | } | 587 | } | ... | ... |
| ... | @@ -16,6 +16,8 @@ | ... | @@ -16,6 +16,8 @@ |
| 16 | package org.onlab.onos.store.trivial.impl; | 16 | package org.onlab.onos.store.trivial.impl; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.ImmutableSet; | 18 | import com.google.common.collect.ImmutableSet; |
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | + | ||
| 19 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
| 20 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
| 21 | import org.apache.felix.scr.annotations.Deactivate; | 23 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -26,6 +28,7 @@ import org.onlab.onos.net.intent.IntentId; | ... | @@ -26,6 +28,7 @@ import org.onlab.onos.net.intent.IntentId; |
| 26 | import org.onlab.onos.net.intent.IntentState; | 28 | import org.onlab.onos.net.intent.IntentState; |
| 27 | import org.onlab.onos.net.intent.IntentStore; | 29 | import org.onlab.onos.net.intent.IntentStore; |
| 28 | import org.onlab.onos.net.intent.IntentStoreDelegate; | 30 | import org.onlab.onos.net.intent.IntentStoreDelegate; |
| 31 | +import org.onlab.onos.net.intent.IntentStore.BatchWrite.Operation; | ||
| 29 | import org.onlab.onos.store.AbstractStore; | 32 | import org.onlab.onos.store.AbstractStore; |
| 30 | import org.slf4j.Logger; | 33 | import org.slf4j.Logger; |
| 31 | 34 | ||
| ... | @@ -33,6 +36,7 @@ import java.util.List; | ... | @@ -33,6 +36,7 @@ import java.util.List; |
| 33 | import java.util.Map; | 36 | import java.util.Map; |
| 34 | import java.util.concurrent.ConcurrentHashMap; | 37 | import java.util.concurrent.ConcurrentHashMap; |
| 35 | 38 | ||
| 39 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 36 | import static com.google.common.base.Preconditions.checkState; | 40 | import static com.google.common.base.Preconditions.checkState; |
| 37 | import static org.onlab.onos.net.intent.IntentState.WITHDRAWN; | 41 | import static org.onlab.onos.net.intent.IntentState.WITHDRAWN; |
| 38 | import static org.slf4j.LoggerFactory.getLogger; | 42 | import static org.slf4j.LoggerFactory.getLogger; |
| ... | @@ -60,12 +64,13 @@ public class SimpleIntentStore | ... | @@ -60,12 +64,13 @@ public class SimpleIntentStore |
| 60 | } | 64 | } |
| 61 | 65 | ||
| 62 | @Override | 66 | @Override |
| 63 | - public IntentEvent createIntent(Intent intent) { | 67 | + public void createIntent(Intent intent) { |
| 64 | if (intents.containsKey(intent.id())) { | 68 | if (intents.containsKey(intent.id())) { |
| 65 | - return null; | 69 | + return; |
| 66 | } | 70 | } |
| 67 | intents.put(intent.id(), intent); | 71 | intents.put(intent.id(), intent); |
| 68 | - return this.setState(intent, IntentState.SUBMITTED); | 72 | + this.setState(intent, IntentState.SUBMITTED); |
| 73 | + return; | ||
| 69 | } | 74 | } |
| 70 | 75 | ||
| 71 | @Override | 76 | @Override |
| ... | @@ -98,7 +103,7 @@ public class SimpleIntentStore | ... | @@ -98,7 +103,7 @@ public class SimpleIntentStore |
| 98 | } | 103 | } |
| 99 | 104 | ||
| 100 | @Override | 105 | @Override |
| 101 | - public IntentEvent setState(Intent intent, IntentState state) { | 106 | + public void setState(Intent intent, IntentState state) { |
| 102 | IntentId id = intent.id(); | 107 | IntentId id = intent.id(); |
| 103 | states.put(id, state); | 108 | states.put(id, state); |
| 104 | IntentEvent.Type type = null; | 109 | IntentEvent.Type type = null; |
| ... | @@ -119,10 +124,9 @@ public class SimpleIntentStore | ... | @@ -119,10 +124,9 @@ public class SimpleIntentStore |
| 119 | default: | 124 | default: |
| 120 | break; | 125 | break; |
| 121 | } | 126 | } |
| 122 | - if (type == null) { | 127 | + if (type != null) { |
| 123 | - return null; | 128 | + notifyDelegate(new IntentEvent(type, intent)); |
| 124 | } | 129 | } |
| 125 | - return new IntentEvent(type, intent); | ||
| 126 | } | 130 | } |
| 127 | 131 | ||
| 128 | @Override | 132 | @Override |
| ... | @@ -139,5 +143,60 @@ public class SimpleIntentStore | ... | @@ -139,5 +143,60 @@ public class SimpleIntentStore |
| 139 | public void removeInstalledIntents(IntentId intentId) { | 143 | public void removeInstalledIntents(IntentId intentId) { |
| 140 | installable.remove(intentId); | 144 | installable.remove(intentId); |
| 141 | } | 145 | } |
| 146 | + /** | ||
| 147 | + * Execute writes in a batch. | ||
| 148 | + * | ||
| 149 | + * @param batch BatchWrite to execute | ||
| 150 | + * @return failed operations | ||
| 151 | + */ | ||
| 152 | + @Override | ||
| 153 | + public List<Operation> batchWrite(BatchWrite batch) { | ||
| 154 | + List<Operation> failed = Lists.newArrayList(); | ||
| 155 | + for (Operation op : batch.operations()) { | ||
| 156 | + switch (op.type()) { | ||
| 157 | + case CREATE_INTENT: | ||
| 158 | + checkArgument(op.args().size() == 1, | ||
| 159 | + "CREATE_INTENT takes 1 argument. %s", op); | ||
| 160 | + Intent intent = (Intent) op.args().get(0); | ||
| 161 | + // TODO: what if it failed? | ||
| 162 | + createIntent(intent); | ||
| 163 | + break; | ||
| 164 | + | ||
| 165 | + case REMOVE_INTENT: | ||
| 166 | + checkArgument(op.args().size() == 1, | ||
| 167 | + "REMOVE_INTENT takes 1 argument. %s", op); | ||
| 168 | + IntentId intentId = (IntentId) op.args().get(0); | ||
| 169 | + removeIntent(intentId); | ||
| 170 | + break; | ||
| 171 | + | ||
| 172 | + case REMOVE_INSTALLED: | ||
| 173 | + checkArgument(op.args().size() == 1, | ||
| 174 | + "REMOVE_INSTALLED takes 1 argument. %s", op); | ||
| 175 | + intentId = (IntentId) op.args().get(0); | ||
| 176 | + removeInstalledIntents(intentId); | ||
| 177 | + break; | ||
| 142 | 178 | ||
| 179 | + case SET_INSTALLABLE: | ||
| 180 | + checkArgument(op.args().size() == 2, | ||
| 181 | + "SET_INSTALLABLE takes 2 arguments. %s", op); | ||
| 182 | + intentId = (IntentId) op.args().get(0); | ||
| 183 | + @SuppressWarnings("unchecked") | ||
| 184 | + List<Intent> installableIntents = (List<Intent>) op.args().get(1); | ||
| 185 | + setInstallableIntents(intentId, installableIntents); | ||
| 186 | + break; | ||
| 187 | + | ||
| 188 | + case SET_STATE: | ||
| 189 | + checkArgument(op.args().size() == 2, | ||
| 190 | + "SET_STATE takes 2 arguments. %s", op); | ||
| 191 | + intent = (Intent) op.args().get(0); | ||
| 192 | + IntentState newState = (IntentState) op.args().get(1); | ||
| 193 | + setState(intent, newState); | ||
| 194 | + break; | ||
| 195 | + | ||
| 196 | + default: | ||
| 197 | + break; | ||
| 198 | + } | ||
| 199 | + } | ||
| 200 | + return failed; | ||
| 201 | + } | ||
| 143 | } | 202 | } | ... | ... |
| ... | @@ -19,7 +19,7 @@ import org.onlab.onos.cluster.LeadershipService; | ... | @@ -19,7 +19,7 @@ import org.onlab.onos.cluster.LeadershipService; |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | * A trivial implementation of the leadership service. | 21 | * A trivial implementation of the leadership service. |
| 22 | - * <p></p> | 22 | + * <p> |
| 23 | * The service is not distributed, so it can assume there's a single leadership | 23 | * The service is not distributed, so it can assume there's a single leadership |
| 24 | * contender. This contender is always granted leadership whenever it asks. | 24 | * contender. This contender is always granted leadership whenever it asks. |
| 25 | */ | 25 | */ | ... | ... |
-
Please register or login to post a comment