
org.jgroups.protocols.relay.RelayHeader Maven / Gradle / Ivy
package org.jgroups.protocols.relay;
import org.jgroups.Address;
import org.jgroups.Global;
import org.jgroups.Header;
import org.jgroups.util.Bits;
import org.jgroups.util.Util;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
/**
* Header for {@link RELAY2} and {@link RELAY3}
* @author Bela Ban
* @since 5.2.15
*/
public class RelayHeader extends Header {
public static final byte DATA = 1;
public static final byte SITE_UNREACHABLE = 2; // final_dest is a SiteMaster
public static final byte SITES_UP = 4;
public static final byte SITES_DOWN = 5;
public static final byte TOPO_REQ = 6;
public static final byte TOPO_RSP = 7; // MemberInfo is the payload of the response message
protected byte type;
protected Address final_dest;
protected Address original_sender;
protected Set sites; // used with SITES_UP/SITES_DOWN/TOPO_RSP
protected Set visited_sites; // used to record sites to which this msg was already sent
// (https://issues.redhat.com/browse/JGRP-1519)
public RelayHeader() {
}
public RelayHeader(byte type) {
this.type=type;
}
public RelayHeader(byte type, Address final_dest, Address original_sender) {
this(type);
this.final_dest=final_dest;
this.original_sender=original_sender;
}
public short getMagicId() {return 80;}
public Supplier extends Header> create() {return RelayHeader::new;}
public byte getType() {return type;}
public Address getFinalDest() {return final_dest;}
public RelayHeader setFinalDestination(Address d) {final_dest=d; return this;}
public Address getOriginalSender() {return original_sender;}
public RelayHeader setOriginalSender(Address s) {original_sender=s; return this;}
public Set getSites() {return sites != null? new HashSet<>(sites) : null;}
public boolean hasSites() {return sites != null && !sites.isEmpty();}
public RelayHeader addToSites(Collection s) {
if(s != null) {
if(this.sites == null)
this.sites=new HashSet<>(s.size());
this.sites.addAll(s);
}
assertNonNullSites();
return this;
}
public RelayHeader addToSites(String ... s) {
if(s != null && s.length > 0) {
if(this.sites == null)
this.sites=new HashSet<>();
this.sites.addAll(Arrays.asList(s));
}
assertNonNullSites();
return this;
}
public RelayHeader addToVisitedSites(String s) {
if(visited_sites == null)
visited_sites=new HashSet<>();
visited_sites.add(s);
return this;
}
public RelayHeader addToVisitedSites(Collection list) {
if(list == null || list.isEmpty())
return this;
for(String s: list)
addToVisitedSites(s);
return this;
}
public boolean hasVisitedSites() {return visited_sites != null && !visited_sites.isEmpty();}
public Set getVisitedSites() {return visited_sites;}
public RelayHeader copy() {
RelayHeader hdr=new RelayHeader(type, final_dest, original_sender)
.addToSites(this.sites)
.addToVisitedSites(visited_sites);
assertNonNullSites();
hdr.assertNonNullSites();
return hdr;
}
@Override
public int serializedSize() {
assertNonNullSites();
return Global.BYTE_SIZE + Util.size(final_dest) + Util.size(original_sender) +
sizeOf(sites) + sizeOf(visited_sites);
}
@Override
public void writeTo(DataOutput out) throws IOException {
out.writeByte(type);
Util.writeAddress(final_dest, out);
Util.writeAddress(original_sender, out);
out.writeInt(sites == null? 0 : sites.size());
if(sites != null) {
for(String s: sites)
Bits.writeString(s, out);
}
out.writeInt(visited_sites == null? 0 : visited_sites.size());
if(visited_sites != null) {
for(String s: visited_sites)
Bits.writeString(s, out);
}
assertNonNullSites();
}
@Override
public void readFrom(DataInput in) throws IOException, ClassNotFoundException {
type=in.readByte();
final_dest=Util.readAddress(in);
original_sender=Util.readAddress(in);
int num_elements=in.readInt();
if(num_elements > 0) {
sites=new HashSet<>(num_elements);
for(int i=0; i < num_elements; i++)
sites.add(Bits.readString(in));
}
num_elements=in.readInt();
if(num_elements > 0) {
visited_sites=new HashSet<>(num_elements);
for(int i=0; i < num_elements; i++)
visited_sites.add(Bits.readString(in));
}
assertNonNullSites();
}
public String toString() {
return String.format("%s [final dest=%s, original sender=%s%s%s]",
typeToString(type), final_dest, original_sender,
sites == null || sites.isEmpty()? "" : String.format(", sites=%s", sites),
visited_sites == null || visited_sites.isEmpty()? "" :
String.format(", visited=%s", visited_sites));
}
protected static String typeToString(byte type) {
switch(type) {
case DATA: return "DATA";
case SITE_UNREACHABLE: return "SITE_UNREACHABLE";
case SITES_UP: return "SITES_UP";
case SITES_DOWN: return "SITES_DOWN";
case TOPO_REQ: return "TOPO_REQ";
case TOPO_RSP: return "TOPO_RSP";
default: return "";
}
}
protected static int sizeOf(Collection list) {
int retval=Global.INT_SIZE; // number of elements
if(list != null) {
for(String s: list)
retval+=Bits.sizeUTF(s) + 1; // presence bytes
}
return retval;
}
protected void assertNonNullSites() {
if(type == SITES_UP || type == SITES_DOWN) {
if(sites == null)
throw new IllegalStateException(String.format("sites cannot be null with type %s\n", type));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy