in src/main/java/org/apache/sling/discovery/impl/cluster/voting/VotingView.java [339:425]
public void vote(final String slingId, final Boolean vote,
final String leaderElectionId) {
if (logger.isDebugEnabled()) {
logger.debug("vote: slingId=" + slingId + ", vote=" + vote);
}
Resource r = getResource();
if (r == null) {
logger.error("vote: no resource set. slingId = " + slingId + ", vote=" + vote);
return;
}
Resource members = r.getChild("members");
if (members == null) {
logger.error("vote: no members resource available for " + r + ". slingId = " + slingId + ", vote=" + vote);
return;
}
final Resource memberResource = members.getChild(
slingId);
if (memberResource == null) {
if (vote == null || !vote) {
// if I wanted to vote no or empty, then it's no big deal
// that I can't find my entry ..
logger.debug("vote: no memberResource found for slingId=" + slingId
+ ", vote=" + vote + ", resource=" + getResource());
} else {
// if I wanted to vote yes, then it is a big deal that I can't find myself
logger.error("vote: no memberResource found for slingId=" + slingId
+ ", vote=" + vote + ", resource=" + getResource());
}
return;
}
final ModifiableValueMap memberMap = memberResource.adaptTo(ModifiableValueMap.class);
if (vote == null) {
if (memberMap.containsKey("vote")) {
logger.info("vote: removing vote (vote==null) of slingId="+slingId+" on: "+this);
} else {
logger.debug("vote: removing vote (vote==null) of slingId="+slingId+" on: "+this);
}
memberMap.remove("vote");
} else {
boolean shouldVote = true;
try {
if (memberMap.containsKey("vote")) {
Object v = memberMap.get("vote");
if (v instanceof Property) {
Property p = (Property)v;
if (p.getBoolean() == vote) {
logger.debug("vote: already voted, with same vote ("+vote+"), not voting again");
shouldVote = false;
}
} else if (v instanceof Boolean) {
Boolean b = (Boolean)v;
if (b.equals(vote)) {
logger.debug("vote: already voted, with same vote ("+vote+"), not voting again");
shouldVote = false;
}
}
}
} catch (ValueFormatException e) {
logger.warn("vote: got a ValueFormatException: "+e, e);
} catch (RepositoryException e) {
logger.warn("vote: got a RepositoryException: "+e, e);
}
if (shouldVote) {
logger.info("vote: slingId=" + slingId + " is voting vote=" + vote+" on "+getResource());
memberMap.put("vote", vote);
memberMap.put("votedAt", Calendar.getInstance());
String currentLeaderElectionId = memberMap.get("leaderElectionId", String.class);
if (leaderElectionId!=null &&
(currentLeaderElectionId == null || !currentLeaderElectionId.equals(leaderElectionId))) {
// SLING-5030 : to ensure leader-step-down after being
// isolated from the cluster, the leaderElectionId must
// be explicitly set upon voting.
// for 99% of the cases not be necessary,
// for the rejoin-after-isolation case however it is
logger.info("vote: changing leaderElectionId on vote to "+leaderElectionId);
memberMap.put("leaderElectionId", leaderElectionId);
memberMap.put("leaderElectionIdCreatedAt", new Date());
}
}
}
try {
getResource().getResourceResolver().commit();
} catch (PersistenceException e) {
logger.error("vote: PersistenceException while voting: "+e, e);
}
}