* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.controller.cluster.datastore.shardmanager;
+import static java.util.Objects.requireNonNull;
+
import akka.actor.ActorRef;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import java.util.Collection;
+import akka.pattern.Patterns;
import java.util.List;
-import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shardmanager.ShardManagerInfoMBean;
+import org.opendaylight.controller.cluster.access.concepts.MemberName;
+import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
import org.opendaylight.controller.cluster.raft.RaftState;
import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import scala.concurrent.Await;
+import scala.concurrent.duration.Duration;
final class ShardManagerInfo extends AbstractMXBean implements ShardManagerInfoMBean {
public static final String JMX_CATEGORY_SHARD_MANAGER = "ShardManager";
- // The only states that you can switch to from outside. You cannot switch to Candidate/IsolatedLeader for example
- private static final Collection<String> ACCEPTABLE_STATES
- = ImmutableList.of(RaftState.Leader.name(), RaftState.Follower.name());
-
private static final Logger LOG = LoggerFactory.getLogger(ShardManagerInfo.class);
+ private static final long ASK_TIMEOUT_MILLIS = 5000;
- private final String memberName;
- private final List<String> localShards;
+ private final ActorRef shardManager;
+ private final MemberName memberName;
- private boolean syncStatus = false;
+ private volatile boolean syncStatus = false;
- private ShardManager shardManager;
- private ShardManagerInfo(String memberName, String name, String mxBeanType, List<String> localShards) {
+ ShardManagerInfo(final ActorRef shardManager, final MemberName memberName, final String name,
+ final String mxBeanType) {
super(name, mxBeanType, JMX_CATEGORY_SHARD_MANAGER);
- this.memberName = memberName;
- this.localShards = localShards;
- }
-
- static ShardManagerInfo createShardManagerMBean(String memberName, String name, String mxBeanType,
- List<String> localShards){
- ShardManagerInfo shardManagerInfo = new ShardManagerInfo(memberName, name, mxBeanType, localShards);
-
- shardManagerInfo.registerMBean();
-
- return shardManagerInfo;
- }
-
- public void addLocalShard(String shardName) {
- localShards.add(shardName);
+ this.shardManager = requireNonNull(shardManager);
+ this.memberName = requireNonNull(memberName);
}
+ @SuppressWarnings({"unchecked", "checkstyle:IllegalCatch"})
@Override
public List<String> getLocalShards() {
- return localShards;
+ try {
+ return (List<String>) Await.result(
+ Patterns.ask(shardManager, GetLocalShardIds.INSTANCE, ASK_TIMEOUT_MILLIS), Duration.Inf());
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
@Override
public boolean getSyncStatus() {
- return this.syncStatus;
+ return syncStatus;
}
- @Override
- public String getMemberName() {
- return memberName;
+ void setSyncStatus(final boolean syncStatus) {
+ this.syncStatus = syncStatus;
}
@Override
- public void switchAllLocalShardsState(String newState, long term) {
- LOG.info("switchAllLocalShardsState called newState = {}, term = {}", newState, term);
+ public String getMemberName() {
+ return memberName.getName();
+ }
- for(String shardName : localShards){
- switchShardState(shardName, newState, term);
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ private void requestSwitchShardState(final ShardIdentifier shardId, final String newState, final long term) {
+ // Validates strings argument
+ final RaftState state = RaftState.valueOf(newState);
+
+ // Leader and Follower are the only states to which we can switch externally
+ switch (state) {
+ case Follower:
+ case Leader:
+ try {
+ Await.result(Patterns.ask(shardManager, new SwitchShardBehavior(shardId, state, term),
+ ASK_TIMEOUT_MILLIS), Duration.Inf());
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ break;
+ case Candidate:
+ case IsolatedLeader:
+ default:
+ throw new IllegalArgumentException("Illegal target state " + state);
}
}
@Override
- public void switchShardState(String shardName, String newState, long term) {
- LOG.info("switchShardState called shardName = {}, newState = {}, term = {}", shardName, newState, term);
-
- Preconditions.checkArgument(localShards.contains(shardName), shardName + " is not local");
- Preconditions.checkArgument(ACCEPTABLE_STATES.contains(newState));
-
- shardManager.getSelf().tell(new SwitchShardBehavior(shardName, RaftState.valueOf(newState), term),
- ActorRef.noSender());
- }
-
- public void setSyncStatus(boolean syncStatus){
- this.syncStatus = syncStatus;
+ public void switchAllLocalShardsState(final String newState, final long term) {
+ LOG.info("switchAllLocalShardsState called newState = {}, term = {}", newState, term);
+ requestSwitchShardState(null, newState, term);
}
- public void setShardManager(ShardManager shardManager){
- this.shardManager = shardManager;
+ @Override
+ public void switchShardState(final String shardId, final String newState, final long term) {
+ final ShardIdentifier identifier = ShardIdentifier.fromShardIdString(shardId);
+ LOG.info("switchShardState called shardName = {}, newState = {}, term = {}", shardId, newState, term);
+ requestSwitchShardState(identifier, newState, term);
}
}