Adding configurable variables to DistributedFlowRuleStore
Change-Id: I989de6b4ca4caf8ac1e648fbae766d0f88414419
Showing
3 changed files
with
73 additions
and
17 deletions
| ... | @@ -74,11 +74,6 @@ | ... | @@ -74,11 +74,6 @@ |
| 74 | </dependency> | 74 | </dependency> |
| 75 | 75 | ||
| 76 | <dependency> | 76 | <dependency> |
| 77 | - <groupId>org.osgi</groupId> | ||
| 78 | - <artifactId>org.osgi.compendium</artifactId> | ||
| 79 | - </dependency> | ||
| 80 | - | ||
| 81 | - <dependency> | ||
| 82 | <groupId>org.apache.felix</groupId> | 77 | <groupId>org.apache.felix</groupId> |
| 83 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 78 | <artifactId>org.apache.felix.scr.annotations</artifactId> |
| 84 | </dependency> | 79 | </dependency> | ... | ... |
| ... | @@ -52,6 +52,10 @@ | ... | @@ -52,6 +52,10 @@ |
| 52 | <artifactId>onlab-junit</artifactId> | 52 | <artifactId>onlab-junit</artifactId> |
| 53 | <scope>test</scope> | 53 | <scope>test</scope> |
| 54 | </dependency> | 54 | </dependency> |
| 55 | + <dependency> | ||
| 56 | + <groupId>org.osgi</groupId> | ||
| 57 | + <artifactId>org.osgi.compendium</artifactId> | ||
| 58 | + </dependency> | ||
| 55 | </dependencies> | 59 | </dependencies> |
| 56 | 60 | ||
| 57 | <build> | 61 | <build> | ... | ... |
| ... | @@ -23,10 +23,13 @@ import org.apache.commons.lang.math.RandomUtils; | ... | @@ -23,10 +23,13 @@ import org.apache.commons.lang.math.RandomUtils; |
| 23 | import org.apache.felix.scr.annotations.Activate; | 23 | import org.apache.felix.scr.annotations.Activate; |
| 24 | import org.apache.felix.scr.annotations.Component; | 24 | import org.apache.felix.scr.annotations.Component; |
| 25 | import org.apache.felix.scr.annotations.Deactivate; | 25 | import org.apache.felix.scr.annotations.Deactivate; |
| 26 | +import org.apache.felix.scr.annotations.Modified; | ||
| 27 | +import org.apache.felix.scr.annotations.Property; | ||
| 26 | import org.apache.felix.scr.annotations.Reference; | 28 | import org.apache.felix.scr.annotations.Reference; |
| 27 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 29 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 28 | import org.apache.felix.scr.annotations.Service; | 30 | import org.apache.felix.scr.annotations.Service; |
| 29 | import org.onlab.util.KryoNamespace; | 31 | import org.onlab.util.KryoNamespace; |
| 32 | +import org.onosproject.cfg.ComponentConfigService; | ||
| 30 | import org.onosproject.cluster.ClusterService; | 33 | import org.onosproject.cluster.ClusterService; |
| 31 | import org.onosproject.cluster.NodeId; | 34 | import org.onosproject.cluster.NodeId; |
| 32 | import org.onosproject.core.CoreService; | 35 | import org.onosproject.core.CoreService; |
| ... | @@ -68,12 +71,14 @@ import org.onosproject.store.serializers.KryoNamespaces; | ... | @@ -68,12 +71,14 @@ import org.onosproject.store.serializers.KryoNamespaces; |
| 68 | import org.onosproject.store.serializers.KryoSerializer; | 71 | import org.onosproject.store.serializers.KryoSerializer; |
| 69 | import org.onosproject.store.serializers.StoreSerializer; | 72 | import org.onosproject.store.serializers.StoreSerializer; |
| 70 | import org.onosproject.store.serializers.impl.DistributedStoreSerializers; | 73 | import org.onosproject.store.serializers.impl.DistributedStoreSerializers; |
| 74 | +import org.osgi.service.component.ComponentContext; | ||
| 71 | import org.slf4j.Logger; | 75 | import org.slf4j.Logger; |
| 72 | 76 | ||
| 73 | import java.io.IOException; | 77 | import java.io.IOException; |
| 74 | import java.util.Arrays; | 78 | import java.util.Arrays; |
| 75 | import java.util.Collection; | 79 | import java.util.Collection; |
| 76 | import java.util.Collections; | 80 | import java.util.Collections; |
| 81 | +import java.util.Dictionary; | ||
| 77 | import java.util.List; | 82 | import java.util.List; |
| 78 | import java.util.Map; | 83 | import java.util.Map; |
| 79 | import java.util.Set; | 84 | import java.util.Set; |
| ... | @@ -88,6 +93,8 @@ import java.util.concurrent.TimeUnit; | ... | @@ -88,6 +93,8 @@ import java.util.concurrent.TimeUnit; |
| 88 | import java.util.concurrent.TimeoutException; | 93 | import java.util.concurrent.TimeoutException; |
| 89 | import java.util.stream.Collectors; | 94 | import java.util.stream.Collectors; |
| 90 | 95 | ||
| 96 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
| 97 | +import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY; | ||
| 91 | import static org.onlab.util.Tools.groupedThreads; | 98 | import static org.onlab.util.Tools.groupedThreads; |
| 92 | import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | 99 | import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED; |
| 93 | import static org.onosproject.store.flow.impl.FlowStoreMessageSubjects.*; | 100 | import static org.onosproject.store.flow.impl.FlowStoreMessageSubjects.*; |
| ... | @@ -104,8 +111,17 @@ public class DistributedFlowRuleStore | ... | @@ -104,8 +111,17 @@ public class DistributedFlowRuleStore |
| 104 | 111 | ||
| 105 | private final Logger log = getLogger(getClass()); | 112 | private final Logger log = getLogger(getClass()); |
| 106 | 113 | ||
| 107 | - // TODO: Make configurable. | ||
| 108 | private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8; | 114 | private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8; |
| 115 | + private static final boolean DEFAULT_BACKUP_ENABLED = false; | ||
| 116 | + private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 5000; | ||
| 117 | + | ||
| 118 | + @Property(name = "msgHandlerPoolSize", intValue = MESSAGE_HANDLER_THREAD_POOL_SIZE, | ||
| 119 | + label = "Number of threads in the message handler pool") | ||
| 120 | + private int msgHandlerPoolSize = MESSAGE_HANDLER_THREAD_POOL_SIZE; | ||
| 121 | + | ||
| 122 | + @Property(name = "backupEnabled", boolValue = DEFAULT_BACKUP_ENABLED, | ||
| 123 | + label = "Indicates whether backups are enabled or not") | ||
| 124 | + private boolean backupEnabled = DEFAULT_BACKUP_ENABLED; | ||
| 109 | 125 | ||
| 110 | private InternalFlowTable flowTable; | 126 | private InternalFlowTable flowTable; |
| 111 | 127 | ||
| ... | @@ -127,6 +143,9 @@ public class DistributedFlowRuleStore | ... | @@ -127,6 +143,9 @@ public class DistributedFlowRuleStore |
| 127 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 143 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 128 | protected CoreService coreService; | 144 | protected CoreService coreService; |
| 129 | 145 | ||
| 146 | + @Reference(cardinality = MANDATORY_UNARY) | ||
| 147 | + protected ComponentConfigService configService; | ||
| 148 | + | ||
| 130 | private Map<Long, NodeId> pendingResponses = Maps.newConcurrentMap(); | 149 | private Map<Long, NodeId> pendingResponses = Maps.newConcurrentMap(); |
| 131 | 150 | ||
| 132 | private ExecutorService messageHandlingExecutor; | 151 | private ExecutorService messageHandlingExecutor; |
| ... | @@ -143,24 +162,22 @@ public class DistributedFlowRuleStore | ... | @@ -143,24 +162,22 @@ public class DistributedFlowRuleStore |
| 143 | } | 162 | } |
| 144 | }; | 163 | }; |
| 145 | 164 | ||
| 146 | - private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 5000; | ||
| 147 | - | ||
| 148 | private ReplicaInfoEventListener replicaInfoEventListener; | 165 | private ReplicaInfoEventListener replicaInfoEventListener; |
| 149 | 166 | ||
| 150 | private IdGenerator idGenerator; | 167 | private IdGenerator idGenerator; |
| 151 | 168 | ||
| 152 | @Activate | 169 | @Activate |
| 153 | - public void activate() { | 170 | + public void activate(ComponentContext context) { |
| 171 | + configService.registerProperties(getClass()); | ||
| 154 | 172 | ||
| 155 | - flowTable = new InternalFlowTable(); // .withBackupsEnabled(false); | 173 | + flowTable = new InternalFlowTable().withBackupsEnabled(backupEnabled); |
| 156 | 174 | ||
| 157 | idGenerator = coreService.getIdGenerator(FlowRuleService.FLOW_OP_TOPIC); | 175 | idGenerator = coreService.getIdGenerator(FlowRuleService.FLOW_OP_TOPIC); |
| 158 | 176 | ||
| 159 | final NodeId local = clusterService.getLocalNode().id(); | 177 | final NodeId local = clusterService.getLocalNode().id(); |
| 160 | 178 | ||
| 161 | messageHandlingExecutor = Executors.newFixedThreadPool( | 179 | messageHandlingExecutor = Executors.newFixedThreadPool( |
| 162 | - MESSAGE_HANDLER_THREAD_POOL_SIZE, | 180 | + msgHandlerPoolSize, groupedThreads("onos/store/flow", "message-handlers")); |
| 163 | - groupedThreads("onos/store/flow", "message-handlers")); | ||
| 164 | 181 | ||
| 165 | clusterCommunicator.addSubscriber(APPLY_BATCH_FLOWS, new OnStoreBatch(local), messageHandlingExecutor); | 182 | clusterCommunicator.addSubscriber(APPLY_BATCH_FLOWS, new OnStoreBatch(local), messageHandlingExecutor); |
| 166 | 183 | ||
| ... | @@ -222,11 +239,12 @@ public class DistributedFlowRuleStore | ... | @@ -222,11 +239,12 @@ public class DistributedFlowRuleStore |
| 222 | 239 | ||
| 223 | replicaInfoManager.addListener(replicaInfoEventListener); | 240 | replicaInfoManager.addListener(replicaInfoEventListener); |
| 224 | 241 | ||
| 225 | - log.info("Started"); | 242 | + logConfig("Started"); |
| 226 | } | 243 | } |
| 227 | 244 | ||
| 228 | @Deactivate | 245 | @Deactivate |
| 229 | - public void deactivate() { | 246 | + public void deactivate(ComponentContext context) { |
| 247 | + configService.unregisterProperties(getClass(), false); | ||
| 230 | clusterCommunicator.removeSubscriber(REMOVE_FLOW_ENTRY); | 248 | clusterCommunicator.removeSubscriber(REMOVE_FLOW_ENTRY); |
| 231 | clusterCommunicator.removeSubscriber(GET_DEVICE_FLOW_ENTRIES); | 249 | clusterCommunicator.removeSubscriber(GET_DEVICE_FLOW_ENTRIES); |
| 232 | clusterCommunicator.removeSubscriber(GET_FLOW_ENTRY); | 250 | clusterCommunicator.removeSubscriber(GET_FLOW_ENTRY); |
| ... | @@ -237,6 +255,46 @@ public class DistributedFlowRuleStore | ... | @@ -237,6 +255,46 @@ public class DistributedFlowRuleStore |
| 237 | log.info("Stopped"); | 255 | log.info("Stopped"); |
| 238 | } | 256 | } |
| 239 | 257 | ||
| 258 | + @Modified | ||
| 259 | + public void modified(ComponentContext context) { | ||
| 260 | + if (context == null) { | ||
| 261 | + backupEnabled = DEFAULT_BACKUP_ENABLED; | ||
| 262 | + logConfig("Default config"); | ||
| 263 | + return; | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + Dictionary properties = context.getProperties(); | ||
| 267 | + int newPoolSize; | ||
| 268 | + boolean newBackupEnabled; | ||
| 269 | + try { | ||
| 270 | + String s = (String) properties.get("msgHandlerPoolSize"); | ||
| 271 | + newPoolSize = isNullOrEmpty(s) ? msgHandlerPoolSize : Integer.parseInt(s.trim()); | ||
| 272 | + | ||
| 273 | + s = (String) properties.get("backupEnabled"); | ||
| 274 | + newBackupEnabled = isNullOrEmpty(s) ? backupEnabled : Boolean.parseBoolean(s.trim()); | ||
| 275 | + | ||
| 276 | + } catch (NumberFormatException | ClassCastException e) { | ||
| 277 | + newPoolSize = MESSAGE_HANDLER_THREAD_POOL_SIZE; | ||
| 278 | + newBackupEnabled = DEFAULT_BACKUP_ENABLED; | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + if (newPoolSize != msgHandlerPoolSize || newBackupEnabled != backupEnabled) { | ||
| 282 | + msgHandlerPoolSize = newPoolSize; | ||
| 283 | + backupEnabled = newBackupEnabled; | ||
| 284 | + // reconfigure the store | ||
| 285 | + flowTable.withBackupsEnabled(backupEnabled); | ||
| 286 | + ExecutorService oldMsgHandler = messageHandlingExecutor; | ||
| 287 | + messageHandlingExecutor = Executors.newFixedThreadPool( | ||
| 288 | + msgHandlerPoolSize, groupedThreads("onos/store/flow", "message-handlers")); | ||
| 289 | + oldMsgHandler.shutdown(); | ||
| 290 | + logConfig("Reconfigured"); | ||
| 291 | + } | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + private void logConfig(String prefix) { | ||
| 295 | + log.info("{} with msgHandlerPoolSize = {}; backupEnabled = {}", | ||
| 296 | + prefix, msgHandlerPoolSize, backupEnabled); | ||
| 297 | + } | ||
| 240 | 298 | ||
| 241 | // This is not a efficient operation on a distributed sharded | 299 | // This is not a efficient operation on a distributed sharded |
| 242 | // flow store. We need to revisit the need for this operation or at least | 300 | // flow store. We need to revisit the need for this operation or at least |
| ... | @@ -639,14 +697,13 @@ public class DistributedFlowRuleStore | ... | @@ -639,14 +697,13 @@ public class DistributedFlowRuleStore |
| 639 | (flowId, flowEntry) -> | 697 | (flowId, flowEntry) -> |
| 640 | (flowEntry == null) ? null : deviceClockService.getTimestamp(flowEntry.deviceId()); | 698 | (flowEntry == null) ? null : deviceClockService.getTimestamp(flowEntry.deviceId()); |
| 641 | 699 | ||
| 642 | - private final EventuallyConsistentMap<FlowId, StoredFlowEntry> backupMap = backupsEnabled ? | 700 | + private final EventuallyConsistentMap<FlowId, StoredFlowEntry> backupMap = |
| 643 | new EventuallyConsistentMapImpl<>("flow-backup", | 701 | new EventuallyConsistentMapImpl<>("flow-backup", |
| 644 | clusterService, | 702 | clusterService, |
| 645 | clusterCommunicator, | 703 | clusterCommunicator, |
| 646 | flowSerializer, | 704 | flowSerializer, |
| 647 | clockService, | 705 | clockService, |
| 648 | - (key, flowEntry) -> getPeerNodes()).withTombstonesDisabled(true) | 706 | + (key, flowEntry) -> getPeerNodes()).withTombstonesDisabled(true); |
| 649 | - : null; | ||
| 650 | 707 | ||
| 651 | private Collection<NodeId> getPeerNodes() { | 708 | private Collection<NodeId> getPeerNodes() { |
| 652 | List<NodeId> nodes = clusterService.getNodes() | 709 | List<NodeId> nodes = clusterService.getNodes() | ... | ... |
-
Please register or login to post a comment