com.gemstone.gemfire.distributed.internal.membership.jgroup.GFJGBasicAdapter 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.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import com.gemstone.gemfire.DataSerializer;
import com.gemstone.gemfire.ForcedDisconnectException;
import com.gemstone.gemfire.GemFireConfigException;
import com.gemstone.gemfire.SystemConnectException;
import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
import com.gemstone.gemfire.distributed.internal.DistributionManager;
import com.gemstone.gemfire.distributed.internal.membership.MemberAttributes;
import com.gemstone.gemfire.distributed.internal.tcpserver.TcpServer;
import com.gemstone.gemfire.internal.InternalDataSerializer;
import com.gemstone.gemfire.internal.SocketCreator;
import com.gemstone.gemfire.internal.VersionedDataInputStream;
import com.gemstone.gemfire.internal.VersionedDataOutputStream;
import com.gemstone.gemfire.internal.VersionedObjectInput;
import com.gemstone.gemfire.internal.VersionedObjectOutput;
import com.gemstone.gemfire.internal.shared.UnsupportedGFXDVersionException;
import com.gemstone.gemfire.internal.shared.Version;
import com.gemstone.gemfire.security.AuthenticationFailedException;
import com.gemstone.org.jgroups.Header;
import com.gemstone.org.jgroups.Message;
import com.gemstone.org.jgroups.spi.GFBasicAdapter;
import com.gemstone.org.jgroups.stack.IpAddress;
import com.gemstone.org.jgroups.util.GemFireTracer;
import com.gemstone.org.jgroups.util.SockCreator;
import com.gemstone.org.jgroups.util.Util;
import com.gemstone.org.jgroups.util.VersionedStreamable;
public class GFJGBasicAdapter implements GFBasicAdapter {
public static void insertGemFireAttributes(IpAddress addr, Object obj) {
MemberAttributes attr = (MemberAttributes)obj;
addr.setProcessId(attr.getVmPid());
addr.setVmKind(attr.getVmKind());
addr.setDirectPort(attr.getPort());
addr.setBirthViewId(attr.getVmViewId());
addr.setName(attr.getName());
addr.setRoles(attr.getGroups());
addr.setDurableClientAttributes(attr.getDurableClientAttributes());
addr.setSize(-1);
addr.setSize(addr.size(Version.CURRENT_ORDINAL));
}
public static void insertDefaultGemFireAttributes(IpAddress addr) {
MemberAttributes attr = com.gemstone.gemfire.distributed.internal.membership.MemberAttributes.DEFAULT;
insertGemFireAttributes(addr, attr);
}
@Override
public void invokeToData(VersionedStreamable obj,
DataOutput out) throws IOException {
InternalDataSerializer.invokeToData(obj, out);
}
@Override
public void writeObject(Object obj, DataOutput out) throws IOException {
DataSerializer.writeObject(obj, out);
}
@Override
public void invokeFromData(VersionedStreamable obj,
DataInput in) throws IOException, ClassNotFoundException {
InternalDataSerializer.invokeFromData(obj, in);
}
@Override
public T readObject(DataInput in) throws IOException,
ClassNotFoundException {
return DataSerializer.readObject(in);
}
@Override
public short getMulticastVersionOrdinal() {
return Version.GFE_71.ordinal();
}
@Override
public short getSerializationVersionOrdinal(short version) {
return Version.fromOrdinalOrCurrent(version).ordinal();
}
@Override
public short getCurrentVersionOrdinal() {
return Version.CURRENT_ORDINAL;
}
@Override
public byte[] serializeWithVersion(Object obj, int destVersionOrdinal) {
try {
ByteArrayOutputStream out_stream=new ByteArrayOutputStream();
//ObjectOutputStream out=new ObjectOutputStream(out_stream);
//out.writeObject(obj);
DataOutputStream out = new DataOutputStream(out_stream);
if (destVersionOrdinal > 0 && destVersionOrdinal != Version.CURRENT_ORDINAL) {
out = new VersionedDataOutputStream(out, Version.fromOrdinalOrCurrent((short)destVersionOrdinal));
}
DataSerializer.writeObject(obj, out); // GemStoneAddition
return out_stream.toByteArray();
}
catch(IOException ex) {
// GemStoneAddition - we need the cause to figure out what went wrong
IllegalArgumentException ia = new
IllegalArgumentException("Error serializing message");
ia.initCause(ex);
throw ia;
}
}
static final byte DEST_SET=1;
static final byte SRC_SET=2;
static final byte BUF_SET=4;
// static final byte HDRS_SET=8; // bela July 15 2005: not needed, we always create headers
static final byte IPADDR_DEST=16;
static final byte IPADDR_SRC=32;
static final byte SRC_HOST_NULL=64;
static final byte CACHE_OP = 1; // GemStoneAddition
static final byte HIGH_PRIORITY = 8; // GemStoneAddition
@Override
public void serializeJGMessage(Message msg, DataOutputStream out) throws IOException {
//int begIdx = out.size(); // GemStoneAddition
byte leading=0;
// if(dest_addr != null) {
// leading+=DEST_SET;
// if(dest_addr instanceof IpAddress)
// leading+=IPADDR_DEST;
// }
short serVersion = msg.getDestVersionOrdinal();
if (0 < serVersion && serVersion < Version.CURRENT_ORDINAL) {
out = new VersionedDataOutputStream(out,
Version.fromOrdinalOrCurrent(serVersion));
}
Version.writeOrdinal(out, serVersion, true);
if(msg.getSrc() != null) {
leading+=SRC_SET;
if(msg.getSrc() instanceof IpAddress) {
leading+=IPADDR_SRC;
if(((IpAddress)msg.getSrc()).getIpAddress() == null) {
leading+=SRC_HOST_NULL;
}
}
}
if(msg.getRawBuffer() != null)
leading+=BUF_SET;
// 1. write the leading byte first
out.write(leading);
// 2. dest_addr
// if(dest_addr != null) {
// if(dest_addr instanceof IpAddress)
// dest_addr.writeTo(out);
// else
// Util.writeAddress(dest_addr, out);
// }
// 3. src_addr
if(msg.getSrc() != null) {
if(msg.getSrc() instanceof IpAddress) {
InternalDataSerializer.invokeToData(((IpAddress)msg.getSrc()), out); // GemStoneAddition
}
else {
Util.writeAddress(msg.getSrc(), out);
}
//eidx = out.size();
//if ( (eidx - sidx) > src_addr.size() ) {
// log.error("address serialized to " + (eidx-sidx) + " bytes but reported size = " + src_addr.size(), new Error());
//}
}
// GemStoneAddition - more flags
byte gfFlags = 0;
if (msg.isCacheOperation)
gfFlags += CACHE_OP;
if (msg.isHighPriority)
gfFlags += HIGH_PRIORITY;
out.write(gfFlags);
// 4. buf
if(msg.getRawBuffer() != null) {
out.writeInt(msg.getLength()-msg.getOffset());
out.write(msg.getRawBuffer(), msg.getOffset(), msg.getLength());
}
// 5. headers
short size=(short)msg.getHeaders().size();
out.writeShort(size);
Map.Entry entry;
// if (log.isTraceEnabled()) {
// log.trace("writing " + size + " headers");
// }
//long estSize, startPos, endPos; // GemStoneAddition
for(Iterator it=msg.getHeaders().entrySet().iterator(); it.hasNext();) {
entry=(Map.Entry)it.next();
//estSize = ((String)entry.getKey()).length() + 2;
//estSize = estSize + 5 + ((Header)entry.getValue()).size();
//startPos = out.size();
out.writeUTF((String)entry.getKey());
ByteArrayOutputStream baos = new ByteArrayOutputStream(50);
DataOutputStream hdos;
if (0 < serVersion && serVersion < Version.CURRENT_ORDINAL) {
hdos = new VersionedDataOutputStream(baos,
Version.fromOrdinalOrCurrent(serVersion));
} else {
hdos = new DataOutputStream(baos);
}
msg.writeHeader((Header)entry.getValue(), hdos);
hdos.flush();
byte[] headerBytes = baos.toByteArray();
// if (log.isTraceEnabled()) {
// log.trace("writing header " + entry.getKey() + " length=" + headerBytes.length);
// }
out.writeInt(headerBytes.length);
out.write(headerBytes);
//endPos = out.size();
//if ( (endPos-startPos) > estSize ) {
// log.error("bad estimating job in message header: " + entry.getKey(), new Error());
//}
}
//int endIdx = out.size();
//if ( (endIdx - begIdx) > size() ) {
// log.error("bad job estimating message size: " + size() + " (est), " + (endIdx-begIdx) + " (actual)", new Error());
//}
}
@Override
public void deserializeJGMessage(Message msg, DataInputStream in)
throws IOException, IllegalAccessException, InstantiationException {
int len, leading;
String hdr_name;
Header hdr = null;
// create a versioned stream if a different version
// was used to multicast this message
short sv = Version.readOrdinal(in);
msg.setVersion(sv);
if (0 < msg.getVersion() && msg.getVersion() < Version.CURRENT_ORDINAL) {
try {
in = new VersionedDataInputStream(in, Version.fromOrdinal(msg.getVersion(), false));
} catch (UnsupportedGFXDVersionException e) {
throw new IOException("Unexpected exception during deserialization", e);
}
}
// 1. read the leading byte first
leading=in.readByte();
// 2. dest_addr
// if((leading & DEST_SET) == DEST_SET) {
// if((leading & IPADDR_DEST) == IPADDR_DEST) {
// dest_addr=new IpAddress();
// dest_addr.readFrom(in);
// }
// else {
// dest_addr=Util.readAddress(in);
// }
// }
// 3. src_addr
if((leading & SRC_SET) == SRC_SET) {
if((leading & IPADDR_SRC) == IPADDR_SRC) {
IpAddress src_addr=new IpAddress();
try {
InternalDataSerializer.invokeFromData(((IpAddress)src_addr), in);
} catch (ClassNotFoundException e) {
throw new IOException(e);
} // GemStoneAddition
msg.setSrc(src_addr);
//readFrom(in);
}
else {
msg.setSrc(Util.readAddress(in));
}
}
// GemStoneAddition
byte gfFlags = in.readByte();
if ( (gfFlags & CACHE_OP) != 0 )
msg.isCacheOperation = true;
if ( (gfFlags & HIGH_PRIORITY) != 0 )
msg.isHighPriority = true;
// 4. buf
if((leading & BUF_SET) == BUF_SET) {
len=in.readInt();
try { // GemStoneAddition -- flag this as a problem
msg.setBuffer(new byte[len]);
}
catch (OutOfMemoryError e) {
System.err.println(
"JGroups#Message: unable to allocate buffer of size " + len
+ "; gfFlags = " + gfFlags + "; src_addr = " + msg.getSrc());
throw e;
}
in.readFully(msg.getRawBuffer(), 0, len); // GemStoneAddition - use readFully
//in.read(buf, 0, len);
}
// 5. headers
len=in.readShort();
if (msg.getHeaders() == null) {
msg.setHeaders(msg.createHeaders(len));
}
for(int i=0; i < len; i++) {
hdr_name=in.readUTF();
int hlen = in.readInt();
// if (log.isTraceEnabled()) {
// log.trace("reading header " + hdr_name + " of length " + hlen);
// }
byte[] headerBytes = new byte[hlen];
in.readFully(headerBytes);
ByteArrayInputStream bais = new ByteArrayInputStream(headerBytes);
DataInputStream dis;
if (0 < msg.getVersion() && msg.getVersion() < Version.CURRENT_ORDINAL) {
try {
dis = new VersionedDataInputStream(bais, Version.fromOrdinal(msg.getVersion(), false));
} catch (UnsupportedGFXDVersionException e) {
throw new IOException("Unexpected exception during deserialization", e);
}
} else {
dis = new DataInputStream(bais);
}
try {
hdr=msg.readHeader(dis);
// if (log.isTraceEnabled()) {
// log.trace("read " + hdr.toString());
// }
msg.getHeaders().put(hdr_name, hdr);
} catch (Exception e) {
GemFireTracer log = GemFireTracer.getLog(getClass());
if (log.isErrorEnabled()) {
log.error("Failed to deserialize a header " + hdr_name + " of length " + hlen, e);
}
}
}
}
@Override
public ObjectOutput getObjectOutput(DataOutputStream out) throws IOException {
ObjectOutput oos=new ObjectOutputStream(out);
if (out instanceof VersionedDataOutputStream) {
Version v = ((VersionedDataOutputStream)out).getVersion();
if (v != null && v != Version.CURRENT) {
oos = new VersionedObjectOutput(oos, v);
}
}
return oos;
}
@Override
public ObjectInput getObjectInput(DataInputStream in) throws IOException {
ObjectInput ois=new ObjectInputStream(in);
if (in instanceof VersionedDataInputStream) {
ois = new VersionedObjectInput(ois, ((VersionedDataInputStream)in).getVersion());
}
return ois;
}
@Override
public int getGossipVersionForOrdinal(short serverOrdinal) {
return TcpServer.getGossipVersionForOrdinal(serverOrdinal);
}
@Override
public boolean isVersionForStreamAtLeast(DataOutput stream, short version) {
return InternalDataSerializer.getVersionForDataStream(stream).ordinal() >= version;
}
@Override
public boolean isVersionForStreamAtLeast(DataInput stream, short version) {
return InternalDataSerializer.getVersionForDataStream(stream).ordinal() >= version;
}
@Override
public DataOutputStream getVersionedDataOutputStream(DataOutputStream dos, short version) throws IOException {
try {
return new VersionedDataOutputStream(dos, Version.fromOrdinal(version, false));
} catch (UnsupportedGFXDVersionException e) {
throw new IOException("Unexpected exception during serialization", e);
}
}
@Override
public DataInputStream getVersionedDataInputStream(DataInputStream instream,
short version) throws IOException {
try {
Version mcastVersion = Version.fromOrdinal(version, false);
return new VersionedDataInputStream(instream, mcastVersion);
} catch (UnsupportedGFXDVersionException e) {
throw new IOException("Unexpected exception during deserialization", e);
}
}
@Override
public byte[] readByteArray(DataInput in) throws IOException {
return DataSerializer.readByteArray(in);
}
@Override
public void writeByteArray(byte[] array, DataOutput out) throws IOException {
DataSerializer.writeByteArray(array, out);
}
@Override
public void writeProperties(Properties props, DataOutput oos)
throws IOException {
DataSerializer.writeProperties(props, oos);
}
@Override
public Properties readProperties(DataInput in) throws IOException, ClassNotFoundException {
return DataSerializer.readProperties(in);
}
@Override
public void checkDisableDNS() {
if (!SocketCreator.FORCE_DNS_USE) {
IpAddress.resolve_dns = false; // do not resolve host names since DNS lookup can hang if the NIC fails
SocketCreator.resolve_dns = false;
}
}
@Override
public void writeString(String str, DataOutput out) throws IOException {
DataSerializer.writeString(str, out);
}
@Override
public String readString(DataInput in) throws IOException {
return DataSerializer.readString(in);
}
@Override
public void writeStringArray(String[] roles, DataOutput dao) throws IOException {
DataSerializer.writeStringArray(roles, dao);
}
@Override
public String[] readStringArray(DataInput in) throws IOException {
return DataSerializer.readStringArray(in);
}
@Override
public String getHostName(InetAddress ip_addr) {
return SocketCreator.getHostName(ip_addr);
}
@Override
public RuntimeException getGemFireConfigException(String string) {
return new GemFireConfigException(string);
}
@Override
public RuntimeException getAuthenticationFailedException(String failReason) {
return new AuthenticationFailedException(failReason);
}
@Override
public SockCreator getSockCreator() {
return SocketCreator.getDefaultInstance();
}
@Override
public void setDefaultGemFireAttributes(IpAddress addr) {
MemberAttributes attr = com.gemstone.gemfire.distributed.internal.membership.MemberAttributes.DEFAULT;
insertGemFireAttributes(addr, attr);
}
@Override
public RuntimeException getDisconnectException(String localizedString) {
return new DistributedSystemDisconnectedException(localizedString);
}
@Override
public Object getForcedDisconnectException(String localizedString) {
return new ForcedDisconnectException(localizedString);
}
@Override
public RuntimeException getSystemConnectException(String localizedString) {
return new SystemConnectException(localizedString);
}
@Override
public InetAddress getLocalHost() throws UnknownHostException {
return SocketCreator.getLocalHost();
}
@Override
public void setGemFireAttributes(IpAddress addr, Object obj) {
insertGemFireAttributes(addr, obj);
}
@Override
public String getVmKindString(int vmKind) {
String vmStr = "";
switch (vmKind) {
case DistributionManager.NORMAL_DM_TYPE:
//vmStr = ":local"; // let this be silent
break;
case DistributionManager.LOCATOR_DM_TYPE:
vmStr = ":locator";
break;
case DistributionManager.ADMIN_ONLY_DM_TYPE:
vmStr = ":admin";
break;
case DistributionManager.LONER_DM_TYPE:
vmStr = ":loner";
break;
default:
//vmStr = ":"; // let this be silent for JGroups addresses
break;
}
return vmStr;
}
}