/** * Returns the logical name of a given member. The lookup is from the local cache of logical * address / logical name mappings and no remote communication is performed. * * @param member * @return The logical name for <code>member</code> */ public String getName(Address member) {return member != null? NameCache.get(member) : null;}
protected static String addressToFilename(Address mbr) { String logical_name=NameCache.get(mbr); String name=(addressAsString(mbr) + (logical_name != null? "." + logical_name + SUFFIX : SUFFIX)); return regexp.matcher(name).replaceAll("-"); }
public String toString() { String val=NameCache.get(this); return val != null? val : toStringLong(); }
public String toString() { String logical_name=NameCache.get(this); return logical_name != null? logical_name : super.toString(); }
public String toString(boolean detailed) { String logical_name=NameCache.get(this); if(logical_name != null) return detailed? String.format("%s (%s)", logical_name, super.toString()) : logical_name; return super.toString(); }
@Override public Node createNode(Address address) { return this.members.computeIfAbsent(address, key -> { IpAddress ipAddress = (IpAddress) this.dispatcher.getChannel().down(new Event(Event.GET_PHYSICAL_ADDRESS, address)); // Physical address might be null if node is no longer a member of the cluster InetSocketAddress socketAddress = (ipAddress != null) ? new InetSocketAddress(ipAddress.getIpAddress(), ipAddress.getPort()) : new InetSocketAddress(0); // If no logical name exists, create one using physical address String name = Optional.ofNullable(NameCache.get(address)).orElseGet(() -> String.format("%s:%s", socketAddress.getHostString(), socketAddress.getPort())); return new AddressableNode(address, name, socketAddress); }); }
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 synchronized void writeNodeToDisk(Address logical_addr, PhysicalAddress physical_addr) { String filename=addressAsString(logical_addr); // first write all data to a temporary file // this is because the writing can be very slow under some circumstances File tmpFile=null, destination=null; try { tmpFile=writeToTempFile(root_dir, logical_addr, physical_addr, NameCache.get(logical_addr)); if(tmpFile == null) return; destination=new File(root_dir, filename + SUFFIX); //do a file move, this is much faster and could be considered atomic on most operating systems FileChannel src_ch=new FileInputStream(tmpFile).getChannel(); FileChannel dest_ch=new FileOutputStream(destination).getChannel(); src_ch.transferTo(0,src_ch.size(),dest_ch); src_ch.close(); dest_ch.close(); if(log.isTraceEnabled()) log.trace("Moved: " + tmpFile.getName() + "->" + destination.getName()); } catch(Exception ioe) { log.error(Util.getMessage("AttemptToMoveFailedAt") + tmpFile.getName() + "->" + destination.getName(), ioe); } finally { deleteFile(tmpFile); } }
public String print(boolean detailed) { String name=getName(); String retval=name != null? name : NameCache.get(this); return retval + ":" + getSite() + (detailed? printOthers() : ""); }
protected MergeHeader createInfo() { PhysicalAddress physical_addr=local_addr != null? (PhysicalAddress)down_prot.down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)) : null; return MergeHeader.createInfo(view.getViewId(), NameCache.get(local_addr), physical_addr); }
@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); } }
protected void multicastOwnMapping() { String logical_name=NameCache.get(local_addr); if(logical_name != null) { Message msg=new Message(null).setFlag(Message.Flag.OOB).setTransientFlag(Message.TransientFlag.DONT_LOOPBACK) .putHeader(id, new Header(Type.CACHE_RSP, local_addr, logical_name)); down_prot.down(msg); } }
public void handleConnect() { if (cluster_name == null || local_addr == null) log.error(Util.getMessage("GroupaddrOrLocaladdrIsNullCannotRegisterWithGossipRouterS")); else { InetAddress bind_addr=getTransport().getBindAddress(); log.trace("registering " + local_addr + " under " + cluster_name + " with GossipRouter"); stubManager.destroyStubs(); PhysicalAddress physical_addr = (PhysicalAddress) down_prot.down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); stubManager = new RouterStubManager(this, cluster_name, local_addr, NameCache.get(local_addr), physical_addr, reconnect_interval).useNio(this.use_nio); for (InetSocketAddress host : initial_hosts) { RouterStub stub=stubManager.createAndRegisterStub(new IpAddress(bind_addr, 0), new IpAddress(host.getAddress(), host.getPort())); stub.socketConnectionTimeout(sock_conn_timeout); } stubManager.connectStubs(); } }
/** * Sends a SITE-UNREACHABLE message to the sender of the message. Because the sender is always local (we're the * relayer), no routing needs to be done * @param dest * @param target_site */ protected void sendSiteUnreachableTo(Address dest, String target_site) { Message msg=new Message(dest).setFlag(Message.Flag.OOB, Message.Flag.INTERNAL) .src(new SiteUUID((UUID)local_addr, NameCache.get(local_addr), site)) .putHeader(id,new Relay2Header(Relay2Header.SITE_UNREACHABLE,new SiteMaster(target_site),null)); down_prot.down(msg); }
public Object handleDownEvent(Event evt) { Object retEvent = super.handleDownEvent(evt); switch (evt.getType()) { case Event.CONNECT: case Event.CONNECT_WITH_STATE_TRANSFER: case Event.CONNECT_USE_FLUSH: case Event.CONNECT_WITH_STATE_TRANSFER_USE_FLUSH: String group=evt.getArg(); Address local=local_addr; if(stubManager != null) stubManager.destroyStubs(); PhysicalAddress physical_addr=getPhysicalAddressFromCache(local); String logical_name=org.jgroups.util.NameCache.get(local); stubManager = new RouterStubManager(this,group,local, logical_name, physical_addr, getReconnectInterval()).useNio(this.use_nio); for (InetSocketAddress gr : gossip_router_hosts) { stubManager.createAndRegisterStub(new IpAddress(bind_addr, bind_port), new IpAddress(gr.getAddress(), gr.getPort())) .receiver(this).set("tcp_nodelay", tcp_nodelay); } stubManager.connectStubs(); break; case Event.DISCONNECT: disconnectStub(); break; } return retEvent; }
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); }
public Object up(Message msg) { Relay2Header hdr=msg.getHeader(id); Address dest=msg.getDest(); if(hdr == null) { // forward a multicast message to all bridges except myself, then pass up if(dest == null && is_site_master && relay_multicasts && !msg.isFlagSet(Message.Flag.NO_RELAY)) { Address src=msg.getSrc(); Address sender=new SiteUUID((UUID)msg.getSrc(), NameCache.get(msg.getSrc()), site); if(src instanceof ExtendedUUID) ((SiteUUID)sender).addContents((ExtendedUUID)src); sendToBridges(sender, msg, site); } return up_prot.up(msg); // pass up } else { // header is not null if(dest != null) handleMessage(hdr, msg); else deliver(null, hdr.original_sender, msg); } return null; }
public void up(MessageBatch batch) { for(Message msg: batch) { Relay2Header hdr=msg.getHeader(id); Address dest=msg.getDest(); if(hdr == null) { // forward a multicast message to all bridges except myself, then pass up if(dest == null && is_site_master && relay_multicasts && !msg.isFlagSet(Message.Flag.NO_RELAY)) { Address src=msg.getSrc(); Address sender=new SiteUUID((UUID)msg.getSrc(), NameCache.get(msg.getSrc()), site); if(src instanceof ExtendedUUID) ((SiteUUID)sender).addContents((ExtendedUUID)src); sendToBridges(sender, msg, site); } } else { // header is not null batch.remove(msg); // message is consumed if(dest != null) handleMessage(hdr, msg); else deliver(null, hdr.original_sender, msg); } } if(!batch.isEmpty()) up_prot.up(batch); }