/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltcore.messaging;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Optional;
import java.util.Set;
import org.apache.zookeeper_voltpatches.ZooKeeper;
import org.json_voltpatches.JSONObject;
import org.json_voltpatches.JSONString;
import org.voltcore.utils.VersionChecker;
import com.google_voltpatches.common.base.Supplier;
import com.google_voltpatches.common.base.Suppliers;
import com.google_voltpatches.common.collect.ImmutableSortedSet;
import com.google_voltpatches.common.net.HostAndPort;
/**
* An interface that allows non voltcore components to effect how hosts
* can become or not mesh members
*/
public interface JoinAcceptor extends JSONString {
/**
* Give the acceptor the {@link JSONObject} provided at the initial connection handshake
*
* @param hostId host id for the new connection
* @param jo the {@link JSONObject} provided at the initial connection handshake
*/
public void accrue(int hostId, JSONObject jo);
/**
* Give the acceptor a map of host ids and {@link JSONObject} provided at the initial
* connection handshake
*
* @param jos a map of host ids and {@link JSONObject}
*/
public void accrue(Map<Integer, JSONObject> jos);
/**
* Allows the acceptor to inject its fields into the connection handshake message
* @param jo the initial handshake message
*/
default JSONObject decorate(JSONObject jo, Optional<Boolean> paused) {
return jo;
}
/**
* Returns the list of mesh coordinators
* @return the list of mesh coordinators
*/
default NavigableSet<String> getCoordinators() {
return ImmutableSortedSet.of("");
}
/**
* notifies the acceptor when a host is removed from the mesh
* @param hostId
*/
public void detract(int hostId);
/**
* notifies the acceptor when a {@link Set<Integer>} hostIds
* are removed from the mesh
*
* @param hostIds a {@link Set<Integer>} of removed hostIds
*/
public void detract(Set<Integer> hostIds);
/**
* On accepting a connection the acceptor is queried whether or
* not the mesh plea should be accepted or not, and if it is not
* if it can be retried
*
* @param zk a {@link ZooKeeper} connection
* @param hostId hostId
* @param jo the {@link JSONObject} provided at the initial connection handshake
* @return a {@link PleaDecision}
*/
default PleaDecision considerMeshPlea(ZooKeeper zk, int hostId, JSONObject jo) {
return new PleaDecision(null /* no error message */, true /* accepted */, false /* retriable */);
}
public static class PleaDecision {
public final String errMsg;
public final boolean accepted;
public final boolean mayRetry;
public PleaDecision(String errMsg, boolean accepted, boolean mayRetry) {
this.errMsg = errMsg;
this.accepted = accepted;
this.mayRetry = mayRetry;
}
@Override
public String toString() {
return "PleaDecision [errMsg=" + errMsg + ", accepted=" + accepted
+ ", mayRetry=" + mayRetry + "]";
}
}
/**
* Memoized supplier of version information so that it reads files only once
*/
static final public Supplier<String[]> versionSupplier =
Suppliers.memoize(
new Supplier<String[]>() {
@Override
public String[] get() {
return org.voltdb.RealVoltDB.extractBuildInfo(null);
}
});
static final VersionChecker DEFAULT_VERSION_CHECKER = new VersionChecker() {
@Override
public boolean isCompatibleVersionString(String other) {
return org.voltdb.RealVoltDB.staticIsCompatibleVersionString(other);
}
@Override
public String getVersionString() {
return versionSupplier.get()[0];
}
@Override
public String getBuildString() {
return versionSupplier.get()[1];
}
};
/**
* @return a version checker
*/
default VersionChecker getVersionChecker() {
return DEFAULT_VERSION_CHECKER;
}
/**
* Get the the first coordinator in lexicographical order
* @return the first coordinator in lexicographical order
*/
default HostAndPort getLeader() {
return HostAndPort.fromString(getCoordinators().first())
.withDefaultPort(org.voltcore.common.Constants.DEFAULT_INTERNAL_PORT);
}
@Override
default String toJSONString() {
return "{}";
}
}