sangyun-han
Committed by Gerrit Code Review

Parameterize schedule period via component config

Change-Id: I2ea4a41ec3035cd0090aef268c01c882635d021f
...@@ -23,8 +23,12 @@ import com.google.common.util.concurrent.MoreExecutors; ...@@ -23,8 +23,12 @@ import com.google.common.util.concurrent.MoreExecutors;
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;
30 +import org.onlab.util.Tools;
31 +import org.onosproject.cfg.ComponentConfigService;
28 import org.onosproject.cluster.ClusterService; 32 import org.onosproject.cluster.ClusterService;
29 import org.onosproject.cluster.LeadershipEvent; 33 import org.onosproject.cluster.LeadershipEvent;
30 import org.onosproject.cluster.LeadershipEventListener; 34 import org.onosproject.cluster.LeadershipEventListener;
...@@ -34,8 +38,10 @@ import org.onosproject.mastership.MastershipAdminService; ...@@ -34,8 +38,10 @@ import org.onosproject.mastership.MastershipAdminService;
34 import org.onosproject.mastership.MastershipEvent; 38 import org.onosproject.mastership.MastershipEvent;
35 import org.onosproject.mastership.MastershipListener; 39 import org.onosproject.mastership.MastershipListener;
36 import org.onosproject.mastership.MastershipService; 40 import org.onosproject.mastership.MastershipService;
41 +import org.osgi.service.component.ComponentContext;
37 import org.slf4j.Logger; 42 import org.slf4j.Logger;
38 43
44 +import java.util.Dictionary;
39 import java.util.concurrent.Future; 45 import java.util.concurrent.Future;
40 import java.util.concurrent.TimeUnit; 46 import java.util.concurrent.TimeUnit;
41 import java.util.concurrent.atomic.AtomicBoolean; 47 import java.util.concurrent.atomic.AtomicBoolean;
...@@ -56,8 +62,11 @@ public class MastershipLoadBalancer { ...@@ -56,8 +62,11 @@ public class MastershipLoadBalancer {
56 62
57 private final Logger log = getLogger(getClass()); 63 private final Logger log = getLogger(getClass());
58 64
59 - // TODO: parameterize via component config 65 + private static final int DEFAULT_SCHEDULE_PERIOD = 5;
60 - private static final int SCHEDULE_PERIOD = 5; 66 + @Property(name = "schedulePeriod", intValue = DEFAULT_SCHEDULE_PERIOD,
67 + label = "Period to schedule balancing the mastership to be shared as evenly as by all online instances.")
68 + private int schedulePeriod = DEFAULT_SCHEDULE_PERIOD;
69 +
61 private static final String REBALANCE_MASTERSHIP = "rebalance/mastership"; 70 private static final String REBALANCE_MASTERSHIP = "rebalance/mastership";
62 71
63 private NodeId localId; 72 private NodeId localId;
...@@ -78,6 +87,9 @@ public class MastershipLoadBalancer { ...@@ -78,6 +87,9 @@ public class MastershipLoadBalancer {
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected ClusterService clusterService; 88 protected ClusterService clusterService;
80 89
90 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 + protected ComponentConfigService cfgService;
92 +
81 private InnerLeadershipListener leadershipListener = new InnerLeadershipListener(); 93 private InnerLeadershipListener leadershipListener = new InnerLeadershipListener();
82 94
83 /* This listener is used to trigger balancing for any mastership event which will include switches changing state 95 /* This listener is used to trigger balancing for any mastership event which will include switches changing state
...@@ -91,7 +103,9 @@ public class MastershipLoadBalancer { ...@@ -91,7 +103,9 @@ public class MastershipLoadBalancer {
91 listeningDecorator(newSingleThreadScheduledExecutor(groupedThreads("MastershipLoadBalancer", "%d", log))); 103 listeningDecorator(newSingleThreadScheduledExecutor(groupedThreads("MastershipLoadBalancer", "%d", log)));
92 104
93 @Activate 105 @Activate
94 - public void activate() { 106 + public void activate(ComponentContext context) {
107 + cfgService.registerProperties(getClass());
108 + modified(context);
95 mastershipService.addListener(mastershipListener); 109 mastershipService.addListener(mastershipListener);
96 localId = clusterService.getLocalNode().id(); 110 localId = clusterService.getLocalNode().id();
97 leadershipService.addListener(leadershipListener); 111 leadershipService.addListener(leadershipListener);
...@@ -101,6 +115,7 @@ public class MastershipLoadBalancer { ...@@ -101,6 +115,7 @@ public class MastershipLoadBalancer {
101 115
102 @Deactivate 116 @Deactivate
103 public void deactivate() { 117 public void deactivate() {
118 + cfgService.unregisterProperties(getClass(), false);
104 mastershipService.removeListener(mastershipListener); 119 mastershipService.removeListener(mastershipListener);
105 leadershipService.withdraw(REBALANCE_MASTERSHIP); 120 leadershipService.withdraw(REBALANCE_MASTERSHIP);
106 leadershipService.removeListener(leadershipListener); 121 leadershipService.removeListener(leadershipListener);
...@@ -109,6 +124,14 @@ public class MastershipLoadBalancer { ...@@ -109,6 +124,14 @@ public class MastershipLoadBalancer {
109 log.info("Stopped"); 124 log.info("Stopped");
110 } 125 }
111 126
127 + @Modified
128 + public void modified(ComponentContext context) {
129 + readComponentConfiguration(context);
130 + cancelBalance();
131 + scheduleBalance();
132 + log.info("modified");
133 + }
134 +
112 private synchronized void processLeaderChange(NodeId newLeader) { 135 private synchronized void processLeaderChange(NodeId newLeader) {
113 boolean currLeader = newLeader.equals(localId); 136 boolean currLeader = newLeader.equals(localId);
114 if (isLeader.getAndSet(currLeader) != currLeader) { 137 if (isLeader.getAndSet(currLeader) != currLeader) {
...@@ -125,7 +148,7 @@ public class MastershipLoadBalancer { ...@@ -125,7 +148,7 @@ public class MastershipLoadBalancer {
125 148
126 ListenableScheduledFuture task = 149 ListenableScheduledFuture task =
127 executorService.schedule(mastershipAdminService::balanceRoles, 150 executorService.schedule(mastershipAdminService::balanceRoles,
128 - SCHEDULE_PERIOD, TimeUnit.SECONDS); 151 + schedulePeriod, TimeUnit.SECONDS);
129 task.addListener(() -> { 152 task.addListener(() -> {
130 log.info("Completed balance roles"); 153 log.info("Completed balance roles");
131 nextTask.set(null); 154 nextTask.set(null);
...@@ -144,6 +167,26 @@ public class MastershipLoadBalancer { ...@@ -144,6 +167,26 @@ public class MastershipLoadBalancer {
144 } 167 }
145 } 168 }
146 169
170 + /**
171 + * Extracts properties from the component configuration context.
172 + *
173 + * @param context the component context
174 + */
175 + private void readComponentConfiguration(ComponentContext context) {
176 + Dictionary<?, ?> properties = context.getProperties();
177 +
178 + Integer newSchedulePeriod = Tools.getIntegerProperty(properties,
179 + "schedulePeriod");
180 + if (newSchedulePeriod == null) {
181 + schedulePeriod = DEFAULT_SCHEDULE_PERIOD;
182 + log.info("Schedule period is not configured, default value is {}",
183 + DEFAULT_SCHEDULE_PERIOD);
184 + } else {
185 + schedulePeriod = newSchedulePeriod;
186 + log.info("Configured. Schedule period is configured to {}", schedulePeriod);
187 + }
188 + }
189 +
147 private class InnerMastershipListener implements MastershipListener { 190 private class InnerMastershipListener implements MastershipListener {
148 191
149 @Override 192 @Override
......