use of org.apache.geode.distributed.internal.DistributionMessage in project geode by apache.
the class JGroupsMessenger method send.
private Set<InternalDistributedMember> send(DistributionMessage msg, boolean reliably) {
// perform the same jgroups messaging as in 8.2's GMSMembershipManager.send() method
// BUT: when marshalling messages we need to include the version of the product and
// localAddress at the beginning of the message. These should be used in the receiver
// code to create a versioned input stream, read the sender address, then read the message
// and set its sender address
DMStats theStats = services.getStatistics();
NetView oldView = this.view;
if (!myChannel.isConnected()) {
logger.info("JGroupsMessenger channel is closed - messaging is not possible");
throw new DistributedSystemDisconnectedException("Distributed System is shutting down");
}
filterOutgoingMessage(msg);
// the message's processor if necessary
if ((msg instanceof DirectReplyMessage) && msg.isDirectAck() && msg.getProcessorId() <= 0) {
((DirectReplyMessage) msg).registerProcessor();
}
InternalDistributedMember[] destinations = msg.getRecipients();
boolean allDestinations = msg.forAll();
boolean useMcast = false;
if (services.getConfig().getTransport().isMcastEnabled()) {
if (msg.getMulticast() || allDestinations) {
useMcast = services.getManager().isMulticastAllowed();
}
}
if (logger.isDebugEnabled() && reliably) {
String recips = useMcast ? "multicast" : Arrays.toString(msg.getRecipients());
logger.debug("sending via JGroups: [{}] recipients: {}", msg, recips);
}
JGAddress local = this.jgAddress;
if (useMcast) {
long startSer = theStats.startMsgSerialization();
Message jmsg = createJGMessage(msg, local, Version.CURRENT_ORDINAL);
theStats.endMsgSerialization(startSer);
Exception problem;
try {
jmsg.setTransientFlag(TransientFlag.DONT_LOOPBACK);
if (!reliably) {
jmsg.setFlag(Message.Flag.NO_RELIABILITY);
}
theStats.incSentBytes(jmsg.getLength());
logger.trace("Sending JGroups message: {}", jmsg);
myChannel.send(jmsg);
} catch (Exception e) {
logger.debug("caught unexpected exception", e);
Throwable cause = e.getCause();
if (cause instanceof ForcedDisconnectException) {
problem = (Exception) cause;
} else {
problem = e;
}
if (services.getShutdownCause() != null) {
Throwable shutdownCause = services.getShutdownCause();
// problem.
if (shutdownCause instanceof ForcedDisconnectException) {
problem = (Exception) shutdownCause;
} else {
Throwable ne = problem;
while (ne.getCause() != null) {
ne = ne.getCause();
}
ne.initCause(services.getShutdownCause());
}
}
final String channelClosed = LocalizedStrings.GroupMembershipService_CHANNEL_CLOSED.toLocalizedString();
// services.getManager().membershipFailure(channelClosed, problem);
throw new DistributedSystemDisconnectedException(channelClosed, problem);
}
} else // useMcast
{
// ! useMcast
int len = destinations.length;
// explicit list of members
List<GMSMember> calculatedMembers;
// == calculatedMembers.len
int calculatedLen;
if (len == 1 && destinations[0] == DistributionMessage.ALL_RECIPIENTS) {
// send to all
// Grab a copy of the current membership
NetView v = services.getJoinLeave().getView();
// Construct the list
calculatedLen = v.size();
calculatedMembers = new LinkedList<GMSMember>();
for (int i = 0; i < calculatedLen; i++) {
InternalDistributedMember m = (InternalDistributedMember) v.get(i);
calculatedMembers.add((GMSMember) m.getNetMember());
}
} else // send to all
{
// send to explicit list
calculatedLen = len;
calculatedMembers = new LinkedList<GMSMember>();
for (int i = 0; i < calculatedLen; i++) {
calculatedMembers.add((GMSMember) destinations[i].getNetMember());
}
}
// send to explicit list
Int2ObjectOpenHashMap<Message> messages = new Int2ObjectOpenHashMap<>();
long startSer = theStats.startMsgSerialization();
boolean firstMessage = true;
for (GMSMember mbr : calculatedMembers) {
short version = mbr.getVersionOrdinal();
if (!messages.containsKey(version)) {
Message jmsg = createJGMessage(msg, local, version);
messages.put(version, jmsg);
if (firstMessage) {
theStats.incSentBytes(jmsg.getLength());
firstMessage = false;
}
}
}
theStats.endMsgSerialization(startSer);
Collections.shuffle(calculatedMembers);
int i = 0;
for (GMSMember mbr : calculatedMembers) {
JGAddress to = new JGAddress(mbr);
short version = mbr.getVersionOrdinal();
Message jmsg = messages.get(version);
Exception problem = null;
try {
Message tmp = (i < (calculatedLen - 1)) ? jmsg.copy(true) : jmsg;
if (!reliably) {
jmsg.setFlag(Message.Flag.NO_RELIABILITY);
}
tmp.setDest(to);
tmp.setSrc(this.jgAddress);
logger.trace("Unicasting to {}", to);
myChannel.send(tmp);
} catch (Exception e) {
problem = e;
}
if (problem != null) {
Throwable cause = services.getShutdownCause();
if (cause != null) {
// problem.
if (cause instanceof ForcedDisconnectException) {
problem = (Exception) cause;
} else {
Throwable ne = problem;
while (ne.getCause() != null) {
ne = ne.getCause();
}
ne.initCause(cause);
}
}
final String channelClosed = LocalizedStrings.GroupMembershipService_CHANNEL_CLOSED.toLocalizedString();
// services.getManager().membershipFailure(channelClosed, problem);
throw new DistributedSystemDisconnectedException(channelClosed, problem);
}
}
// send individually
}
// (i.e., left the view), we signal it here.
if (msg.forAll()) {
return Collections.emptySet();
}
Set<InternalDistributedMember> result = new HashSet<>();
NetView newView = this.view;
if (newView != null && newView != oldView) {
for (InternalDistributedMember d : destinations) {
if (!newView.contains(d)) {
logger.debug("messenger: member has left the view: {} view is now {}", d, newView);
result.add(d);
}
}
}
return result;
}
use of org.apache.geode.distributed.internal.DistributionMessage in project geode by apache.
the class JGroupsMessenger method readEncryptedMessage.
@SuppressWarnings("resource")
DistributionMessage readEncryptedMessage(DataInputStream dis, short ordinal, GMSEncrypt encryptLocal) throws Exception {
int dfsid = InternalDataSerializer.readDSFIDHeader(dis);
int requestId = dis.readInt();
long start = services.getStatistics().startUDPMsgDecryption();
try {
logger.debug("readEncryptedMessage Reading Request id " + dfsid + " and requestid is " + requestId + " myid " + this.localAddress);
InternalDistributedMember pkMbr = null;
boolean readPK = false;
switch(dfsid) {
case FIND_COORDINATOR_REQ:
case JOIN_REQUEST:
readPK = true;
break;
case FIND_COORDINATOR_RESP:
case JOIN_RESPONSE:
// this will have requestId to know the PK
pkMbr = getRequestedMember(requestId);
break;
}
byte[] data;
byte[] pk = null;
if (readPK) {
// need to read PK
pk = InternalDataSerializer.readByteArray(dis);
// encrypt.setPublicKey(publickey, mbr);
data = InternalDataSerializer.readByteArray(dis);
// using prefixed pk from sender
data = encryptLocal.decryptData(data, pk);
} else {
data = InternalDataSerializer.readByteArray(dis);
// from cluster key
if (pkMbr != null) {
// using member public key
data = encryptLocal.decryptData(data, pkMbr);
} else {
// from cluster key
data = encryptLocal.decryptData(data);
}
}
{
DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
if (ordinal < Version.CURRENT_ORDINAL) {
in = new VersionedDataInputStream(in, Version.fromOrdinalNoThrow(ordinal, true));
}
DistributionMessage result = deserializeMessage(in, ordinal);
if (pk != null) {
logger.info("Setting public key for " + result.getSender() + " len " + pk.length);
setPublicKey(pk, result.getSender());
}
return result;
}
} catch (Exception e) {
throw new Exception("Message id is " + dfsid, e);
} finally {
services.getStatistics().endUDPMsgDecryption(start);
}
}
use of org.apache.geode.distributed.internal.DistributionMessage in project geode by apache.
the class JGroupsMessenger method deserializeMessage.
DistributionMessage deserializeMessage(DataInputStream in, short ordinal) throws ClassNotFoundException, IOException {
GMSMember m = new GMSMember();
m.readEssentialData(in);
DistributionMessage result = (DistributionMessage) DataSerializer.readObject(in);
setSender(result, m, ordinal);
return result;
}
use of org.apache.geode.distributed.internal.DistributionMessage in project geode by apache.
the class GMSJoinLeave method installView.
public void installView(NetView newView) {
synchronized (viewInstallationLock) {
if (currentView != null && currentView.getViewId() >= newView.getViewId()) {
// old view - ignore it
return;
}
logger.info("received new view: {}\nold view is: {}", newView, currentView);
if (currentView == null && !this.isJoined) {
boolean found = false;
for (InternalDistributedMember mbr : newView.getMembers()) {
if (this.localAddress.equals(mbr)) {
found = true;
this.birthViewId = mbr.getVmViewId();
this.localAddress.setVmViewId(this.birthViewId);
GMSMember me = (GMSMember) this.localAddress.getNetMember();
me.setBirthViewId(birthViewId);
break;
}
}
if (!found) {
logger.info("rejecting view (not yet joined)");
return;
}
}
if (isJoined && isNetworkPartition(newView, true)) {
if (quorumRequired) {
Set<InternalDistributedMember> crashes = newView.getActualCrashedMembers(currentView);
forceDisconnect(LocalizedStrings.Network_partition_detected.toLocalizedString(crashes.size(), crashes));
return;
}
}
previousView = currentView;
currentView = newView;
preparedView = null;
lastConflictingView = null;
services.installView(newView);
if (!isJoined) {
logger.debug("notifying join thread");
isJoined = true;
synchronized (joinResponse) {
joinResponse.notifyAll();
}
}
if (!newView.getCreator().equals(this.localAddress)) {
if (newView.shouldBeCoordinator(this.localAddress)) {
becomeCoordinator();
} else if (this.isCoordinator) {
// stop being coordinator
stopCoordinatorServices();
this.isCoordinator = false;
}
}
if (!this.isCoordinator) {
// resend these
synchronized (viewRequests) {
for (Iterator<DistributionMessage> it = viewRequests.iterator(); it.hasNext(); ) {
DistributionMessage m = it.next();
if (m instanceof JoinRequestMessage) {
if (currentView.contains(((JoinRequestMessage) m).getMemberID())) {
it.remove();
}
} else if (m instanceof LeaveRequestMessage) {
if (!currentView.contains(((LeaveRequestMessage) m).getMemberID())) {
it.remove();
}
} else if (m instanceof RemoveMemberMessage) {
if (!currentView.contains(((RemoveMemberMessage) m).getMemberID())) {
it.remove();
}
}
}
}
}
}
synchronized (removedMembers) {
removeMembersFromCollectionIfNotInView(removedMembers, currentView);
}
synchronized (leftMembers) {
removeMembersFromCollectionIfNotInView(leftMembers, currentView);
}
}
use of org.apache.geode.distributed.internal.DistributionMessage in project geode by apache.
the class StreamingOperation method getDataFromAll.
/**
* Returns normally if succeeded to get data, otherwise throws an exception
*
* @throws InterruptedException TODO-javadocs
*/
public void getDataFromAll(Set recipients) throws org.apache.geode.cache.TimeoutException, InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (recipients.isEmpty())
return;
StreamingProcessor processor = new StreamingProcessor(this.sys, recipients);
DistributionMessage m = createRequestMessage(recipients, processor);
this.sys.getDistributionManager().putOutgoing(m);
// while() loop removed for bug 36983 - you can't loop on waitForReplies()
try {
// should we allow this to timeout?
processor.waitForRepliesUninterruptibly();
} catch (InternalGemFireException ex) {
Throwable cause = ex.getCause();
if (cause instanceof org.apache.geode.cache.TimeoutException) {
throw (org.apache.geode.cache.TimeoutException) cause;
}
throw ex;
} catch (ReplyException e) {
e.handleAsUnexpected();
// throws exception
}
}
Aggregations