All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.activemq.artemis.shaded.org.jgroups.stack.ProtocolStack Maven / Gradle / Ivy

There is a newer version: 2.37.0
Show newest version
package org.apache.activemq.artemis.shaded.org.jgroups.stack;

import org.apache.activemq.artemis.shaded.org.jgroups.*;
import org.apache.activemq.artemis.shaded.org.jgroups.annotations.Property;
import org.apache.activemq.artemis.shaded.org.jgroups.conf.ClassConfigurator;
import org.apache.activemq.artemis.shaded.org.jgroups.conf.PropertyConverter;
import org.apache.activemq.artemis.shaded.org.jgroups.conf.ProtocolConfiguration;
import org.apache.activemq.artemis.shaded.org.jgroups.jmx.ReflectUtils;
import org.apache.activemq.artemis.shaded.org.jgroups.protocols.TP;
import org.apache.activemq.artemis.shaded.org.jgroups.util.MessageBatch;
import org.apache.activemq.artemis.shaded.org.jgroups.util.Ref;
import org.apache.activemq.artemis.shaded.org.jgroups.util.StackType;
import org.apache.activemq.artemis.shaded.org.jgroups.util.Util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;


/**
 * A ProtocolStack manages a number of protocols layered above each other. It
 * creates all protocol classes, initializes them and, when ready, starts all of
 * them, beginning with the bottom most protocol. It also dispatches messages
 * received from the stack to registered objects (e.g. channel, GMP) and sends
 * messages sent by those objects down the stack.
 * 

* The ProtocolStack makes use of the Configurator to setup and initialize * stacks, and to destroy them again when not needed anymore * * @author Bela Ban */ public class ProtocolStack extends Protocol { public enum Position {ABOVE, BELOW}; protected static final String max_list_print_size="max-list-print-size"; protected Protocol top_prot; protected Protocol bottom_prot; protected JChannel channel; protected volatile boolean stopped=true; public ProtocolStack topProtocol(Protocol top) {this.top_prot=top; return this;} public ProtocolStack bottomProtocol(Protocol bottom) {this.bottom_prot=bottom; return this;} protected final DiagnosticsHandler.ProbeHandler props_handler=new DiagnosticsHandler.ProbeHandler() { public Map handleProbe(String... keys) { for(String key: keys) { if(Objects.equals(key, "props")) { String tmp=printProtocolSpec(true); HashMap map=new HashMap<>(1); map.put("props", tmp); return map; } if(key.startsWith(max_list_print_size)) { int index=key.indexOf('='); if(index >= 0) { Util.MAX_LIST_PRINT_SIZE=Integer.parseInt(key.substring(index+1)); } HashMap map=new HashMap<>(1); map.put(max_list_print_size, String.valueOf(Util.MAX_LIST_PRINT_SIZE)); return map; } if(key.equals("pp") || key.startsWith("print-protocols")) { List prots=getProtocols(); Collections.reverse(prots); StringBuilder sb=new StringBuilder(); for(Protocol prot: prots) sb.append(prot.getName()).append("\n"); HashMap map=new HashMap<>(1); map.put("protocols", sb.toString()); return map; } if(key.startsWith("rp") || key.startsWith("remove-protocol")) { int len=key.startsWith("rp")? "rp".length() : "remove-protocol".length(); key=key.substring(len); int index=key.indexOf('='); if(index != -1) { String rest=key.substring(index +1); if(rest != null && !rest.isEmpty()) { List prots=Util.parseCommaDelimitedStrings(rest); if(!prots.isEmpty()) { for(String p: prots) { List protocols=findProtocols(p); if(protocols != null && !protocols.isEmpty()) { for(Protocol prot_to_remove: protocols) { try { Protocol removed=removeProtocol(prot_to_remove); if(removed != null) log.debug("removed protocol %s from stack", prot_to_remove.getName()); } catch(Exception e) { log.error(Util.getMessage("FailedRemovingProtocol") + rest, e); } } } } } } } } if(key.startsWith("insert-protocol")) { key=key.substring("insert-protocol".length()+1); int index=key.indexOf('='); if(index == -1) break; // 1. name of the protocol to be inserted String prot_name=key.substring(0, index).trim(); if(findProtocol(prot_name) != null) { log.error("Protocol %s cannot be inserted as it is already present", prot_name); break; } Protocol prot=null; try { prot=createProtocol(prot_name); } catch(Exception e) { log.error(Util.getMessage("FailedCreatingAnInstanceOf") + prot_name, e); break; } key=key.substring(index+1); index=key.indexOf('='); if(index == -1) { log.error("= missing in insert-protocol command"); break; } // 2. "above" or "below" String tmp=key.substring(0, index); if(!tmp.equalsIgnoreCase("above") && !tmp.equalsIgnoreCase("below")) { log.error("Missing \"above\" or \"below\" in insert-protocol command"); break; } key=key.substring(index+1); String neighbor_prot=key.trim(); Protocol neighbor=findProtocol(neighbor_prot); if(neighbor == null) { log.error(Util.getMessage("NeighborProtocol") + " " + neighbor_prot + " not found in stack"); break; } Position position=tmp.equalsIgnoreCase("above")? Position.ABOVE : Position.BELOW; try { insertProtocol(prot, position, neighbor.getClass()); } catch(Exception e) { log.error(Util.getMessage("FailedInsertingProtocol") + prot_name + " " + tmp + " " + neighbor_prot, e); } try { callAfterCreationHook(prot, afterCreationHook()); prot.init(); prot.start(); } catch(Exception e) { log.error(Util.getMessage("FailedCreatingAnInstanceOf") + prot_name, e); } } } return null; } public String[] supportedKeys() { return new String[]{"props", max_list_print_size + "[=number]", "print-protocols", "\nremove-protocol=", "\ninsert-protocol==above | below="}; } }; public ProtocolStack(JChannel channel) throws Exception { this.channel=channel; Class tmp=ClassConfigurator.class; // load this class, trigger init() tmp.getDeclaredConstructor().newInstance(); } /** Used for programmatic creation of ProtocolStack */ public ProtocolStack() { } public JChannel getChannel() {return channel;} public ProtocolStack setChannel(JChannel ch) { this.channel=ch; return this; } /** Returns all protocols in a list, from top to bottom. These are not copies of protocols, so modifications will affect the actual instances ! */ public List getProtocols() { List v=new ArrayList<>(15); Protocol p=top_prot; while(p != null) { v.add(p); p=p.getDownProtocol(); } return v; } /** Returns the bottom most protocol */ public TP getTransport() { Protocol bottom=getBottomProtocol(); return bottom instanceof TP? (TP)bottom : null; } public Map> dumpStats() { Map> retval=new HashMap<>(); // no need to be sorted, we need order of protocols as in the config! for(Protocol p=top_prot; p != null; p=p.getDownProtocol()) { String prot_name=p.getName(); if(prot_name == null) continue; Map tmp=new TreeMap<>(); ReflectUtils.dumpStats(p, tmp); if(!tmp.isEmpty()) retval.put(prot_name, tmp); } return retval; } public Map> dumpStats(final String protocol_name, List attrs) { List prots=null; try { Class cl=Util.loadProtocolClass(protocol_name, this.getClass()); Protocol prot=findProtocol(cl); if(prot != null) prots=Collections.singletonList(prot); } catch(Exception e) { } if(prots == null) prots=findProtocols(protocol_name); if(prots == null || prots.isEmpty()) return null; Map> retval=new HashMap<>(); for(Protocol prot: prots) { Map tmp=new TreeMap<>(); ReflectUtils.dumpStats(prot, tmp); if(attrs != null && !attrs.isEmpty()) { // weed out attrs not in list for(Iterator it=tmp.keySet().iterator(); it.hasNext(); ) { String attrname=it.next(); boolean found=false; for(String attr : attrs) { if(attrname.startsWith(attr)) { found=true; break; // found } } if(!found) it.remove(); } } String pname=prot.getName(); if(retval.containsKey(pname)) retval.put(pname + "-" + prot.getId(), tmp); else retval.put(pname, tmp); } return retval; } /** * Prints the names of the protocols, from the bottom to top. If include_properties is true, * the properties for each protocol will also be printed. */ public String printProtocolSpec(boolean include_properties) { StringBuilder sb=new StringBuilder(); List protocols=getProtocols(); if(protocols == null || protocols.isEmpty()) return null; boolean first_colon_printed=false; Collections.reverse(protocols); for(Protocol prot: protocols) { String prot_name=prot.getClass().getName(); int index=prot_name.indexOf(Global.PREFIX); if(index >= 0) prot_name=prot_name.substring(Global.PREFIX.length()); if(first_colon_printed) sb.append(":"); else first_colon_printed=true; sb.append(prot_name); if(include_properties) { Map tmp=getProps(prot); if(!tmp.isEmpty()) { boolean printed=false; sb.append("("); for(Map.Entry entry: tmp.entrySet()) { if(printed) sb.append(";"); else printed=true; sb.append(entry.getKey()).append("=").append(entry.getValue()); } sb.append(")\n"); } } } return sb.toString(); } public String printProtocolSpecAsXML() { StringBuilder sb=new StringBuilder(); Protocol prot=bottom_prot; int len, max_len=30; sb.append("\n"); while(prot != null && !Objects.equals(prot.getClass(), ProtocolStack.class)) { String prot_name=prot.getClass().getName(); if(prot_name != null) { sb.append(" <").append(prot_name).append(" "); Map tmpProps=getProps(prot); if(tmpProps != null) { len=prot_name.length(); String s; for(Iterator> it=tmpProps.entrySet().iterator();it.hasNext();) { Entry entry=it.next(); s=entry.getKey() + "=\"" + entry.getValue() + "\" "; if(len + s.length() > max_len) { sb.append("\n "); len=8; } sb.append(s); len+=s.length(); } } sb.append("/>\n"); prot=prot.getUpProtocol(); } } sb.append(""); return sb.toString(); } public String printProtocolSpecAsPlainString() { return printProtocolSpecAsPlainString(false); } private String printProtocolSpecAsPlainString(boolean print_props) { StringBuilder sb=new StringBuilder(); List protocols=getProtocols(); if(protocols == null) return null; Collections.reverse(protocols); for(Protocol prot: protocols) { sb.append(prot.getClass().getName()).append("\n"); if(print_props) { Map tmp=getProps(prot); for(Map.Entry entry: tmp.entrySet()) { sb.append(" ").append(entry.getKey()).append("=").append(entry.getValue()).append("\n"); } } } return sb.toString(); } private static Map getProps(Protocol prot) { Map retval=new HashMap<>(); for(Class clazz=prot.getClass(); clazz != null; clazz=clazz.getSuperclass()) { // copy all fields marked with @Property Field[] fields=clazz.getDeclaredFields(); Property annotation; for(Field field: fields) { if(field.isAnnotationPresent(Property.class)) { Object value=Util.getField(field, prot); if(value != null) { annotation=field.getAnnotation(Property.class); Class conv_class=annotation.converter(); PropertyConverter conv=null; try { conv=(PropertyConverter)conv_class.getDeclaredConstructor().newInstance(); } catch(Exception e) { } String tmp=conv != null? conv.toString(value) : value.toString(); retval.put(field.getName(), tmp); } } } // copy all setters marked with @Property Method[] methods=clazz.getDeclaredMethods(); for(Method method: methods) { String methodName=method.getName(); if(method.isAnnotationPresent(Property.class) && Configurator.isSetPropertyMethod(method, clazz)) { annotation=method.getAnnotation(Property.class); List possible_names=new LinkedList<>(); if(annotation.name() != null) possible_names.add(annotation.name()); possible_names.add(Util.methodNameToAttributeName(methodName)); Field field=Util.findField(prot, possible_names); if(field != null) { Object value=Util.getField(field, prot); if(value != null) { Class conv_class=annotation.converter(); PropertyConverter conv=null; try { conv=(PropertyConverter)conv_class.getDeclaredConstructor().newInstance(); } catch(Exception e) { } String tmp=conv != null? conv.toString(value) : value.toString(); retval.put(field.getName(), tmp); } } } } } return retval; } public void setup(List configs) throws Exception { if(top_prot == null) { top_prot=new Configurator(this).setupProtocolStack(configs); top_prot.setUpProtocol(this); this.setDownProtocol(top_prot); bottom_prot=getBottomProtocol(); initProtocolStack(configs); } } /** * Adds a protocol at the tail of the protocol list * @param prot * @return * @since 2.11 */ public ProtocolStack addProtocol(Protocol prot) { if(prot == null) return this; prot.setProtocolStack(this); prot.setUpProtocol(this); if(bottom_prot == null) { top_prot=bottom_prot=prot; return this; } prot.setDownProtocol(top_prot); prot.getDownProtocol().setUpProtocol(prot); top_prot=prot; return this; } /** * Adds a list of protocols * @param prots * @return * @since 2.11 */ public ProtocolStack addProtocols(Protocol ... prots) { if(prots != null) { for(Protocol prot: prots) addProtocol(prot); } return this; } /** * Adds a list of protocols * @param prots * @return * @since 2.1 */ public ProtocolStack addProtocols(List prots) { if(prots != null) prots.forEach(this::addProtocol); return this; } /** * Inserts an already created (and initialized) protocol into the protocol list. Sets the links * to the protocols above and below correctly and adjusts the linked list of protocols accordingly. * Note that this method may change the value of top_prot or bottom_prot. * @param prot The protocol to be inserted. Before insertion, a sanity check will ensure that none * of the existing protocols have the same name as the new protocol. * @param position Where to place the protocol with respect to the neighbor_prot (ABOVE, BELOW) * @param neighbor_prot The name of the neighbor protocol. An exception will be thrown if this name * is not found * @exception Exception Will be thrown when the new protocol cannot be created, or inserted. */ public void insertProtocol(Protocol prot, Position position, String neighbor_prot) throws Exception { if(neighbor_prot == null) throw new IllegalArgumentException("neighbor_prot is null"); Protocol neighbor=findProtocol(neighbor_prot); if(neighbor == null) throw new IllegalArgumentException("protocol " + neighbor_prot + " not found in " + printProtocolSpec(false)); if(position == Position.BELOW && neighbor instanceof TP) throw new IllegalArgumentException("Cannot insert protocol " + prot.getName() + " below transport protocol"); insertProtocolInStack(prot, neighbor, position); } public void insertProtocolInStack(Protocol prot, Protocol neighbor, Position position) { // connect to the protocol layer below and above if(position == Position.BELOW) { prot.setUpProtocol(neighbor); Protocol below=neighbor.getDownProtocol(); prot.setDownProtocol(below); if(below != null) below.setUpProtocol(prot); neighbor.setDownProtocol(prot); } else { // ABOVE is default Protocol above=neighbor.getUpProtocol(); checkAndSwitchTop(neighbor, prot); prot.setUpProtocol(above); if(above != null) above.setDownProtocol(prot); prot.setDownProtocol(neighbor); neighbor.setUpProtocol(prot); } } private void checkAndSwitchTop(Protocol oldTop, Protocol newTop){ if(oldTop == top_prot) { top_prot = newTop; top_prot.setUpProtocol(this); } } public void insertProtocol(Protocol prot, Position position, Class neighbor_prot) throws Exception { if(neighbor_prot == null) throw new IllegalArgumentException("neighbor_prot is null"); Protocol neighbor=findProtocol(neighbor_prot); if(neighbor == null) throw new IllegalArgumentException("protocol \"" + neighbor_prot + "\" not found in " + stack.printProtocolSpec(false)); if(position == Position.BELOW && neighbor instanceof TP) throw new IllegalArgumentException("\"" + prot + "\" cannot be inserted below the transport (" + neighbor + ")"); insertProtocolInStack(prot, neighbor, position); } @SafeVarargs public final void insertProtocol(Protocol prot, Position position, Class... neighbor_prots) throws Exception { if(neighbor_prots == null) throw new IllegalArgumentException("neighbor_prots is null"); Protocol neighbor=findProtocol(neighbor_prots); if(neighbor == null) throw new IllegalArgumentException("protocol \"" + Arrays.toString(neighbor_prots) + "\" not found in " + stack.printProtocolSpec(false)); insertProtocolInStack(prot, neighbor, position); } public void insertProtocolAtTop(Protocol prot) { if(prot == null) throw new IllegalArgumentException("prot needs to be non-null"); // check if prot already exists (we cannot have more than 1 protocol of a given class) Class clazz=prot.getClass(); Protocol existing_instance=findProtocol(clazz); if(existing_instance != null) return; top_prot.up_prot=prot; prot.down_prot=top_prot; prot.up_prot=this; top_prot=prot; log.debug("inserted " + prot + " at the top of the stack"); } /** * Removes a protocol from the stack. Stops the protocol and readjusts the linked lists of protocols. * @param prot_name The name of the protocol. Since all protocol names in a stack have to be unique * (otherwise the stack won't be created), the name refers to just 1 protocol. * @exception Exception Thrown if the protocol cannot be stopped correctly. */ public T removeProtocol(String prot_name) { if(prot_name == null) return null; return removeProtocol(findProtocol(prot_name)); } public ProtocolStack removeProtocols(String ... protocols) { for(String protocol: protocols) removeProtocol(protocol); return this; } @SafeVarargs public final ProtocolStack removeProtocols(Class... protocols) { for(Class protocol: protocols) removeProtocol(protocol); return this; } @SafeVarargs public final T removeProtocol(Class... protocols) { for(Class cl: protocols) { T tmp=removeProtocol(cl); if(tmp != null) return tmp; } return null; } public T removeProtocol(Class prot) { if(prot == null) return null; return removeProtocol(findProtocol(prot)); } public T removeProtocol(T prot) { if(prot == null) return null; Protocol above=prot.getUpProtocol(), below=prot.getDownProtocol(); checkAndSwitchTop(prot, below); if(above != null) above.setDownProtocol(below); if(below != null) below.setUpProtocol(above); prot.setUpProtocol(null); prot.setDownProtocol(null); try { prot.stop(); } catch(Throwable t) { log.error(Util.getMessage("FailedStopping") + prot.getName() + ": " + t); } try { prot.destroy(); } catch(Throwable t) { log.error(Util.getMessage("FailedDestroying") + prot.getName() + ": " + t); } return prot; } /** Returns a given protocol or null if not found */ public T findProtocol(String name) { T tmp=(T)top_prot; String prot_name; while(tmp != null) { prot_name=tmp.getName(); if(Objects.equals(prot_name, name)) return tmp; tmp=tmp.getDownProtocol(); } return null; } public List findProtocols(String regexp) { List retval=null; Pattern pattern=Pattern.compile(regexp); for(T prot=(T)top_prot; prot != null; prot=prot.getDownProtocol()) { String prot_name=prot.getName(); if(pattern.matcher(prot_name).matches()) { if(retval == null) retval=new ArrayList<>(); retval.add(prot); } } return retval; } public T getBottomProtocol() { T curr_prot=(T)this; while(curr_prot != null && curr_prot.getDownProtocol() !=null) curr_prot=curr_prot.getDownProtocol(); return curr_prot; } public Protocol getTopProtocol() { return top_prot; } public T findProtocol(Class clazz) { Protocol tmp=top_prot; while(tmp != null) { Class protClass=tmp.getClass(); if(clazz.isAssignableFrom(protClass)) return (T)tmp; tmp=tmp.getDownProtocol(); } return null; } /** * Finds the first protocol of a list and returns it. Returns null if no protocol can be found * @param classes A list of protocol classes to find * @return Protocol The protocol found */ @SafeVarargs public final T findProtocol(Class... classes) { for(Class clazz: classes) { T prot=findProtocol(clazz); if(prot != null) return prot; } return null; } /** * Replaces one protocol instance with another. Should be done before the stack is connected * @param existing_prot * @param new_prot */ public void replaceProtocol(Protocol existing_prot, Protocol new_prot) throws Exception { Protocol up_neighbor=existing_prot.getUpProtocol(), down_neighbor=existing_prot.getDownProtocol(); new_prot.setUpProtocol(existing_prot.getUpProtocol()); new_prot.setDownProtocol(existing_prot.getDownProtocol()); up_neighbor.setDownProtocol(new_prot); if(down_neighbor != null) down_neighbor.setUpProtocol(new_prot); existing_prot.setDownProtocol(null); existing_prot.setUpProtocol(null); existing_prot.stop(); existing_prot.destroy(); if(new_prot.getUpProtocol() == this) top_prot=new_prot; callAfterCreationHook(new_prot, afterCreationHook()); new_prot.init(); } protected Protocol createProtocol(String classname) throws Exception { Class clazz=Util.loadProtocolClass(classname, getClass()); Protocol retval=clazz.getDeclaredConstructor().newInstance(); if(retval == null) throw new Exception("creation of instance for protocol " + classname + "failed"); retval.setProtocolStack(this); return retval; } public void init() throws Exception { List protocols=getProtocols(); Collections.reverse(protocols); top_prot=Configurator.connectProtocols(protocols); top_prot.setUpProtocol(this); this.setDownProtocol(top_prot); bottom_prot=getBottomProtocol(); StackType ip_version=Util.getIpStackType(); TP tp=getTransport(); InetAddress resolved_addr=tp != null? tp.getBindAddress() : null; if(resolved_addr != null) ip_version=resolved_addr instanceof Inet6Address? StackType.IPv6 : StackType.IPv4; else if(ip_version == StackType.Dual) ip_version=StackType.IPv4; // prefer IPv4 addresses Configurator.setDefaultAddressValues(protocols, ip_version); initProtocolStack(); } public void initProtocolStack() throws Exception { initProtocolStack(null); } /** Calls @link{{@link Protocol#init()}} in all protocols, from bottom to top */ public void initProtocolStack(List configs) throws Exception { List protocols=getProtocols(); Collections.reverse(protocols); try { for(int i=0; i < protocols.size(); i++) { Protocol prot=protocols.get(i); if(prot.getProtocolStack() == null) prot.setProtocolStack(this); callAfterCreationHook(prot, prot.afterCreationHook()); prot.init(); initComponents(prot, configs != null? configs.get(i) : null); } } catch(Exception ex) { this.destroy(); throw ex; } } public static void initComponents(Protocol p, ProtocolConfiguration cfg) throws Exception { // copy the props and weed out properties from non-components Map properties=cfg != null? cfg.getProperties() : new HashMap<>(); Map props=new HashMap<>(); // first a bit of sanity checking: no duplicate components in p final Map> prefixes=new HashMap<>(); final Ref ex=new Ref<>(null); Util.forAllComponentTypes(p.getClass(), (cl, prefix) -> { if(ex.isSet()) return; if(prefix == null || prefix.trim().isEmpty()) { ex.set(new IllegalArgumentException(String.format("component (class=%s) in %s must have a prefix", cl.getSimpleName(), p.getName()))); return; } if(prefixes.containsKey(prefix)) ex.set(new IllegalArgumentException(String.format("multiple components (class=%s) in %s have same prefix '%s'", cl.getSimpleName(), p.getName(), prefix))); else prefixes.put(prefix, cl); }); if(ex.isSet()) throw ex.get(); Util.forAllComponentTypes(p.getClass(), (c, prefix) -> { String key=prefix + "."; properties.entrySet().stream().filter(e -> e.getKey().startsWith(key)) .forEach(e -> props.put(e.getKey(), e.getValue())); }); ex.set(null); // StackType ip_version=Util.getIpStackType(); InetAddress resolved_addr=p.getTransport() != null? p.getTransport().getBindAddress() : null; final StackType ip_version=resolved_addr instanceof Inet6Address? StackType.IPv6 : StackType.IPv4; Util.forAllComponents(p, (comp,prefix) -> { try { if(ex.isSet()) return; Map m=new HashMap<>(); String key=prefix + "."; props.entrySet().stream().filter(e -> e.getKey().startsWith(key)) .forEach(e -> m.put(e.getKey().substring(prefix.length() + 1), e.getValue())); props.keySet().removeIf(k -> k.startsWith(key)); if(!m.isEmpty()) { Configurator.initializeAttrs(comp, m, ip_version); if(!m.isEmpty()) { String fmt="the following properties in %s:%s (%s) are not recognized: %s"; ex.set(new IllegalArgumentException(String.format(fmt, p.getName(), prefix, comp.getClass().getSimpleName(), m))); } } Configurator.setDefaultAddressValues(comp, ip_version); if(comp instanceof Lifecycle) ((Lifecycle)comp).init(); } catch(Exception e) { throw new IllegalArgumentException(String.format("failed initializing component %s in protocol %s: %s", comp.getClass().getSimpleName(), p, e)); } }); if(ex.isSet()) throw ex.get(); if(!props.isEmpty()) { String fmt="configuration error: the following component properties in %s are not recognized: %s"; throw new IllegalArgumentException(String.format(fmt, p.getName(), props)); } } public void destroy() { if(top_prot != null) getProtocols().forEach(Protocol::destroy); } /** * Start all protocols. The {@link Protocol#start()} method is called in each protocol, * from bottom to top. Each protocol can perform some initialization, e.g. create a multicast socket */ public void startStack() throws Exception { if(!stopped) return; stopped=false; List protocols=getProtocols(); Collections.reverse(protocols); for(Protocol prot: protocols) prot.start(); TP transport=getTransport(); transport.registerProbeHandler(props_handler); } /** * Iterates through all the protocols from top to bottom and does the following: *

    *
  1. Waits until all messages in the down queue have been flushed (ie., size is 0) *
  2. Calls stop() on the protocol *
*/ public void stopStack(String cluster) { if(stopped) return; getProtocols().forEach(Protocol::stop); TP transport=getTransport(); transport.unregisterProbeHandler(props_handler); stopped=true; } /*--------------------------- Protocol functionality ------------------------------*/ public String getName() {return "ProtocolStack";} public Object up(Event evt) { return channel.up(evt); } public Object up(Message msg) {return channel.up(msg);} public void up(MessageBatch batch) { channel.up(batch); } public Object down(Event evt) { if(top_prot != null) return top_prot.down(evt); return null; } public Object down(Message msg) { if(top_prot != null) return top_prot.down(msg); return null; } protected static void callAfterCreationHook(Protocol prot, String classname) throws Exception { if(classname == null || prot == null) return; Class clazz=(Class)Util.loadClass(classname, prot.getClass()); ProtocolHook hook=clazz.getDeclaredConstructor().newInstance(); hook.afterCreation(prot); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy