HazelcastIntentStore: workaround to provide Event subject on WITHDRAWN
Change-Id: Ie9562d2223fb7e7a89f91f5faaad4bbeec6f4bd9
diff --git a/core/store/dist/src/main/java/org/onosproject/store/intent/impl/HazelcastIntentStore.java b/core/store/dist/src/main/java/org/onosproject/store/intent/impl/HazelcastIntentStore.java
index fc10284..c353b9f 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/intent/impl/HazelcastIntentStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/intent/impl/HazelcastIntentStore.java
@@ -113,7 +113,14 @@
private Timer getIntentTimer;
private Timer getIntentStateTimer;
- private String listenerId;
+ // manual near cache of Intent
+ // (Note: IntentId -> Intent is expected to be immutable)
+ // entry will be evicted, when state for that IntentId is removed.
+ private Map<IntentId, Intent> localIntents;
+
+ private String stateListenerId;
+
+ private String intentsListenerId;
private Timer createResponseTimer(String methodName) {
return createTimer("IntentStore", methodName, "responseTime");
@@ -122,6 +129,8 @@
@Override
@Activate
public void activate() {
+ localIntents = new ConcurrentHashMap<>();
+
createIntentTimer = createResponseTimer("createIntent");
removeIntentTimer = createResponseTimer("removeIntent");
setInstallableIntentsTimer = createResponseTimer("setInstallableIntents");
@@ -158,6 +167,7 @@
// TODO: enable near cache, allow read from backup for this IMap
IMap<byte[], byte[]> rawIntents = super.theInstance.getMap(INTENTS_MAP_NAME);
intents = new SMap<>(rawIntents , super.serializer);
+ intentsListenerId = intents.addEntryListener(new RemoteIntentsListener(), true);
MapConfig statesCfg = config.getMapConfig(INTENT_STATES_MAP_NAME);
statesCfg.setAsyncBackupCount(MapConfig.MAX_BACKUP_COUNT - statesCfg.getBackupCount());
@@ -165,7 +175,7 @@
IMap<byte[], byte[]> rawStates = super.theInstance.getMap(INTENT_STATES_MAP_NAME);
states = new SMap<>(rawStates , super.serializer);
EntryListener<IntentId, IntentState> listener = new RemoteIntentStateListener();
- listenerId = states.addEntryListener(listener , true);
+ stateListenerId = states.addEntryListener(listener, true);
transientStates.clear();
@@ -180,7 +190,8 @@
@Deactivate
public void deactivate() {
- states.removeEntryListener(listenerId);
+ intents.removeEntryListener(intentsListenerId);
+ states.removeEntryListener(stateListenerId);
log.info("Stopped");
}
@@ -245,7 +256,15 @@
public Intent getIntent(IntentId intentId) {
Context timer = startTimer(getIntentTimer);
try {
- return intents.get(intentId);
+ Intent intent = localIntents.get(intentId);
+ if (intent != null) {
+ return intent;
+ }
+ intent = intents.get(intentId);
+ if (intent != null) {
+ localIntents.put(intentId, intent);
+ }
+ return intent;
} finally {
stopTimer(timer);
}
@@ -605,15 +624,28 @@
}
}
+ public final class RemoteIntentsListener extends EntryAdapter<IntentId, Intent> {
+
+ @Override
+ public void entryAdded(EntryEvent<IntentId, Intent> event) {
+ localIntents.put(event.getKey(), event.getValue());
+ }
+
+ @Override
+ public void entryUpdated(EntryEvent<IntentId, Intent> event) {
+ entryAdded(event);
+ }
+ }
+
public final class RemoteIntentStateListener extends EntryAdapter<IntentId, IntentState> {
@Override
public void onEntryEvent(EntryEvent<IntentId, IntentState> event) {
+ final IntentId intentId = event.getKey();
final Member myself = theInstance.getCluster().getLocalMember();
if (!myself.equals(event.getMember())) {
// When Intent state was modified by remote node,
// clear local transient state.
- final IntentId intentId = event.getKey();
IntentState oldState = transientStates.remove(intentId);
if (oldState != null) {
log.debug("{} state updated remotely, removing transient state {}",
@@ -622,9 +654,21 @@
if (event.getValue() != null) {
// notify if this is not entry removed event
- notifyDelegate(IntentEvent.getEvent(event.getValue(), getIntent(intentId)));
+
+ final Intent intent = getIntent(intentId);
+ if (intent == null) {
+ log.warn("no Intent found for {} on Event {}", intentId, event);
+ return;
+ }
+ notifyDelegate(IntentEvent.getEvent(event.getValue(), intent));
+ // remove IntentCache
+ localIntents.remove(intentId, intent);
}
}
+
+ // populate manual near cache, to prepare for
+ // transition event to WITHDRAWN
+ getIntent(intentId);
}
}
}