Aaron Kruglikov
Committed by Gerrit Code Review

Adding an option for persistent flow storage.

Change-Id: I1dd70c9f2ea9cd99ef5a55eaa4b54968f7d3c55f
...@@ -59,6 +59,7 @@ import org.onosproject.net.flow.FlowRuleStore; ...@@ -59,6 +59,7 @@ import org.onosproject.net.flow.FlowRuleStore;
59 import org.onosproject.net.flow.FlowRuleStoreDelegate; 59 import org.onosproject.net.flow.FlowRuleStoreDelegate;
60 import org.onosproject.net.flow.StoredFlowEntry; 60 import org.onosproject.net.flow.StoredFlowEntry;
61 import org.onosproject.net.flow.TableStatisticsEntry; 61 import org.onosproject.net.flow.TableStatisticsEntry;
62 +import org.onosproject.persistence.PersistenceService;
62 import org.onosproject.store.AbstractStore; 63 import org.onosproject.store.AbstractStore;
63 import org.onosproject.store.cluster.messaging.ClusterCommunicationService; 64 import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
64 import org.onosproject.store.cluster.messaging.ClusterMessage; 65 import org.onosproject.store.cluster.messaging.ClusterMessage;
...@@ -74,6 +75,7 @@ import org.onosproject.store.serializers.custom.DistributedStoreSerializers; ...@@ -74,6 +75,7 @@ import org.onosproject.store.serializers.custom.DistributedStoreSerializers;
74 import org.onosproject.store.service.EventuallyConsistentMap; 75 import org.onosproject.store.service.EventuallyConsistentMap;
75 import org.onosproject.store.service.EventuallyConsistentMapEvent; 76 import org.onosproject.store.service.EventuallyConsistentMapEvent;
76 import org.onosproject.store.service.EventuallyConsistentMapListener; 77 import org.onosproject.store.service.EventuallyConsistentMapListener;
78 +import org.onosproject.store.service.Serializer;
77 import org.onosproject.store.service.StorageService; 79 import org.onosproject.store.service.StorageService;
78 import org.onosproject.store.service.WallClockTimestamp; 80 import org.onosproject.store.service.WallClockTimestamp;
79 import org.osgi.service.component.ComponentContext; 81 import org.osgi.service.component.ComponentContext;
...@@ -113,6 +115,7 @@ public class NewDistributedFlowRuleStore ...@@ -113,6 +115,7 @@ public class NewDistributedFlowRuleStore
113 115
114 private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8; 116 private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8;
115 private static final boolean DEFAULT_BACKUP_ENABLED = true; 117 private static final boolean DEFAULT_BACKUP_ENABLED = true;
118 + private static final boolean DEFAULT_PERSISTENCE_ENABLED = false;
116 private static final int DEFAULT_BACKUP_PERIOD_MILLIS = 2000; 119 private static final int DEFAULT_BACKUP_PERIOD_MILLIS = 2000;
117 private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 5000; 120 private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 5000;
118 // number of devices whose flow entries will be backed up in one communication round 121 // number of devices whose flow entries will be backed up in one communication round
...@@ -129,6 +132,9 @@ public class NewDistributedFlowRuleStore ...@@ -129,6 +132,9 @@ public class NewDistributedFlowRuleStore
129 @Property(name = "backupPeriod", intValue = DEFAULT_BACKUP_PERIOD_MILLIS, 132 @Property(name = "backupPeriod", intValue = DEFAULT_BACKUP_PERIOD_MILLIS,
130 label = "Delay in ms between successive backup runs") 133 label = "Delay in ms between successive backup runs")
131 private int backupPeriod = DEFAULT_BACKUP_PERIOD_MILLIS; 134 private int backupPeriod = DEFAULT_BACKUP_PERIOD_MILLIS;
135 + @Property(name = "persistenceEnabled", boolValue = false,
136 + label = "Indicates whether or not changes in the flow table should be persisted to disk.")
137 + private boolean persistenceEnabled = DEFAULT_PERSISTENCE_ENABLED;
132 138
133 private InternalFlowTable flowTable = new InternalFlowTable(); 139 private InternalFlowTable flowTable = new InternalFlowTable();
134 140
...@@ -153,6 +159,9 @@ public class NewDistributedFlowRuleStore ...@@ -153,6 +159,9 @@ public class NewDistributedFlowRuleStore
153 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 159 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
154 protected MastershipService mastershipService; 160 protected MastershipService mastershipService;
155 161
162 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
163 + protected PersistenceService persistenceService;
164 +
156 private Map<Long, NodeId> pendingResponses = Maps.newConcurrentMap(); 165 private Map<Long, NodeId> pendingResponses = Maps.newConcurrentMap();
157 private ExecutorService messageHandlingExecutor; 166 private ExecutorService messageHandlingExecutor;
158 167
...@@ -716,7 +725,25 @@ public class NewDistributedFlowRuleStore ...@@ -716,7 +725,25 @@ public class NewDistributedFlowRuleStore
716 * @return Map representing Flow Table of given device. 725 * @return Map representing Flow Table of given device.
717 */ 726 */
718 private Map<FlowId, Set<StoredFlowEntry>> getFlowTable(DeviceId deviceId) { 727 private Map<FlowId, Set<StoredFlowEntry>> getFlowTable(DeviceId deviceId) {
719 - return flowEntries.computeIfAbsent(deviceId, id -> Maps.newConcurrentMap()); 728 + if (persistenceEnabled) {
729 + return flowEntries.computeIfAbsent(deviceId, id -> persistenceService
730 + .<FlowId, Set<StoredFlowEntry>>persistentMapBuilder()
731 + .withName("FlowTable:" + deviceId.toString())
732 + .withSerializer(new Serializer() {
733 + @Override
734 + public <T> byte[] encode(T object) {
735 + return SERIALIZER.encode(object);
736 + }
737 +
738 + @Override
739 + public <T> T decode(byte[] bytes) {
740 + return SERIALIZER.decode(bytes);
741 + }
742 + })
743 + .build());
744 + } else {
745 + return flowEntries.computeIfAbsent(deviceId, id -> Maps.newConcurrentMap());
746 + }
720 } 747 }
721 748
722 private Set<StoredFlowEntry> getFlowEntriesInternal(DeviceId deviceId, FlowId flowId) { 749 private Set<StoredFlowEntry> getFlowEntriesInternal(DeviceId deviceId, FlowId flowId) {
......