/**
* Licensed to the zk1931 under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zk1931.jzab;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.Properties;
import com.github.zk1931.jzab.proto.ZabMessage;
import com.github.zk1931.jzab.proto.ZabMessage.Proposal.ProposalType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Configurations(ensemble of cluster, serverId, version).
*/
class ClusterConfiguration implements Cloneable {
private Zxid version;
private final Set<String> peers;
private final String serverId;
private static final Logger LOG =
LoggerFactory.getLogger(ClusterConfiguration.class);
public ClusterConfiguration(Zxid version,
Collection<String> peers,
String serverId) {
this.version = version;
this.peers = new HashSet<String>(peers);
this.serverId = serverId;
};
public Zxid getVersion() {
return this.version;
}
public void setVersion(Zxid newVersion) {
this.version = newVersion;
}
public Set<String> getPeers() {
return this.peers;
}
public String getServerId() {
return this.serverId;
}
public void addPeer(String peer) {
peers.add(peer);
}
public void removePeer(String peer) {
this.peers.remove(peer);
}
public Properties toProperties() {
Properties prop = new Properties();
StringBuilder strBuilder = new StringBuilder();
String strVersion = this.version.toSimpleString();
if (!this.peers.isEmpty()) {
String[] peersArray = this.peers.toArray(new String[this.peers.size()]);
strBuilder.append(peersArray[0]);
for (int i = 1; i < peersArray.length; ++i) {
strBuilder.append("," + peersArray[i]);
}
}
prop.setProperty("peers", strBuilder.toString());
prop.setProperty("version", strVersion);
prop.setProperty("serverId", this.serverId);
return prop;
}
public static ClusterConfiguration fromProperties(Properties prop) {
String strPeers = prop.getProperty("peers");
Zxid version = Zxid.fromSimpleString(prop.getProperty("version"));
String serverId = prop.getProperty("serverId");
Set<String> peerSet;
if (strPeers.equals("")) {
peerSet = new HashSet<String>();
} else {
peerSet = new HashSet<String>(Arrays.asList(strPeers.split(",")));
}
return new ClusterConfiguration(version, peerSet, serverId);
}
public static
ClusterConfiguration fromProto(ZabMessage.ClusterConfiguration cnf,
String serverId) {
Zxid version = MessageBuilder.fromProtoZxid(cnf.getVersion());
return new ClusterConfiguration(version, cnf.getServersList(), serverId);
}
public ZabMessage.ClusterConfiguration toProto() {
return MessageBuilder.buildConfig(this);
}
public ByteBuffer toByteBuffer() {
return ByteBuffer.wrap(toProto().toByteArray());
}
public static ClusterConfiguration fromByteBuffer(ByteBuffer buffer,
String serverId)
throws IOException {
byte[] bufArray = new byte[buffer.remaining()];
buffer.get(bufArray);
return fromProto(ZabMessage.ClusterConfiguration.parseFrom(bufArray),
serverId);
}
public Transaction toTransaction() {
ByteBuffer cop = this.toByteBuffer();
Transaction txn = new Transaction(version, ProposalType.COP_VALUE, cop);
return txn;
}
public boolean contains(String peerId) {
return this.peers.contains(peerId);
}
@Override
public String toString() {
return toProperties().toString();
}
/**
* Gets the minimal quorum size.
*/
public int getQuorumSize() {
int clusterSize = this.getPeers().size();
if (clusterSize == 0) {
return 0;
} else {
return clusterSize / 2 + 1;
}
}
public ClusterConfiguration clone() {
return new ClusterConfiguration(version, peers, serverId);
}
}