Charles Chan
Committed by Gerrit Code Review

ONOS-3763 Change flow state to PENDING_ADD when retrying

Will emit a RULE_UPDATE event if the state is changed.
Update unit test accordingly.

Change-Id: Ie84778c62f52f15b7636d41db246814145e73f77
......@@ -97,6 +97,16 @@ public interface FlowRuleStore extends Store<FlowRuleBatchEvent, FlowRuleStoreDe
FlowRuleEvent removeFlowRule(FlowEntry rule);
/**
* Marks a flow rule as PENDING_ADD during retry.
*
* Emits flow_update event if the state is changed
*
* @param rule the flow rule that is retrying
* @return flow_updated event, or null if nothing updated
*/
FlowRuleEvent pendingFlowRule(FlowEntry rule);
/**
* Updates the flow table statistics of the specified device using
* the given statistics.
*
......
......@@ -258,6 +258,23 @@ public class SimpleFlowRuleStore
}
@Override
public FlowRuleEvent pendingFlowRule(FlowEntry rule) {
List<StoredFlowEntry> entries = getFlowEntries(rule.deviceId(), rule.id());
synchronized (entries) {
for (StoredFlowEntry entry : entries) {
if (entry.equals(rule) &&
entry.state() != FlowEntryState.PENDING_ADD) {
synchronized (entry) {
entry.setState(FlowEntryState.PENDING_ADD);
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
}
}
}
}
return null;
}
@Override
public void storeBatch(
FlowRuleBatchOperation operation) {
List<FlowRuleBatchEntry> toAdd = new ArrayList<>();
......
......@@ -305,6 +305,7 @@ public class FlowRuleManager
break;
case ADDED:
case PENDING_ADD:
event = store.pendingFlowRule(flowRule);
try {
frp.applyFlowRule(flowRule);
} catch (UnsupportedOperationException e) {
......
......@@ -206,7 +206,7 @@ public class FlowRuleManagerTest {
assertEquals("should still be 2 rules", 2, flowCount());
providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
validateEvents(RULE_UPDATED);
validateEvents(RULE_UPDATED, RULE_UPDATED);
}
private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
......@@ -293,7 +293,7 @@ public class FlowRuleManagerTest {
service.applyFlowRules(f3);
providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
validateEvents(RULE_ADD_REQUESTED, RULE_ADDED);
validateEvents(RULE_ADD_REQUESTED, RULE_ADDED, RULE_UPDATED);
providerService.flowRemoved(fe3);
validateEvents();
......
......@@ -526,6 +526,19 @@ public class NewDistributedFlowRuleStore
}
@Override
public FlowRuleEvent pendingFlowRule(FlowEntry rule) {
if (mastershipService.isLocalMaster(rule.deviceId())) {
StoredFlowEntry stored = flowTable.getFlowEntry(rule);
if (stored != null &&
stored.state() != FlowEntryState.PENDING_ADD) {
stored.setState(FlowEntryState.PENDING_ADD);
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
}
}
return null;
}
@Override
public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
NodeId master = mastershipService.getMasterFor(rule.deviceId());
if (Objects.equals(local, master)) {
......