public static List<PingData> getDiscoveryResponsesFor(String cluster_name) { if(cluster_name == null) return null; Map<Address,SHARED_LOOPBACK> mbrs=routing_table.get(new AsciiString(cluster_name)); List<PingData> rsps=new ArrayList<>(mbrs != null? mbrs.size() : 0); if(mbrs != null) { for(Map.Entry<Address,SHARED_LOOPBACK> entry: mbrs.entrySet()) { Address addr=entry.getKey(); SHARED_LOOPBACK slp=entry.getValue(); PingData data=new PingData(addr, slp.isServer(), NameCache.get(addr), null).coord(slp.isCoord()); rsps.add(data); } } return rsps; }
@ManagedOperation(description="Reads data from local caches and dumps them to a file") public void dumpCache(String output_filename) throws Exception { Map<Address,PhysicalAddress> cache_contents= (Map<Address,PhysicalAddress>)down_prot.down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS, false)); List<PingData> list=new ArrayList<>(cache_contents.size()); for(Map.Entry<Address,PhysicalAddress> entry: cache_contents.entrySet()) { Address addr=entry.getKey(); PhysicalAddress phys_addr=entry.getValue(); PingData data=new PingData(addr, true, NameCache.get(addr), phys_addr).coord(addr.equals(local_addr)); list.add(data); } OutputStream out=new FileOutputStream(output_filename); write(list, out); }
protected void writeAll(Address[] excluded_mbrs) { Map<Address,PhysicalAddress> cache_contents= (Map<Address,PhysicalAddress>)down_prot.down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS, false)); if(excluded_mbrs != null) for(Address excluded_mbr : excluded_mbrs) cache_contents.remove(excluded_mbr); List<PingData> list=new ArrayList<>(cache_contents.size()); for(Map.Entry<Address,PhysicalAddress> entry: cache_contents.entrySet()) { Address addr=entry.getKey(); if(update_store_on_view_change && (view != null && !view.containsMember(addr))) continue; PhysicalAddress phys_addr=entry.getValue(); PingData data=new PingData(addr, true, NameCache.get(addr), phys_addr).coord(addr.equals(local_addr)); list.add(data); } write(list, cluster_name); if(log.isTraceEnabled()) log.trace("%s: wrote to backend store: %s", local_addr, list.stream().map(PingData::getAddress).collect(Collectors.toList())); }
protected void readFrom(DataInput in, boolean read_type) throws Exception { if(read_type) type=GossipType.values()[in.readByte()]; group=Bits.readString(in); addr=Util.readAddress(in); sender=Util.readAddress(in); if(type != GossipType.MESSAGE) { logical_name=Bits.readString(in); short len=in.readShort(); if(len > 0) { ping_data=new ArrayList<>(len); for(int i=0; i < len; i++) { PingData data=new PingData(); data.readFrom(in); ping_data.add(data); } } physical_addr=(PhysicalAddress)Util.readAddress(in); } length=in.readInt(); if(length > 0) { buffer=new byte[length]; in.readFully(buffer, offset=0, length); } }
@Override public void members(List<PingData> mbrs) { PhysicalAddress own_physical_addr=(PhysicalAddress)down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); PingData data=new PingData(local_addr, false, org.jgroups.util.NameCache.get(local_addr), own_physical_addr); PingHeader hdr=new PingHeader(PingHeader.GET_MBRS_REQ).clusterName(cluster_name); Set<PhysicalAddress> physical_addrs=mbrs.stream().filter(ping_data -> ping_data != null && ping_data.getPhysicalAddr() != null) .map(PingData::getPhysicalAddr).collect(Collectors.toSet()); for(PhysicalAddress physical_addr: physical_addrs) { if(physical_addr != null && own_physical_addr.equals(physical_addr)) // no need to send the request to myself continue; // the message needs to be DONT_BUNDLE, see explanation above final Message msg=new Message(physical_addr).setFlag(Message.Flag.INTERNAL, Message.Flag.DONT_BUNDLE, Message.Flag.OOB) .putHeader(this.id, hdr).setBuffer(marshal(data)); log.trace("%s: sending discovery request to %s", local_addr, msg.getDest()); down_prot.down(msg); } }
data=new PingData(local_addr, false, NameCache.get(local_addr), physical_addr); if(members != null && members.size() <= max_members_in_discovery_request) data.mbrs(members);
retval.add(new PingData(uuid, true, name_str, phys_addr).coord(is_coordinator));
protected void handleGetMembersRequest(Address sender, DataInput in) { GossipData req=readRequest(in, GossipType.GET_MBRS); if(req == null) return; GossipData rsp=new GossipData(GossipType.GET_MBRS_RSP, req.getGroup(), null); Map<Address,Entry> members=address_mappings.get(req.getGroup()); if(members != null) { for(Map.Entry<Address,Entry> entry : members.entrySet()) { Address logical_addr=entry.getKey(); PhysicalAddress phys_addr=entry.getValue().phys_addr; String logical_name=entry.getValue().logical_name; PingData data=new PingData(logical_addr, true, logical_name, phys_addr); rsp.addPingData(data); } } ByteArrayDataOutputStream out=new ByteArrayDataOutputStream(rsp.serializedSize()); try { rsp.writeTo(out); server.send(sender, out.buffer(), 0, out.position()); } catch(Exception ex) { log.error("failed sending %d to %s: %s", GossipType.GET_MBRS_RSP, sender, ex); } }
@SuppressWarnings("unchecked") @Override public Object up(Event evt) { switch (evt.getType()) { case Event.FIND_MBRS: List<Address> missing = (List<Address>) evt.getArg(); Responses responses = new Responses(false); for (Address laddr : missing) { try { if (laddr instanceof JGAddress) { PingData pd = new PingData(laddr, true, laddr.toString(), newIpAddress(laddr)); responses.addResponse(pd, false); updateUDPCache(pd); } } catch (RuntimeException e) { logger.warn("Unable to create PingData response", e); throw e; } } return responses; } return up_prot.up(evt); }
/** * Creates a byte[] representation of the PingData, but DISCARDING the view it contains. * @param data the PingData instance to serialize. * @return */ protected byte[] serializeWithoutView(PingData data) { final PingData clone = new PingData(data.getAddress(), data.isServer(), data.getLogicalName(), data.getPhysicalAddr()).coord(data.isCoord()); try { return Util.streamableToByteBuffer(clone); } catch(Exception e) { log.error(Util.getMessage("ErrorSerializingPingData"), e); return null; } }
physical_addr = (PhysicalAddress) down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); data = new PingData(local_addr, false, NameCache.get(local_addr), physical_addr); if (members != null && members.size() <= max_members_in_discovery_request) data.mbrs(members);
protected void sendDiscoveryRequest(String cluster_name, List<Address> members_to_find, boolean initial_discovery) throws Exception { PingData data=null; if(!use_ip_addrs || !initial_discovery) { PhysicalAddress physical_addr=(PhysicalAddress)down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); // https://issues.jboss.org/browse/JGRP-1670 data=new PingData(local_addr, false, NameCache.get(local_addr), physical_addr); if(members_to_find != null && members_to_find.size() <= max_members_in_discovery_request) data.mbrs(members_to_find); } // message needs to have DONT_BUNDLE flag: if A sends message M to B, and we need to fetch B's physical // address, then the bundler thread blocks until the discovery request has returned. However, we cannot send // the discovery *request* until the bundler thread has returned from sending M PingHeader hdr=new PingHeader(PingHeader.GET_MBRS_REQ).clusterName(cluster_name).initialDiscovery(initial_discovery); Message msg=new Message(null).putHeader(getId(),hdr) .setFlag(Message.Flag.INTERNAL,Message.Flag.DONT_BUNDLE,Message.Flag.OOB) .setTransientFlag(Message.TransientFlag.DONT_LOOPBACK); if(data != null) msg.setBuffer(marshal(data)); sendMcastDiscoveryRequest(msg); }
if(responses.isEmpty()) { PhysicalAddress physical_addr=(PhysicalAddress)down(new Event(Event.GET_PHYSICAL_ADDRESS,local_addr)); PingData coord_data=new PingData(local_addr, true, NameCache.get(local_addr), physical_addr).coord(is_coord); write(Collections.singletonList(coord_data), cluster_name); return;
protected void sendDiscoveryResponse(Address logical_addr, PhysicalAddress physical_addr, String logical_name, final Address sender, boolean coord) { final PingData data=new PingData(logical_addr, is_server, logical_name, physical_addr).coord(coord); final Message rsp_msg=new Message(sender).setFlag(Message.Flag.INTERNAL, Message.Flag.OOB, Message.Flag.DONT_BUNDLE) .putHeader(this.id, new PingHeader(PingHeader.GET_MBRS_RSP)).setBuffer(marshal(data)); if(stagger_timeout > 0) { int view_size=view != null? view.size() : 10; int rank=Util.getRank(view, local_addr); // returns 0 if view or local_addr are null long sleep_time=rank == 0? Util.random(stagger_timeout) : stagger_timeout * rank / view_size - (stagger_timeout / view_size); timer.schedule(() -> { log.trace("%s: received GET_MBRS_REQ from %s, sending staggered response %s", local_addr, sender, data); down_prot.down(rsp_msg); }, sleep_time, TimeUnit.MILLISECONDS, sends_can_block); return; } log.trace("%s: received GET_MBRS_REQ from %s, sending response %s", local_addr, sender, data); down_prot.down(rsp_msg); }
protected synchronized PingData readPingData(String path) { PingData retval = null; DataInputStream in = null; try { byte[] bytes = curator.getData().forPath(path); in = new DataInputStream(new ByteArrayInputStream(bytes)); PingData tmp = new PingData(); tmp.readFrom(in); return tmp; } catch (Exception e) { log.debug(String.format("Failed to read ZooKeeper znode: %s", path), e); } finally { Util.close(in); } return retval; }
@ManagedOperation(description="Reads data from local caches and dumps them to a file") public void dumpCache(String output_filename) throws Exception { Map<Address,PhysicalAddress> cache_contents= (Map<Address,PhysicalAddress>)down_prot.down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS, false)); List<PingData> list=new ArrayList<>(cache_contents.size()); for(Map.Entry<Address,PhysicalAddress> entry: cache_contents.entrySet()) { Address addr=entry.getKey(); PhysicalAddress phys_addr=entry.getValue(); PingData data=new PingData(addr, true, NameCache.get(addr), phys_addr).coord(addr.equals(local_addr)); list.add(data); } OutputStream out=new FileOutputStream(output_filename); write(list, out); }
public static List<PingData> getDiscoveryResponsesFor(String cluster_name) { if(cluster_name == null) return null; Map<Address,SHARED_LOOPBACK> mbrs=routing_table.get(new AsciiString(cluster_name)); List<PingData> rsps=new ArrayList<>(mbrs != null? mbrs.size() : 0); if(mbrs != null) { for(Map.Entry<Address,SHARED_LOOPBACK> entry: mbrs.entrySet()) { Address addr=entry.getKey(); SHARED_LOOPBACK slp=entry.getValue(); PingData data=new PingData(addr, slp.isServer(), NameCache.get(addr), null).coord(slp.isCoord()); rsps.add(data); } } return rsps; }
@Override public void members(List<PingData> mbrs) { PhysicalAddress own_physical_addr=(PhysicalAddress)down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); PingData data=new PingData(local_addr, false, org.jgroups.util.NameCache.get(local_addr), own_physical_addr); PingHeader hdr=new PingHeader(PingHeader.GET_MBRS_REQ).clusterName(cluster_name); Set<PhysicalAddress> physical_addrs=mbrs.stream().filter(ping_data -> ping_data != null && ping_data.getPhysicalAddr() != null) .map(PingData::getPhysicalAddr).collect(Collectors.toSet()); for(PhysicalAddress physical_addr: physical_addrs) { if(physical_addr != null && own_physical_addr.equals(physical_addr)) // no need to send the request to myself continue; // the message needs to be DONT_BUNDLE, see explanation above final Message msg=new Message(physical_addr).setFlag(Message.Flag.INTERNAL, Message.Flag.DONT_BUNDLE, Message.Flag.OOB) .putHeader(this.id, hdr).setBuffer(marshal(data)); log.trace("%s: sending discovery request to %s", local_addr, msg.getDest()); down_prot.down(msg); } }
/** * Creates a byte[] representation of the PingData, but DISCARDING the view it contains. * @param data the PingData instance to serialize. * @return */ protected byte[] serializeWithoutView(PingData data) { final PingData clone = new PingData(data.getAddress(), data.isServer(), data.getLogicalName(), data.getPhysicalAddr()).coord(data.isCoord()); try { return Util.streamableToByteBuffer(clone); } catch(Exception e) { log.error(Util.getMessage("ErrorSerializingPingData"), e); return null; } }
private void addPingRsp(Responses rsps, TEST_PING discovery) { // Rather than relying on transport (PING) or your own multicast channel // (MPING), talk to other discovery instances directly via Java method // calls and discover the other nodes in the cluster. // Add mapping of remote's address -> physical addr to the local cache mapAddrWithPhysicalAddr(this, discovery); // Add mapping of local's address -> physical addr to the remote cache mapAddrWithPhysicalAddr(discovery, this); Address localAddr = discovery.getLocalAddr(); PhysicalAddress physicalAddr = (PhysicalAddress) discovery.down(new Event(Event.GET_PHYSICAL_ADDRESS, localAddr)); String logicalName = NameCache.get(localAddr); PingData pingRsp = new PingData(localAddr, discovery.isServer(), logicalName, physicalAddr).coord(discovery .is_coord); if (log.isTraceEnabled()) log.trace(String.format("Returning ping rsp: %s", pingRsp)); if (rsps != null) { rsps.addResponse(pingRsp, true); addResponse(pingRsp, true); } }