import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_OWNER_QNAME;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_QNAME;
+
import org.opendaylight.controller.cluster.datastore.ShardDataTree;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_ID_QNAME;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_QNAME;
+
import akka.actor.ActorRef;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
}
void init(ShardDataTree shardDataTree) {
- shardDataTree.registerTreeChangeListener(YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).
- node(EntityType.QNAME).node(EntityType.QNAME).node(ENTITY_QNAME).node(ENTITY_QNAME).
- node(Candidate.QNAME).node(Candidate.QNAME).build(), this);
+ shardDataTree.registerTreeChangeListener(YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH)
+ .node(EntityType.QNAME).node(EntityType.QNAME).node(ENTITY_QNAME).node(ENTITY_QNAME)
+ .node(Candidate.QNAME).node(Candidate.QNAME).build(), this);
}
@Override
public void onDataTreeChanged(Collection<DataTreeCandidate> changes) {
- for(DataTreeCandidate change: changes) {
+ for (DataTreeCandidate change: changes) {
DataTreeCandidateNode changeRoot = change.getRootNode();
ModificationType type = changeRoot.getModificationType();
YangInstanceIdentifier entityId = extractEntityPath(change.getRootPath());
- if(type == ModificationType.WRITE || type == ModificationType.APPEARED) {
+ if (type == ModificationType.WRITE || type == ModificationType.APPEARED) {
LOG.debug("{}: Candidate {} was added for entity {}", logId, candidate, entityId);
- Collection<String> currentCandidates = addToCurrentCandidates(entityId, candidate);
- shard.tell(new CandidateAdded(entityId, candidate, new ArrayList<>(currentCandidates)), shard);
- } else if(type == ModificationType.DELETE || type == ModificationType.DISAPPEARED) {
+ Collection<String> newCandidates = addToCurrentCandidates(entityId, candidate);
+ shard.tell(new CandidateAdded(entityId, candidate, new ArrayList<>(newCandidates)), shard);
+ } else if (type == ModificationType.DELETE || type == ModificationType.DISAPPEARED) {
LOG.debug("{}: Candidate {} was removed for entity {}", logId, candidate, entityId);
- Collection<String> currentCandidates = removeFromCurrentCandidates(entityId, candidate);
- shard.tell(new CandidateRemoved(entityId, candidate, new ArrayList<>(currentCandidates)), shard);
+ Collection<String> newCandidates = removeFromCurrentCandidates(entityId, candidate);
+ shard.tell(new CandidateRemoved(entityId, candidate, new ArrayList<>(newCandidates)), shard);
}
}
}
private Collection<String> addToCurrentCandidates(YangInstanceIdentifier entityId, String newCandidate) {
Collection<String> candidates = currentCandidates.get(entityId);
- if(candidates == null) {
+ if (candidates == null) {
candidates = new LinkedHashSet<>();
currentCandidates.put(entityId, candidates);
}
private Collection<String> removeFromCurrentCandidates(YangInstanceIdentifier entityId, String candidateToRemove) {
Collection<String> candidates = currentCandidates.get(entityId);
- if(candidates != null) {
+ if (candidates != null) {
candidates.remove(candidateToRemove);
return candidates;
}
private static YangInstanceIdentifier extractEntityPath(YangInstanceIdentifier candidatePath) {
List<PathArgument> newPathArgs = new ArrayList<>();
- for(PathArgument pathArg: candidatePath.getPathArguments()) {
+ for (PathArgument pathArg: candidatePath.getPathArguments()) {
newPathArgs.add(pathArg);
- if(pathArg instanceof NodeIdentifierWithPredicates) {
+ if (pathArg instanceof NodeIdentifierWithPredicates) {
NodeIdentifierWithPredicates nodeKey = (NodeIdentifierWithPredicates) pathArg;
Entry<QName, Object> key = nodeKey.getKeyValues().entrySet().iterator().next();
- if(ENTITY_ID_QNAME.equals(key.getKey())) {
+ if (ENTITY_ID_QNAME.equals(key.getKey())) {
break;
}
}
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.CANDIDATE_NODE_ID;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.ENTITY_OWNER_NODE_ID;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.entityPath;
+
import akka.actor.ActorRef;
import akka.dispatch.OnComplete;
import akka.pattern.Patterns;
future.onComplete(new OnComplete<Object>() {
@Override
public void onComplete(final Throwable failure, final Object response) {
- if(failure != null) {
+ if (failure != null) {
LOG.debug("Error sending message {} to {}", message, shardActor, failure);
} else {
LOG.debug("{} message to {} succeeded", message, shardActor, failure);
@VisibleForTesting
void executeLocalEntityOwnershipShardOperation(final Object message) {
- if(localEntityOwnershipShard == null) {
+ if (localEntityOwnershipShard == null) {
Future<ActorRef> future = context.findLocalShardAsync(ENTITY_OWNERSHIP_SHARD_NAME);
future.onComplete(new OnComplete<ActorRef>() {
@Override
public void onComplete(final Throwable failure, final ActorRef shardActor) {
- if(failure != null) {
+ if (failure != null) {
LOG.error("Failed to find local {} shard", ENTITY_OWNERSHIP_SHARD_NAME, failure);
} else {
localEntityOwnershipShard = shardActor;
throws CandidateAlreadyRegisteredException {
Preconditions.checkNotNull(entity, "entity cannot be null");
- if(registeredEntities.putIfAbsent(entity, entity) != null) {
+ if (registeredEntities.putIfAbsent(entity, entity) != null) {
throw new CandidateAlreadyRegisteredException(entity);
}
// Check if there are any candidates, if there are none we do not really have ownership state
final MapEntryNode entity = (MapEntryNode) entityNode.get();
- final Optional<DataContainerChild<? extends PathArgument, ?>> optionalCandidates = entity.getChild(CANDIDATE_NODE_ID);
- final boolean hasCandidates = optionalCandidates.isPresent() && ((MapNode) optionalCandidates.get()).getValue().size() > 0;
- if(!hasCandidates){
+ final Optional<DataContainerChild<? extends PathArgument, ?>> optionalCandidates =
+ entity.getChild(CANDIDATE_NODE_ID);
+ final boolean hasCandidates = optionalCandidates.isPresent()
+ && ((MapNode) optionalCandidates.get()).getValue().size() > 0;
+ if (!hasCandidates) {
return Optional.absent();
}
}
@VisibleForTesting
+ @SuppressWarnings("checkstyle:IllegalCatch")
DataTree getLocalEntityOwnershipShardDataTree() {
if (localEntityOwnershipShardDataTree == null) {
try {
- if(localEntityOwnershipShard == null) {
+ if (localEntityOwnershipShard == null) {
localEntityOwnershipShard = Await.result(context.findLocalShardAsync(
ENTITY_OWNERSHIP_SHARD_NAME), Duration.Inf());
}
package org.opendaylight.controller.cluster.datastore.entityownership;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.createEntity;
+
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
@Override
public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
- for(DataTreeCandidate change: changes) {
+ for (DataTreeCandidate change: changes) {
DataTreeCandidateNode changeRoot = change.getRootNode();
LeafNode<?> ownerLeaf = (LeafNode<?>) changeRoot.getDataAfter().get();
- LOG.debug("{}: Entity node changed: {}, {}", logId(), changeRoot.getModificationType(), change.getRootPath());
+ LOG.debug("{}: Entity node changed: {}, {}", logId(), changeRoot.getModificationType(),
+ change.getRootPath());
String newOwner = extractOwner(ownerLeaf);
String origOwner = null;
Optional<NormalizedNode<?, ?>> dataBefore = changeRoot.getDataBefore();
- if(dataBefore.isPresent()) {
+ if (dataBefore.isPresent()) {
origOwner = extractOwner((LeafNode<?>) changeRoot.getDataBefore().get());
}
DOMEntity entity = createEntity(change.getRootPath());
- LOG.debug("{}: Calling notifyEntityOwnershipListeners: entity: {}, wasOwner: {}, isOwner: {}, hasOwner: {}",
- logId(), entity, wasOwner, isOwner, hasOwner);
+ LOG.debug(
+ "{}: Calling notifyEntityOwnershipListeners: entity: {}, wasOwner: {}, isOwner: {}, hasOwner: {}",
+ logId(), entity, wasOwner, isOwner, hasOwner);
listenerSupport.notifyEntityOwnershipListeners(entity, wasOwner, isOwner, hasOwner);
}
import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.EntityOwners;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.Entity;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.entity.Candidate;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
* @author Thomas Pantelis
*/
public final class EntityOwnersModel {
- static final QName ENTITY_QNAME = org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.
- md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.Entity.QNAME;
+ static final QName ENTITY_QNAME = Entity.QNAME;
static final QName CANDIDATE_NAME_QNAME = QName.create(Candidate.QNAME, "name");
static final QName ENTITY_ID_QNAME = QName.create(ENTITY_QNAME, "id");
static final QName ENTITY_OWNER_QNAME = QName.create(ENTITY_QNAME, "owner");
YangInstanceIdentifier.of(EntityOwners.QNAME).node(EntityType.QNAME);
static YangInstanceIdentifier entityPath(String entityType, YangInstanceIdentifier entityId) {
- return YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).node(EntityType.QNAME).
- nodeWithKey(EntityType.QNAME, ENTITY_TYPE_QNAME, entityType).node(ENTITY_QNAME).
- nodeWithKey(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).build();
+ return YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).node(EntityType.QNAME)
+ .nodeWithKey(EntityType.QNAME, ENTITY_TYPE_QNAME, entityType).node(ENTITY_QNAME)
+ .nodeWithKey(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).build();
}
static YangInstanceIdentifier candidatePath(String entityType, YangInstanceIdentifier entityId,
String candidateName) {
- return YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).node(EntityType.QNAME).
- nodeWithKey(EntityType.QNAME, ENTITY_TYPE_QNAME, entityType).node(ENTITY_QNAME).
- nodeWithKey(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).node(Candidate.QNAME).
- nodeWithKey(Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName).build();
+ return YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).node(EntityType.QNAME)
+ .nodeWithKey(EntityType.QNAME, ENTITY_TYPE_QNAME, entityType).node(ENTITY_QNAME)
+ .nodeWithKey(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).node(Candidate.QNAME)
+ .nodeWithKey(Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName).build();
}
static ContainerNode entityOwnersWithEntityTypeEntry(MapEntryNode entityTypeNode) {
return ImmutableContainerNodeBuilder.create().withNodeIdentifier(
- ENTITY_OWNERS_NODE_ID).addChild(ImmutableNodes.mapNodeBuilder(EntityType.QNAME).
- addChild(entityTypeNode).build()).build();
+ ENTITY_OWNERS_NODE_ID).addChild(ImmutableNodes.mapNodeBuilder(EntityType.QNAME)
+ .addChild(entityTypeNode).build()).build();
}
static MapEntryNode entityTypeEntryWithEntityEntry(String entityType, MapEntryNode entityNode) {
}
static MapNode candidateEntry(String candidateName) {
- return ImmutableOrderedMapNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Candidate.QNAME)).
- addChild(candidateMapEntry(candidateName)).build();
+ return ImmutableOrderedMapNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Candidate.QNAME))
+ .addChild(candidateMapEntry(candidateName)).build();
}
static MapEntryNode candidateMapEntry(String candidateName) {
ImmutableNodes.leafNode(ENTITY_OWNER_QNAME, owner)).build();
}
- public static String entityTypeFromEntityPath(YangInstanceIdentifier entityPath){
+ public static String entityTypeFromEntityPath(YangInstanceIdentifier entityPath) {
YangInstanceIdentifier parent = entityPath;
- while(!parent.isEmpty()) {
+ while (!parent.isEmpty()) {
if (EntityType.QNAME.equals(parent.getLastPathArgument().getNodeType())) {
- YangInstanceIdentifier.NodeIdentifierWithPredicates entityTypeLastPathArgument = (YangInstanceIdentifier.NodeIdentifierWithPredicates) parent.getLastPathArgument();
+ YangInstanceIdentifier.NodeIdentifierWithPredicates entityTypeLastPathArgument =
+ (YangInstanceIdentifier.NodeIdentifierWithPredicates) parent.getLastPathArgument();
return (String) entityTypeLastPathArgument.getKeyValues().get(ENTITY_TYPE_QNAME);
}
parent = parent.getParent();
static DOMEntity createEntity(YangInstanceIdentifier entityPath) {
String entityType = null;
YangInstanceIdentifier entityId = null;
- for(PathArgument pathArg: entityPath.getPathArguments()) {
- if(pathArg instanceof NodeIdentifierWithPredicates) {
+ for (PathArgument pathArg: entityPath.getPathArguments()) {
+ if (pathArg instanceof NodeIdentifierWithPredicates) {
NodeIdentifierWithPredicates nodeKey = (NodeIdentifierWithPredicates) pathArg;
Entry<QName, Object> key = nodeKey.getKeyValues().entrySet().iterator().next();
- if(ENTITY_TYPE_QNAME.equals(key.getKey())) {
+ if (ENTITY_TYPE_QNAME.equals(key.getKey())) {
entityType = key.getValue().toString();
- } else if(ENTITY_ID_QNAME.equals(key.getKey())) {
+ } else if (ENTITY_ID_QNAME.equals(key.getKey())) {
entityId = (YangInstanceIdentifier) key.getValue();
}
}
import org.opendaylight.controller.cluster.common.actor.AbstractUntypedActor;
import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* An actor which is responsible for notifying an EntityOwnershipListener of changes.
* @author Thomas Pantelis
*/
class EntityOwnershipListenerActor extends AbstractUntypedActor {
- private static final Logger LOG = LoggerFactory.getLogger(EntityOwnershipListenerActor.class);
-
private final DOMEntityOwnershipListener listener;
private EntityOwnershipListenerActor(DOMEntityOwnershipListener listener) {
}
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
private void onEntityOwnershipChanged(DOMEntityOwnershipChange change) {
LOG.debug("Notifying EntityOwnershipListener {}: {}", listener, change);
private void notifyListeners(DOMEntity entity, String mapKey, boolean wasOwner, boolean isOwner, boolean hasOwner) {
Collection<DOMEntityOwnershipListener> listeners = entityTypeListenerMap.get(mapKey);
- if(!listeners.isEmpty()) {
+ if (!listeners.isEmpty()) {
notifyListeners(entity, wasOwner, isOwner, hasOwner, listeners);
}
}
Collection<DOMEntityOwnershipListener> listeners) {
DOMEntityOwnershipChange changed = new DOMEntityOwnershipChange(entity,
EntityOwnershipChangeState.from(wasOwner, isOwner, hasOwner), inJeopardy);
- for(DOMEntityOwnershipListener listener: listeners) {
+ for (DOMEntityOwnershipListener listener: listeners) {
ActorRef listenerActor = listenerActorFor(listener);
LOG.debug("{}: Notifying EntityOwnershipListenerActor {} with {}", logId, listenerActor, changed);
private void addListener(DOMEntityOwnershipListener listener, String mapKey) {
if (entityTypeListenerMap.put(mapKey, listener)) {
ListenerActorRefEntry listenerEntry = listenerActorMap.get(listener);
- if(listenerEntry == null) {
+ if (listenerEntry == null) {
listenerActorMap.put(listener, new ListenerActorRefEntry());
} else {
listenerEntry.referenceCount++;
LOG.debug("{}: Found {}", logId, listenerEntry);
listenerEntry.referenceCount--;
- if(listenerEntry.referenceCount <= 0) {
+ if (listenerEntry.referenceCount <= 0) {
listenerActorMap.remove(listener);
- if(listenerEntry.actorRef != null) {
+ if (listenerEntry.actorRef != null) {
LOG.debug("Killing EntityOwnershipListenerActor {}", listenerEntry.actorRef);
listenerEntry.actorRef.tell(PoisonPill.getInstance(), ActorRef.noSender());
}
int referenceCount = 1;
ActorRef actorFor(DOMEntityOwnershipListener listener) {
- if(actorRef == null) {
+ if (actorRef == null) {
actorRef = actorContext.actorOf(EntityOwnershipListenerActor.props(listener));
LOG.debug("{}: Created EntityOwnershipListenerActor {} for listener {}", logId, actorRef, listener);
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.candidateNodeKey;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.candidatePath;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.entityOwnersWithCandidate;
+
import akka.actor.ActorRef;
import akka.actor.ActorSelection;
import akka.actor.Cancellable;
import akka.cluster.Cluster;
+import akka.cluster.ClusterEvent.CurrentClusterState;
import akka.cluster.Member;
import akka.cluster.MemberStatus;
-import akka.cluster.ClusterEvent.CurrentClusterState;
import akka.pattern.Patterns;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
private final EntityOwnershipStatistics entityOwnershipStatistics;
private boolean removeAllInitialCandidates = true;
- private static DatastoreContext noPersistenceDatastoreContext(DatastoreContext datastoreContext) {
- return DatastoreContext.newBuilderFrom(datastoreContext).persistent(false).build();
- }
-
protected EntityOwnershipShard(Builder builder) {
super(builder);
this.localMemberName = builder.localMemberName;
this.entityOwnershipStatistics.init(getDataStore());
}
+ private static DatastoreContext noPersistenceDatastoreContext(DatastoreContext datastoreContext) {
+ return DatastoreContext.newBuilderFrom(datastoreContext).persistent(false).build();
+ }
+
@Override
protected void onDatastoreContext(DatastoreContext context) {
super.onDatastoreContext(noPersistenceDatastoreContext(context));
@Override
public void handleNonRaftCommand(final Object message) {
- if(message instanceof RegisterCandidateLocal) {
+ if (message instanceof RegisterCandidateLocal) {
onRegisterCandidateLocal((RegisterCandidateLocal) message);
- } else if(message instanceof UnregisterCandidateLocal) {
- onUnregisterCandidateLocal((UnregisterCandidateLocal)message);
- } else if(message instanceof CandidateAdded){
+ } else if (message instanceof UnregisterCandidateLocal) {
+ onUnregisterCandidateLocal((UnregisterCandidateLocal) message);
+ } else if (message instanceof CandidateAdded) {
onCandidateAdded((CandidateAdded) message);
- } else if(message instanceof CandidateRemoved){
+ } else if (message instanceof CandidateRemoved) {
onCandidateRemoved((CandidateRemoved) message);
- } else if(message instanceof PeerDown) {
+ } else if (message instanceof PeerDown) {
onPeerDown((PeerDown) message);
- } else if(message instanceof PeerUp) {
+ } else if (message instanceof PeerUp) {
onPeerUp((PeerUp) message);
- } else if(message instanceof RegisterListenerLocal) {
- onRegisterListenerLocal((RegisterListenerLocal)message);
- } else if(message instanceof UnregisterListenerLocal) {
+ } else if (message instanceof RegisterListenerLocal) {
+ onRegisterListenerLocal((RegisterListenerLocal) message);
+ } else if (message instanceof UnregisterListenerLocal) {
onUnregisterListenerLocal((UnregisterListenerLocal) message);
- } else if(message instanceof SelectOwner) {
+ } else if (message instanceof SelectOwner) {
onSelectOwner((SelectOwner) message);
- } else if(message instanceof RemoveAllCandidates) {
+ } else if (message instanceof RemoveAllCandidates) {
onRemoveAllCandidates((RemoveAllCandidates) message);
- } else if(!commitCoordinator.handleMessage(message, this)) {
+ } else if (!commitCoordinator.handleMessage(message, this)) {
super.handleNonRaftCommand(message);
}
}
LOG.debug("{}: onSelectOwner: {}", persistenceId(), selectOwner);
String currentOwner = getCurrentOwner(selectOwner.getEntityPath());
- if(Strings.isNullOrEmpty(currentOwner)) {
+ if (Strings.isNullOrEmpty(currentOwner)) {
writeNewOwner(selectOwner.getEntityPath(), newOwner(currentOwner, selectOwner.getAllCandidates(),
selectOwner.getOwnerSelectionStrategy()));
Cancellable cancellable = entityToScheduledOwnershipTask.get(selectOwner.getEntityPath());
- if(cancellable != null){
- if(!cancellable.isCancelled()){
+ if (cancellable != null) {
+ if (!cancellable.isCancelled()) {
cancellable.cancel();
}
entityToScheduledOwnershipTask.remove(selectOwner.getEntityPath());
DOMEntity entity = unregisterCandidate.getEntity();
listenerSupport.unsetHasCandidateForEntity(entity);
- YangInstanceIdentifier candidatePath = candidatePath(entity.getType(), entity.getIdentifier(), localMemberName.getName());
+ YangInstanceIdentifier candidatePath = candidatePath(entity.getType(), entity.getIdentifier(),
+ localMemberName.getName());
commitCoordinator.commitModification(new DeleteModification(candidatePath), this);
getSender().tell(SuccessReply.INSTANCE, getSelf());
private void onUnregisterListenerLocal(UnregisterListenerLocal unregisterListener) {
LOG.debug("{}: onUnregisterListenerLocal: {}", persistenceId(), unregisterListener);
- listenerSupport.removeEntityOwnershipListener(unregisterListener.getEntityType(), unregisterListener.getListener());
+ listenerSupport.removeEntityOwnershipListener(unregisterListener.getEntityType(),
+ unregisterListener.getListener());
getSender().tell(SuccessReply.INSTANCE, getSelf());
}
void tryCommitModifications(final BatchedModifications modifications) {
- if(isLeader()) {
- LOG.debug("{}: Committing BatchedModifications {} locally", persistenceId(), modifications.getTransactionID());
+ if (isLeader()) {
+ LOG.debug("{}: Committing BatchedModifications {} locally", persistenceId(),
+ modifications.getTransactionID());
// Note that it's possible the commit won't get consensus and will timeout and not be applied
// to the state. However we don't need to retry it in that case b/c it will be committed to
if (leader != null) {
possiblyRemoveAllInitialCandidates(leader);
- if(LOG.isDebugEnabled()) {
- LOG.debug("{}: Sending BatchedModifications {} to leader {}", persistenceId(),
- modifications.getTransactionID(), leader);
- }
+ LOG.debug("{}: Sending BatchedModifications {} to leader {}", persistenceId(),
+ modifications.getTransactionID(), leader);
Future<Object> future = Patterns.ask(leader, modifications, TimeUnit.SECONDS.toMillis(
getDatastoreContext().getShardTransactionCommitTimeoutInSeconds()));
// potential stale candidates we had previously registered, as it's possible a candidate may not be
// registered by a client in the new incarnation. We have to send the RemoveAllCandidates message prior to any
// pending registrations.
- if(removeAllInitialCandidates && leader != null) {
+ if (removeAllInitialCandidates && leader != null) {
removeAllInitialCandidates = false;
- if(!isLeader()) {
+ if (!isLeader()) {
LOG.debug("{} - got new leader {} on startup - sending RemoveAllCandidates", persistenceId(), leader);
leader.tell(new RemoveAllCandidates(localMemberName), ActorRef.noSender());
return false;
case IsolatedLeader:
return true;
+ default:
+ throw new IllegalStateException("Unsupported RAFT state " + state);
}
- throw new IllegalStateException("Unsupported RAFT state " + state);
}
private void notifyAllListeners() {
private void initializeDownPeerMemberNamesFromClusterState() {
java.util.Optional<Cluster> cluster = getRaftActorContext().getCluster();
- if(!cluster.isPresent()) {
+ if (!cluster.isPresent()) {
return;
}
CurrentClusterState state = cluster.get().state();
Set<Member> unreachable = state.getUnreachable();
- LOG.debug("{}: initializeDownPeerMemberNamesFromClusterState - current downPeerMemberNames: {}, unreachable: {}",
- persistenceId(), downPeerMemberNames, unreachable);
+ LOG.debug(
+ "{}: initializeDownPeerMemberNamesFromClusterState - current downPeerMemberNames: {}, unreachable: {}",
+ persistenceId(), downPeerMemberNames, unreachable);
downPeerMemberNames.clear();
- for(Member m: unreachable) {
+ for (Member m: unreachable) {
downPeerMemberNames.add(MemberName.forName(m.getRoles().iterator().next()));
}
- for(Member m: state.getMembers()) {
- if(m.status() != MemberStatus.up() && m.status() != MemberStatus.weaklyUp()) {
+ for (Member m: state.getMembers()) {
+ if (m.status() != MemberStatus.up() && m.status() != MemberStatus.weaklyUp()) {
LOG.debug("{}: Adding down member with status {}", persistenceId(), m.status());
downPeerMemberNames.add(MemberName.forName(m.getRoles().iterator().next()));
}
private void onCandidateRemoved(CandidateRemoved message) {
LOG.debug("{}: onCandidateRemoved: {}", persistenceId(), message);
- if(isLeader()) {
+ if (isLeader()) {
String currentOwner = getCurrentOwner(message.getEntityPath());
writeNewOwner(message.getEntityPath(),
- newOwner(currentOwner, message.getRemainingCandidates(), getEntityOwnerElectionStrategy(message.getEntityPath())));
+ newOwner(currentOwner, message.getRemainingCandidates(),
+ getEntityOwnerElectionStrategy(message.getEntityPath())));
}
}
}
private void onCandidateAdded(CandidateAdded message) {
- if(!isLeader()){
+ if (!isLeader()) {
return;
}
LOG.debug("{}: Using strategy {} to select owner, currentOwner = {}", persistenceId(), strategy, currentOwner);
- if(strategy.getSelectionDelayInMillis() == 0L) {
+ if (strategy.getSelectionDelayInMillis() == 0L) {
writeNewOwner(message.getEntityPath(), newOwner(currentOwner, message.getAllCandidates(),
strategy));
- } else if(message.getAllCandidates().size() == availableMembers) {
+ } else if (message.getAllCandidates().size() == availableMembers) {
LOG.debug("{}: Received the maximum candidates requests : {} writing new owner",
persistenceId(), availableMembers);
cancelOwnerSelectionTask(message.getEntityPath());
LOG.info("{}: onPeerDown: {}", persistenceId(), peerDown);
MemberName downMemberName = peerDown.getMemberName();
- if(downPeerMemberNames.add(downMemberName) && isLeader()) {
+ if (downPeerMemberNames.add(downMemberName) && isLeader()) {
// Select new owners for entities owned by the down peer and which have other candidates. For an entity for
// which the down peer is the only candidate, we leave it as the owner and don't clear it. This is done to
// handle the case where the peer member process is actually still running but the node is partitioned.
private void selectNewOwnerForEntitiesOwnedBy(Set<String> ownedBy) {
final BatchedModifications modifications = commitCoordinator.newBatchedModifications();
searchForEntitiesOwnedBy(ownedBy, (entityTypeNode, entityNode) -> {
- YangInstanceIdentifier entityPath = YangInstanceIdentifier.builder(ENTITY_TYPES_PATH).
- node(entityTypeNode.getIdentifier()).node(ENTITY_NODE_ID).node(entityNode.getIdentifier()).
- node(ENTITY_OWNER_NODE_ID).build();
+ YangInstanceIdentifier entityPath = YangInstanceIdentifier.builder(ENTITY_TYPES_PATH)
+ .node(entityTypeNode.getIdentifier()).node(ENTITY_NODE_ID).node(entityNode.getIdentifier())
+ .node(ENTITY_OWNER_NODE_ID).build();
String newOwner = newOwner(getCurrentOwner(entityPath), getCandidateNames(entityNode),
getEntityOwnerElectionStrategy(entityPath));
- if(!newOwner.isEmpty()) {
+ if (!newOwner.isEmpty()) {
LOG.debug("{}: Found entity {}, writing new owner {}", persistenceId(), entityPath, newOwner);
modifications.addModification(new WriteModification(entityPath,
// leader change occurred.
commitCoordinator.onStateChanged(this, isLeader());
- if(isLeader()) {
+ if (isLeader()) {
// Try to assign owners for entities that have no current owner. It's possible the peer that is now up
// had previously registered as a candidate and was the only candidate but the owner write tx couldn't be
// committed due to a leader change. Eg, the leader is able to successfully commit the candidate add tx but
private Collection<String> getCandidateNames(MapEntryNode entity) {
Collection<MapEntryNode> candidates = ((MapNode)entity.getChild(CANDIDATE_NODE_ID).get()).getValue();
Collection<String> candidateNames = new ArrayList<>(candidates.size());
- for(MapEntryNode candidate: candidates) {
+ for (MapEntryNode candidate: candidates) {
candidateNames.add(candidate.getChild(CANDIDATE_NAME_NODE_ID).get().getValue().toString());
}
Optional<DataContainerChild<? extends PathArgument, ?>> possibleOwner =
entityNode.getChild(ENTITY_OWNER_NODE_ID);
String currentOwner = possibleOwner.isPresent() ? possibleOwner.get().getValue().toString() : "";
- if(ownedBy.contains(currentOwner)) {
+ if (ownedBy.contains(currentOwner)) {
walker.onEntity(entityTypeNode, entityNode);
}
});
private void searchForEntities(EntityWalker walker) {
Optional<NormalizedNode<?, ?>> possibleEntityTypes = getDataStore().readNode(ENTITY_TYPES_PATH);
- if(!possibleEntityTypes.isPresent()) {
+ if (!possibleEntityTypes.isPresent()) {
return;
}
- for(MapEntryNode entityType: ((MapNode) possibleEntityTypes.get()).getValue()) {
+ for (MapEntryNode entityType: ((MapNode) possibleEntityTypes.get()).getValue()) {
Optional<DataContainerChild<?, ?>> possibleEntities = entityType.getChild(ENTITY_NODE_ID);
- if(!possibleEntities.isPresent()) {
+ if (!possibleEntities.isPresent()) {
// shouldn't happen but handle anyway
continue;
}
- for(MapEntryNode entity: ((MapNode) possibleEntities.get()).getValue()) {
+ for (MapEntryNode entity: ((MapNode) possibleEntities.get()).getValue()) {
walker.onEntity(entityType, entity);
}
}
/**
* Schedule a new owner selection job. Cancelling any outstanding job if it has not been cancelled.
- *
- * @param entityPath
- * @param allCandidates
*/
- public void scheduleOwnerSelection(YangInstanceIdentifier entityPath, Collection<String> allCandidates,
- EntityOwnerSelectionStrategy strategy){
+ private void scheduleOwnerSelection(YangInstanceIdentifier entityPath, Collection<String> allCandidates,
+ EntityOwnerSelectionStrategy strategy) {
cancelOwnerSelectionTask(entityPath);
LOG.debug("{}: Scheduling owner selection after {} ms", persistenceId(), strategy.getSelectionDelayInMillis());
final Cancellable lastScheduledTask = context().system().scheduler().scheduleOnce(
- FiniteDuration.apply(strategy.getSelectionDelayInMillis(), TimeUnit.MILLISECONDS)
- , self(), new SelectOwner(entityPath, allCandidates, strategy)
- , context().system().dispatcher(), self());
+ FiniteDuration.apply(strategy.getSelectionDelayInMillis(), TimeUnit.MILLISECONDS), self(),
+ new SelectOwner(entityPath, allCandidates, strategy), context().system().dispatcher(), self());
entityToScheduledOwnershipTask.put(entityPath, lastScheduledTask);
}
- private void cancelOwnerSelectionTask(YangInstanceIdentifier entityPath){
+ private void cancelOwnerSelectionTask(YangInstanceIdentifier entityPath) {
final Cancellable lastScheduledTask = entityToScheduledOwnershipTask.get(entityPath);
- if(lastScheduledTask != null && !lastScheduledTask.isCancelled()){
+ if (lastScheduledTask != null && !lastScheduledTask.isCancelled()) {
lastScheduledTask.cancel();
}
}
- private String newOwner(String currentOwner, Collection<String> candidates, EntityOwnerSelectionStrategy ownerSelectionStrategy) {
+ private String newOwner(String currentOwner, Collection<String> candidates,
+ EntityOwnerSelectionStrategy ownerSelectionStrategy) {
Collection<String> viableCandidates = getViableCandidates(candidates);
- if(viableCandidates.isEmpty()){
+ if (viableCandidates.isEmpty()) {
return "";
}
return ownerSelectionStrategy.newOwner(currentOwner, viableCandidates);
private String getCurrentOwner(YangInstanceIdentifier entityId) {
Optional<NormalizedNode<?, ?>> optionalEntityOwner = getDataStore().readNode(entityId.node(ENTITY_OWNER_QNAME));
- if(optionalEntityOwner.isPresent()){
+ if (optionalEntityOwner.isPresent()) {
return optionalEntityOwner.get().getValue().toString();
}
return null;
super(EntityOwnershipShard.class);
}
- Builder localMemberName(MemberName localMemberName) {
+ Builder localMemberName(MemberName newLocalMemberName) {
checkSealed();
- this.localMemberName = localMemberName;
+ this.localMemberName = newLocalMemberName;
return this;
}
- Builder ownerSelectionStrategyConfig(EntityOwnerSelectionStrategyConfig ownerSelectionStrategyConfig){
+ Builder ownerSelectionStrategyConfig(EntityOwnerSelectionStrategyConfig newOwnerSelectionStrategyConfig) {
checkSealed();
- this.ownerSelectionStrategyConfig = ownerSelectionStrategyConfig;
+ this.ownerSelectionStrategyConfig = newOwnerSelectionStrategyConfig;
return this;
}
boolean handleMessage(Object message, EntityOwnershipShard shard) {
boolean handled = true;
- if(CommitTransactionReply.isSerializedType(message)) {
+ if (CommitTransactionReply.isSerializedType(message)) {
// Successful reply from a local commit.
inflightCommitSucceeded(shard);
- } else if(message instanceof akka.actor.Status.Failure) {
+ } else if (message instanceof akka.actor.Status.Failure) {
// Failure reply from a local commit.
- inflightCommitFailure(((Failure)message).cause(), shard);
- } else if(COMMIT_RETRY_MESSAGE.equals(message)) {
+ inflightCommitFailure(((Failure) message).cause(), shard);
+ } else if (COMMIT_RETRY_MESSAGE.equals(message)) {
retryInflightCommit(shard);
} else {
handled = false;
private void retryInflightCommit(EntityOwnershipShard shard) {
// Shouldn't be null happen but verify anyway
- if(inflightCommit == null) {
+ if (inflightCommit == null) {
return;
}
- if(shard.hasLeader()) {
+ if (shard.hasLeader()) {
log.debug("Retrying commit for BatchedModifications {}", inflightCommit.getTransactionID());
shard.tryCommitModifications(inflightCommit);
void inflightCommitFailure(Throwable cause, EntityOwnershipShard shard) {
// This should've originated from a failed inflight commit but verify anyway
- if(inflightCommit == null) {
+ if (inflightCommit == null) {
return;
}
log.debug("Inflight BatchedModifications {} commit failed", inflightCommit.getTransactionID(), cause);
- if(!(cause instanceof NoShardLeaderException)) {
+ if (!(cause instanceof NoShardLeaderException)) {
// If the failure is other than NoShardLeaderException the commit may have been partially
// processed so retry with a new transaction ID to be safe.
newInflightCommitWithDifferentTransactionID();
void inflightCommitSucceeded(EntityOwnershipShard shard) {
// Shouldn't be null but verify anyway
- if(inflightCommit == null) {
+ if (inflightCommit == null) {
return;
}
- if(retryCommitSchedule != null) {
+ if (retryCommitSchedule != null) {
retryCommitSchedule.cancel();
}
}
void commitNextBatch(EntityOwnershipShard shard) {
- if(inflightCommit != null || pendingModifications.isEmpty() || !shard.hasLeader()) {
+ if (inflightCommit != null || pendingModifications.isEmpty() || !shard.hasLeader()) {
return;
}
inflightCommit = newBatchedModifications();
Iterator<Modification> iter = pendingModifications.iterator();
- while(iter.hasNext()) {
+ while (iter.hasNext()) {
inflightCommit.addModification(iter.next());
iter.remove();
- if(inflightCommit.getModifications().size() >=
- shard.getDatastoreContext().getShardBatchedModificationCount()) {
+ if (inflightCommit.getModifications().size()
+ >= shard.getDatastoreContext().getShardBatchedModificationCount()) {
break;
}
}
}
void commitModifications(BatchedModifications modifications, EntityOwnershipShard shard) {
- if(modifications.getModifications().isEmpty()) {
+ if (modifications.getModifications().isEmpty()) {
return;
}
boolean hasLeader = shard.hasLeader();
- if(inflightCommit != null || !hasLeader) {
- if(log.isDebugEnabled()) {
+ if (inflightCommit != null || !hasLeader) {
+ if (log.isDebugEnabled()) {
log.debug("{} - adding modifications to pending",
inflightCommit != null ? "A commit is inflight" : "No shard leader");
}
possiblyPrunePendingCommits(shard, isLeader);
- if(!isLeader && inflightCommit != null) {
+ if (!isLeader && inflightCommit != null) {
// We're no longer the leader but we have an inflight local commit. This likely means we didn't get
// consensus for the commit and switched to follower due to another node with a higher term. We
// can't be sure if the commit was replicated to any node so we retry it here with a new
// transaction ID.
- if(retryCommitSchedule != null) {
+ if (retryCommitSchedule != null) {
retryCommitSchedule.cancel();
}
shard.convertPendingTransactionsToMessages();
// Prune the inflightCommit.
- if(inflightCommit != null) {
+ if (inflightCommit != null) {
inflightCommit = pruneModifications(inflightCommit);
}
// Prune the subsequent pending modifications.
Iterator<Modification> iter = pendingModifications.iterator();
- while(iter.hasNext()) {
+ while (iter.hasNext()) {
Modification mod = iter.next();
- if(!canForwardModificationToNewLeader(mod)) {
+ if (!canForwardModificationToNewLeader(mod)) {
iter.remove();
}
}
@Nullable
private BatchedModifications pruneModifications(BatchedModifications toPrune) {
- BatchedModifications prunedModifications = new BatchedModifications(toPrune.getTransactionID(), toPrune.getVersion());
+ BatchedModifications prunedModifications = new BatchedModifications(toPrune.getTransactionID(),
+ toPrune.getVersion());
prunedModifications.setDoCommitOnReady(toPrune.isDoCommitOnReady());
prunedModifications.setReady(toPrune.isReady());
prunedModifications.setTotalMessagesSent(toPrune.getTotalMessagesSent());
- for(Modification mod: toPrune.getModifications()) {
- if(canForwardModificationToNewLeader(mod)) {
+ for (Modification mod: toPrune.getModifications()) {
+ if (canForwardModificationToNewLeader(mod)) {
prunedModifications.addModification(mod);
}
}
package org.opendaylight.controller.cluster.datastore.entityownership;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.entityTypeFromEntityPath;
+
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.romix.scala.collection.concurrent.TrieMap;
/**
* EntityOwnershipStatistics is a utility class that keeps track of ownership statistics for the candidates and
* caches it for quick count queries.
- * <p>
+ * <p/>
* While the entity ownership model does maintain the information about which entity is owned by which candidate
* finding out how many entities of a given type are owned by a given candidate is not an efficient query.
*/
class EntityOwnershipStatistics extends AbstractEntityOwnerChangeListener {
- private TrieMap<String, TrieMap<String, Long>> statistics = new TrieMap<>();
+ private final TrieMap<String, TrieMap<String, Long>> statistics = new TrieMap<>();
EntityOwnershipStatistics(){
}
LeafNode<?> ownerLeaf = (LeafNode<?>) changeRoot.getDataAfter().get();
String entityType = entityTypeFromEntityPath(change.getRootPath());
String newOwner = extractOwner(ownerLeaf);
- if(!Strings.isNullOrEmpty(newOwner)) {
+ if (!Strings.isNullOrEmpty(newOwner)) {
updateStatistics(entityType, newOwner, 1);
}
Optional<NormalizedNode<?, ?>> dataBefore = changeRoot.getDataBefore();
if (dataBefore.isPresent()) {
String origOwner = extractOwner((LeafNode<?>) changeRoot.getDataBefore().get());
- if(!Strings.isNullOrEmpty(origOwner)) {
+ if (!Strings.isNullOrEmpty(origOwner)) {
updateStatistics(entityType, origOwner, -1);
}
}
return snapshot;
}
- Map<String, Long> byEntityType(String entityType){
- if(statistics.get(entityType) != null) {
+ Map<String, Long> byEntityType(String entityType) {
+ if (statistics.get(entityType) != null) {
return statistics.get(entityType).readOnlySnapshot();
}
return new HashMap<>();
}
- private void updateStatistics(String entityType, String candidateName, long count){
- Map<String, Long> m = statistics.get(entityType);
- if(m == null){
- m = new TrieMap<>();
- m.put(candidateName, count);
- statistics.put(entityType, m);
+ private void updateStatistics(String entityType, String candidateName, long count) {
+ Map<String, Long> map = statistics.get(entityType);
+ if (map == null) {
+ map = new TrieMap<>();
+ map.put(candidateName, count);
+ statistics.put(entityType, map);
} else {
- Long candidateOwnedEntities = m.get(candidateName);
- if(candidateOwnedEntities == null){
- m.put(candidateName, count);
+ Long candidateOwnedEntities = map.get(candidateName);
+ if (candidateOwnedEntities == null) {
+ map.put(candidateName, count);
} else {
- m.put(candidateName, candidateOwnedEntities + count);
+ map.put(candidateName, candidateOwnedEntities + count);
}
}
}
-}
\ No newline at end of file
+}
private final String removedCandidate;
private final Collection<String> remainingCandidates;
- public CandidateRemoved(YangInstanceIdentifier entityPath, String removedCandidate, Collection<String> remainingCandidates) {
+ public CandidateRemoved(YangInstanceIdentifier entityPath, String removedCandidate,
+ Collection<String> remainingCandidates) {
this.entityPath = entityPath;
this.removedCandidate = removedCandidate;
this.remainingCandidates = remainingCandidates;
import org.opendaylight.controller.cluster.access.concepts.MemberName;
/**
- * Message sent by an EntityOwnershipShard to its leader on startup to remove all its candidates. .
+ * Message sent by an EntityOwnershipShard to its leader on startup to remove all its candidates.
*
* @author Thomas Pantelis
*/
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
/**
- * Message sent when a new owner needs to be selected
+ * Message sent when a new owner needs to be selected.
*/
public class SelectOwner {
private final YangInstanceIdentifier entityPath;
@Override
public String toString() {
- return "SelectOwner{" +
- "entityPath=" + entityPath +
- ", allCandidates=" + allCandidates +
- ", ownerSelectionStrategy=" + ownerSelectionStrategy +
- '}';
+ return "SelectOwner [entityPath=" + entityPath + ", allCandidates=" + allCandidates
+ + ", ownerSelectionStrategy=" + ownerSelectionStrategy + "]";
}
}
/**
* An EntityOwnerSelectionStrategy is to be used by the EntityOwnershipShard to select a new owner from a collection
- * of candidates
+ * of candidates.
*/
public interface EntityOwnerSelectionStrategy {
/**
+ * Returns the time in millis owner selection should be delayed.
*
* @return the time in millis owner selection should be delayed
*/
/**
+ * Selects a new owner from the list of viable candidates.
+ *
* @param currentOwner the current owner of the entity if any, null otherwise
* @param viableCandidates the available candidates from which to choose the new owner
* @return the new owner
return entityTypeToStrategyInfo.get(entityType) != null;
}
- public EntityOwnerSelectionStrategy createStrategy(String entityType, Map<String, Long> initialStatistics){
+ public EntityOwnerSelectionStrategy createStrategy(String entityType, Map<String, Long> initialStatistics) {
final EntityOwnerSelectionStrategy strategy;
final EntityOwnerSelectionStrategy existingStrategy = entityTypeToOwnerSelectionStrategy.get(entityType);
- if(existingStrategy != null){
+ if (existingStrategy != null) {
strategy = existingStrategy;
} else {
EntityOwnerSelectionStrategyConfig.StrategyInfo strategyInfo = entityTypeToStrategyInfo.get(entityType);
- if(strategyInfo == null){
+ if (strategyInfo == null) {
strategy = FirstCandidateSelectionStrategy.INSTANCE;
} else {
strategy = strategyInfo.createStrategy(initialStatistics);
}
/**
- * @deprecated FIXME: THIS IS CONFIGURATION FOR A CUSTOM-LOADED CLASS CONSTRUCTOR
- *
* This class should not exist. It contains a single long, which is passed to the constructor (via reflection).
* We are getting that information from a BundleContext. We are running in OSGi environment, hence this class
* needs to be deployed in its own bundle, with its own configuration.
- *
* If this is used internally, it needs to be relocated into a separate package along with the implementation
* using it.
+ *
+ * @deprecated FIXME: THIS IS CONFIGURATION FOR A CUSTOM-LOADED CLASS CONSTRUCTOR
*/
@Deprecated
public void clearStrategies() {
this.delay = delay;
}
- public EntityOwnerSelectionStrategy createStrategy(Map<String, Long> initialStatistics){
+ public EntityOwnerSelectionStrategy createStrategy(Map<String, Long> initialStatistics) {
try {
- return strategyClass.getDeclaredConstructor(long.class, Map.class).newInstance(delay, initialStatistics);
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ return strategyClass.getDeclaredConstructor(long.class, Map.class)
+ .newInstance(delay, initialStatistics);
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException
+ | NoSuchMethodException e) {
LOG.warn("could not create custom strategy", e);
}
return FirstCandidateSelectionStrategy.INSTANCE;
public static class Builder {
private final EntityOwnerSelectionStrategyConfig config;
- private Builder(final EntityOwnerSelectionStrategyConfig config){
+ private Builder(final EntityOwnerSelectionStrategyConfig config) {
this.config = config;
}
- public Builder addStrategy(final String entityType, final Class<? extends EntityOwnerSelectionStrategy> strategy, final long delay){
+ public Builder addStrategy(final String entityType,
+ final Class<? extends EntityOwnerSelectionStrategy> strategy, final long delay) {
config.entityTypeToStrategyInfo.put(entityType, new StrategyInfo(strategy, delay));
return this;
}
- public EntityOwnerSelectionStrategyConfig build(){
+ public EntityOwnerSelectionStrategyConfig build() {
return this.config;
}
}
import org.slf4j.LoggerFactory;
/**
+ * Reads the entity owner selection strategy config.
+ *
* @deprecated FIXME: Service injection class. This class needs to be eliminated in favor of proper service injection,
* which can be any of OSGi (which this class uses internally), java.util.ServiceLoader, or config
* subsystem.
// Hidden on purpose
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
public static EntityOwnerSelectionStrategyConfig loadStrategyWithConfig(final BundleContext bundleContext) {
final EntityOwnerSelectionStrategyConfig.Builder builder = EntityOwnerSelectionStrategyConfig.newBuilder();
return builder.build();
}
- private static EntityOwnerSelectionStrategyConfig parseConfiguration(final Builder builder, final Configuration config) {
+ private static EntityOwnerSelectionStrategyConfig parseConfiguration(final Builder builder,
+ final Configuration config) {
// Historic note: java.util.Dictionary since introduction of java.util.Map in Java 1.2
final Dictionary<String, Object> properties = config.getProperties();
if (properties == null) {
throws ClassNotFoundException {
final Class<?> clazz;
try {
- clazz = EntityOwnerSelectionStrategyConfigReader.class.getClassLoader().loadClass(strategyClassAndDelay);
+ clazz = EntityOwnerSelectionStrategyConfigReader.class.getClassLoader().loadClass(strategyClassAndDelay);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Failed to load strategy " + strategyClassAndDelay);
}
import java.util.Map;
/**
- * The FirstCandidateSelectionStrategy always selects the first viable candidate from the list of candidates
+ * The FirstCandidateSelectionStrategy always selects the first viable candidate from the list of candidates.
*/
public class FirstCandidateSelectionStrategy extends AbstractEntityOwnerSelectionStrategy {
- public static final FirstCandidateSelectionStrategy INSTANCE = new FirstCandidateSelectionStrategy(0L, Collections.emptyMap());
+ public static final FirstCandidateSelectionStrategy INSTANCE =
+ new FirstCandidateSelectionStrategy(0L, Collections.emptyMap());
public FirstCandidateSelectionStrategy(long selectionDelayInMillis, Map<String, Long> initialStatistics) {
super(selectionDelayInMillis, initialStatistics);
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* The LeastLoadedCandidateSelectionStrategy assigns ownership for an entity to the candidate which owns the least
* number of entities.
*/
public class LeastLoadedCandidateSelectionStrategy extends AbstractEntityOwnerSelectionStrategy {
- private static final Logger LOG = LoggerFactory.getLogger(LeastLoadedCandidateSelectionStrategy.class);
-
- private Map<String, Long> localStatistics = new HashMap<>();
+ private final Map<String, Long> localStatistics = new HashMap<>();
protected LeastLoadedCandidateSelectionStrategy(long selectionDelayInMillis, Map<String, Long> initialStatistics) {
super(selectionDelayInMillis, initialStatistics);
String leastLoadedCandidate = null;
long leastLoadedCount = Long.MAX_VALUE;
- if(!Strings.isNullOrEmpty(currentOwner)){
+ if (!Strings.isNullOrEmpty(currentOwner)) {
long localVal = MoreObjects.firstNonNull(localStatistics.get(currentOwner), 0L);
localStatistics.put(currentOwner, localVal - 1);
}
- for(String candidateName : viableCandidates){
+ for (String candidateName : viableCandidates) {
long val = MoreObjects.firstNonNull(localStatistics.get(candidateName), 0L);
- if(val < leastLoadedCount){
+ if (val < leastLoadedCount) {
leastLoadedCount = val;
leastLoadedCandidate = candidateName;
}
}
- if(leastLoadedCandidate == null){
+ if (leastLoadedCandidate == null) {
leastLoadedCandidate = viableCandidates.iterator().next();
}
}
@VisibleForTesting
- Map<String, Long> getLocalStatistics(){
+ Map<String, Long> getLocalStatistics() {
return localStatistics;
}
}