ONOS-4858 Resubmit pending intents with same timestamp
This will avoid needless recomputation if the intent processing is delayed.
Change-Id: I851c4ce65271a250da89f919886a3f26a774d20c
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentService.java b/core/api/src/main/java/org/onosproject/net/intent/IntentService.java
index 9d947ea..d8143bd 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentService.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentService.java
@@ -72,6 +72,17 @@
Iterable<Intent> getIntents();
/**
+ * Adds an intent data object to the pending map for processing.
+ * <p>
+ * This method is intended to only be called by core components, not
+ * applications.
+ * </p>
+ *
+ * @param intentData intent data to be added to pending map
+ */
+ void addPending(IntentData intentData);
+
+ /**
* Returns an iterable of intent data objects currently in the system.
*
* @return set of intent data objects
diff --git a/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java b/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java
index 1ceb3b2..02e8975 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java
@@ -176,6 +176,11 @@
}
@Override
+ public void addPending(IntentData intentData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public Iterable<IntentData> getIntentData() {
throw new UnsupportedOperationException();
}
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/intent/IntentServiceAdapter.java
index 73d0321..9867d04 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentServiceAdapter.java
@@ -43,6 +43,11 @@
}
@Override
+ public void addPending(IntentData intentData) {
+
+ }
+
+ @Override
public Iterable<IntentData> getIntentData() {
return null;
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java
index d51fe3a..56ee709 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java
@@ -170,8 +170,9 @@
private void resubmitCorrupt(IntentData intentData, boolean checkThreshold) {
if (checkThreshold && intentData.errorCount() >= retryThreshold) {
+ //FIXME trace or debug statement?
return; // threshold met or exceeded
- }
+ } // FIXME should we backoff here?
switch (intentData.request()) {
case INSTALL_REQ:
@@ -188,15 +189,12 @@
}
private void resubmitPendingRequest(IntentData intentData) {
+ // FIXME should we back off here?
switch (intentData.request()) {
case INSTALL_REQ:
- service.submit(intentData.intent());
- break;
case WITHDRAW_REQ:
- service.withdraw(intentData.intent());
- break;
case PURGE_REQ:
- service.purge(intentData.intent());
+ service.addPending(intentData);
break;
default:
log.warn("Failed to resubmit pending intent {} in state {} with request {}",
@@ -235,7 +233,7 @@
for (IntentData intentData : store.getPendingData(true, periodMs)) {
resubmitPendingRequest(intentData);
- stuckCount++;
+ pendingCount++;
}
if (corruptCount + failedCount + stuckCount + pendingCount > 0) {
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 07759e3..12c636c 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -266,6 +266,14 @@
}
@Override
+ public void addPending(IntentData intentData) {
+ checkPermission(INTENT_WRITE);
+ checkNotNull(intentData, INTENT_NULL);
+ //TODO we might consider further checking / assertions
+ store.addPending(intentData);
+ }
+
+ @Override
public Iterable<IntentData> getIntentData() {
checkPermission(INTENT_READ);
return store.getIntentData(false, 0);
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTest.java
index 8716e302..a6e6067 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTest.java
@@ -50,15 +50,26 @@
private static class MockIntentService extends IntentServiceAdapter {
private int submitCounter = 0;
+ private int pendingCounter = 0;
@Override
public void submit(Intent intent) {
submitCounter++;
}
+ @Override
+ public void addPending(IntentData intentData) {
+ pendingCounter++;
+ }
+
public int submitCounter() {
return submitCounter;
}
+
+ public int pendingCounter() {
+ return pendingCounter;
+ }
+
}
@Before
@@ -138,7 +149,7 @@
cleanup.run();
assertEquals("Expect number of submits incorrect",
- 1, service.submitCounter());
+ 1, service.pendingCounter());
}
@@ -168,7 +179,7 @@
cleanup.run();
assertEquals("Expect number of submits incorrect",
- 1, service.submitCounter());
+ 1, service.pendingCounter());
}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTestMock.java b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTestMock.java
index d5d2af0..164aa9d 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTestMock.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentCleanupTestMock.java
@@ -144,7 +144,7 @@
IntentData data = new IntentData(intent, INSTALL_REQ, version);
store.addPending(data);
- service.submit(intent);
+ service.addPending(data);
expectLastCall().once();
replay(service);
@@ -177,7 +177,7 @@
IntentData data = new IntentData(intent, INSTALL_REQ, version);
store.addPending(data);
- service.submit(intent);
+ service.addPending(data);
expectLastCall().once();
replay(service);
diff --git a/core/store/dist/src/main/java/org/onosproject/store/intent/impl/GossipIntentStore.java b/core/store/dist/src/main/java/org/onosproject/store/intent/impl/GossipIntentStore.java
index 2eb1d2e..c52b35e 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/intent/impl/GossipIntentStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/intent/impl/GossipIntentStore.java
@@ -38,6 +38,7 @@
import org.onosproject.net.intent.IntentStoreDelegate;
import org.onosproject.net.intent.Key;
import org.onosproject.store.AbstractStore;
+import org.onosproject.store.Timestamp;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapEvent;
@@ -272,13 +273,15 @@
public void addPending(IntentData data) {
checkNotNull(data);
- if (data.version() == null) {
- pendingMap.put(data.key(), new IntentData(data.intent(), data.state(),
- new WallClockTimestamp(), clusterService.getLocalNode().id()));
- } else {
- pendingMap.put(data.key(), new IntentData(data.intent(), data.state(),
- data.version(), clusterService.getLocalNode().id()));
- }
+ Timestamp version = data.version() != null ? data.version() : new WallClockTimestamp();
+ pendingMap.compute(data.key(), (key, existingValue) -> {
+ if (existingValue == null || existingValue.version().isOlderThan(version)) {
+ return new IntentData(data.intent(), data.state(),
+ version, clusterService.getLocalNode().id());
+ } else {
+ return existingValue;
+ }
+ });
}
@Override
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentService.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentService.java
index cebc4a4..dc75b04 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentService.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentService.java
@@ -192,6 +192,11 @@
}
@Override
+ public void addPending(IntentData intentData) {
+ intentService.addPending(intentData);
+ }
+
+ @Override
public Iterable<IntentData> getIntentData() {
return store.getIntentData();
}