com.gemstone.gemfire.distributed.internal.membership.jgroup.JGroupMember Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
The newest version!
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.distributed.internal.membership.jgroup;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.net.InetAddress;
import com.gemstone.gemfire.InternalGemFireError;
import com.gemstone.gemfire.distributed.DurableClientAttributes;
import com.gemstone.gemfire.distributed.internal.membership.NetMember;
import com.gemstone.gemfire.distributed.internal.membership.MemberAttributes;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import com.gemstone.gemfire.internal.shared.Version;
import com.gemstone.org.jgroups.JChannel;
import com.gemstone.org.jgroups.stack.IpAddress;
/**
* This is the fundamental representation of a member of a GemFire distributed system.
*
* Unfortunately, this class serves two distinct functions. First, it is the
* fundamental element of membership in the GemFire distributed system. As such,
* it is used in enumerations and properly responds to hashing and equals() comparisons.
*
* Second, it is used as a cheap way of representing an address. This is
* unfortunate, because as a NetMember, it holds two separate port numbers: the
* "membership" descriptor as well as a direct communication channel.
*
* TODO fix this.
*/
public final class JGroupMember implements NetMember {
private transient IpAddress ipAddr;
// Used only by Externalization
public JGroupMember() {
}
/** the JGroups address object */
public IpAddress getAddress() {
return ipAddr;
}
public MemberAttributes getAttributes() {
return new MemberAttributes(ipAddr.getDirectPort(), ipAddr.getProcessId(),
ipAddr.getVmKind(), ipAddr.getBirthViewId(), ipAddr.getName(), ipAddr.getRoles(),
(DurableClientAttributes)ipAddr.getDurableClientAttributes());
}
public void setAttributes(MemberAttributes p_attr) {
MemberAttributes attr = p_attr;
if (attr == null) {
attr = MemberAttributes.INVALID;
}
GFJGBasicAdapter.insertGemFireAttributes(ipAddr, attr);
}
/**
* This constructor used internally, esp. for views
*
* @param base
*/
public JGroupMember(IpAddress base) {
ipAddr = base;
}
/**
* This is the only constructor to refer to a CacheMember other
* than the current host.
*/
public JGroupMember(JGroupMember m) {
ipAddr = m.ipAddr; // This should be ok, since they shouldn't change
}
/**
* Create a CacheMember referring to the current host (as defined by
* the given string).
*
* @param i the hostname, must be for the current host
* @param p the membership listening port
*/
public JGroupMember(String i, int p) {
ipAddr = new IpAddress(i, p);
// ipAddr.splitBrainEnabled(false);
// ipAddr.cantBeCoordinator(false);
}
/**
* Create a CacheMember referring to the current host (as defined by
* the given string).
*
* @param i the hostname, must be for the current host
* @param p the membership listening port
* @param splitBrainEnabled whether the member has network partition detection enabled
* @param canBeCoordinator whether the member can be group coordinator
*/
public JGroupMember(InetAddress i, int p, boolean splitBrainEnabled, boolean canBeCoordinator) {
ipAddr = new IpAddress(i, p);
ipAddr.splitBrainEnabled(splitBrainEnabled);
ipAddr.shouldntBeCoordinator(!canBeCoordinator);
}
/**
* Create a CacheMember referring to the current host
*
* @param port the membership listening port
*/
public JGroupMember(int port) {
ipAddr = new IpAddress(port);
}
public final InetAddress getIpAddress() {
return ipAddr.getIpAddress();
}
public final int getPort() {
return ipAddr.getPort();
}
public boolean isMulticastAddress() {
return ipAddr.isMulticastAddress();
}
public boolean splitBrainEnabled() {
return ipAddr.splitBrainEnabled();
}
public boolean canBeCoordinator() {
return ipAddr.preferredForCoordinator();
}
/**
* Establishes an order between 2 addresses. Assumes other contains non-null IpAddress.
* Excludes channel_name from comparison.
* @return 0 for equality, value less than 0 if smaller, greater than 0 if greater.
*/
public int compare(NetMember other) {
return compareTo(other);
}
/**
* implements the java.lang.Comparable interface
* @see java.lang.Comparable
* @param o - the Object to be compared
* @return a negative integer, zero, or a positive integer as this object is less than,
* equal to, or greater than the specified object.
* @exception java.lang.ClassCastException - if the specified object's type prevents it
* from being compared to this Object.
*/
public int compareTo(Object o) {
if (o == this) {
return 0;
}
// obligatory type check
if ((o == null) || !(o instanceof JGroupMember))
throw new ClassCastException(LocalizedStrings.JGroupMember_JGROUPMEMBERCOMPARETO_COMPARISON_BETWEEN_DIFFERENT_CLASSES.toLocalizedString());
return ipAddr.compareTo(((JGroupMember)o).ipAddr);
}
@Override
public boolean equals(Object obj) {
// GemStone fix for 29125
if ((obj == null) || !(obj instanceof JGroupMember)) {
return false;
}
return compareTo(obj) == 0;
}
@Override
public int hashCode() {
return ipAddr.hashCode();
}
@Override
public String toString() {
return ipAddr.toString();
}
/**
* For Externalizable
*
* @see java.io.Externalizable
*/
public void writeExternal(ObjectOutput out) throws IOException {
if (ipAddr == null)
throw new InternalGemFireError(LocalizedStrings.JGroupMember_ATTEMPT_TO_EXTERNALIZE_NULL_IP_ADDRESS.toLocalizedString());
// ipAddr.writeExternal(out);
// do it the way we like
byte[] address = ipAddr.getIpAddress().getAddress();
out.writeInt(address.length); // IPv6 compatible
out.write(address);
out.writeInt(ipAddr.getPort());
out.write(ipAddr.getFlags());
Version.writeOrdinal(out, ipAddr.getVersionOrdinal(), true);
byte bytes[] = new MemberAttributes(ipAddr.getDirectPort(), ipAddr.getProcessId(),
ipAddr.getVmKind(), ipAddr.getBirthViewId(), ipAddr.getName(), ipAddr.getRoles(),
(DurableClientAttributes)ipAddr.getDurableClientAttributes()).toByteArray();
if (bytes == null)
out.writeInt(0);
else {
out.writeInt(bytes.length);
out.write(bytes);
}
}
/**
* For Externalizable
*
* @see java.io.Externalizable
*/
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
// ipAddr = new IpAddress();
// ipAddr.readExternal(in);
// do it the way we like
int len = in.readInt(); // IPv6 compatible
byte addr[] = new byte[len];
in.readFully(addr);
InetAddress ia = InetAddress.getByAddress(addr);
int port = in.readInt();
byte flags = in.readByte();
ipAddr = new IpAddress(ia, port);
ipAddr.setFlags(flags);
ipAddr.readVersion(flags, in);
len = in.readInt();
if (len != 0) {
byte bytes[] = new byte[len];
in.readFully(bytes);
GFJGBasicAdapter.insertGemFireAttributes(ipAddr, new MemberAttributes(bytes));
}
}
public void setPort(int p) {
IpAddress i = new IpAddress(ipAddr.getIpAddress(), p);
i.setFlags(ipAddr.getFlags());
i.setVmKind(ipAddr.getVmKind());
i.setDirectPort(ipAddr.getDirectPort());
i.setProcessId(ipAddr.getProcessId());
i.setRoles(ipAddr.getRoles());
i.setDurableClientAttributes(ipAddr.getDurableClientAttributes());
i.setVersionOrdinal(ipAddr.getVersionOrdinal());
this.ipAddr = i;
}
}