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

org.jgroups.protocols.relay.config.RelayConfig Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
package org.jgroups.protocols.relay.config;

import org.jgroups.JChannel;
import org.jgroups.conf.XmlConfigurator;
import org.jgroups.conf.XmlNode;
import org.jgroups.stack.Protocol;
import org.jgroups.util.Util;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Parses and maintains the RELAY2 configuration (in memory)
 * @author Bela Ban
 * @since 3.2
 */
public class RelayConfig {
    protected static final String RELAY_CONFIG  = "RelayConfiguration";
    protected static final String SITES         = "sites";
    protected static final String SITE          = "site";
    protected static final String BRIDGES       = "bridges";
    protected static final String BRIDGE        = "bridge";
    protected static final String FORWARDS      = "forwards";
    protected static final String FORWARD       = "forward";
    
	private RelayConfig() {
		throw new InstantiationError( "Must not instantiate this class" );
	}



    /** Parses site names and their configuration (e.g. "nyc" --> SiteConfig) into the map passed as argument */
    public static void parse(InputStream input, final Map map) throws Exception {
        XmlNode root=XmlConfigurator.parseXmlDocument(input);
        parse(root, map);
    }

    public static void parse(XmlNode root, final Map map) throws Exception {
        match(RELAY_CONFIG, root.getName());
        List children=root.getChildren();
        if(children == null || children.isEmpty())
            return;
        for(XmlNode node: children) {
            match(SITES, node.getName());
            parseSites(map, node);
        }
    }


    protected static void parseSites(final Map map, XmlNode root) throws Exception {
        List children=root.getChildren();
        if(children == null || children.isEmpty())
            return;
        for(XmlNode node: children) {
            match(SITE, node.getName());
            Map attrs=node.getAttributes();
            if(attrs == null || attrs.isEmpty() || !attrs.containsKey("name"))
                throw new IllegalStateException(String.format("site must have a name (attrs: %s)", attrs));
            String site_name=attrs.get("name");
            if(map.containsKey(site_name))
                throw new Exception("Site \"" + site_name + "\" already defined");
            SiteConfig site_config=new SiteConfig(site_name);
            map.put(site_name, site_config);
            parseBridgesAndForwards(site_config, node);
        }
    }

    protected static void parseBridgesAndForwards(SiteConfig site_config, XmlNode root) throws Exception {
        List children=root.getChildren();
        if(children == null || children.isEmpty())
            return;
        for(XmlNode node: children) {
            String node_name=node.getName();
            if(BRIDGES.equals(node_name))
                parseBridges(site_config, node);
            else if(FORWARDS.equals(node_name))
                parseForwards(site_config, node);
            else
                throw new Exception("expected \"" + BRIDGES + "\" or \"" + FORWARDS + "\" keywords");
        }
    }

    protected static void parseBridges(SiteConfig site_config, XmlNode root) throws Exception {
        List children=root.getChildren();
        if(children == null || children.isEmpty())
            return;
        for(XmlNode node: children) {
            String node_name=node.getName();
            match(BRIDGE, node_name);

            Map attrs=node.getAttributes();
            if(attrs == null || attrs.isEmpty())
                continue;
            String name=attrs.get("name");
            String config=attrs.get("config");
            BridgeConfig bridge_config=new PropertiesBridgeConfig(name, config);
            site_config.addBridge(bridge_config);
        }
    }

    protected static void parseForwards(SiteConfig site_config, XmlNode root) throws Exception {
        List children=root.getChildren();
        if(children == null || children.isEmpty())
            return;
        for(XmlNode node: children) {
            match(FORWARD, node.getName());
            Map attrs=node.getAttributes();
            if(attrs == null || attrs.isEmpty())
                continue;
            String to=attrs.get("to");
            String gateway=attrs.get("gateway");
            ForwardConfig forward_config=new ForwardConfig(to, gateway);
            site_config.addForward(forward_config);
        }
    }


    protected static void match(String expected_name, String name) throws Exception {
        if(!expected_name.equals(name))
            throw new Exception("\"" + name + "\" didn't match \"" + expected_name + "\"");
    }

    public static class SiteConfig {
        protected final String              name;
        protected final List  bridges=new ArrayList<>();
        protected final List forwards=new ArrayList<>();

        public SiteConfig(String name) {
            this.name=name;
        }

        public String getName() {return name;}

        public List  getBridges()   {return bridges;}
        public List getForwards()  {return forwards;}

        public SiteConfig addBridge(BridgeConfig bridge_config)    {bridges.add(bridge_config);   return this;}
        public SiteConfig addForward(ForwardConfig forward_config) {forwards.add(forward_config); return this;}

        public String toString() {
            StringBuilder sb=new StringBuilder("name=" + name + "\n");
            if(!bridges.isEmpty())
                for(BridgeConfig bridge_config: bridges)
                    sb.append(bridge_config).append("\n");
            if(!forwards.isEmpty())
                for(ForwardConfig forward_config: forwards)
                    sb.append(forward_config).append("\n");
            return sb.toString();
        }
    }

    public abstract static class BridgeConfig {
        protected String cluster_name;

        protected BridgeConfig(String cluster_name) {
            this.cluster_name=cluster_name;
        }

        public String            getClusterName()         {return cluster_name;}
        public BridgeConfig      setClusterName(String s) {cluster_name=s; return this;}
        public abstract JChannel createChannel() throws Exception;

        public String toString() {return String.format("bridge %s", cluster_name);}
    }

    public static class PropertiesBridgeConfig extends BridgeConfig {
        protected final String config;

        public PropertiesBridgeConfig(String cluster_name, String config) {
            super(cluster_name);
            this.config=Util.substituteVariable(config);
        }

        public JChannel createChannel() throws Exception {return new JChannel(config);}
        public String toString() {return String.format("config=%s\n%s", config, super.toString());}
    }


    public static class ProgrammaticBridgeConfig extends BridgeConfig {
        protected Protocol[] protocols;

        public ProgrammaticBridgeConfig(String cluster_name, Protocol[] prots) {
            super(cluster_name);
            this.protocols=prots;
        }

        public JChannel createChannel() throws Exception {
            return new JChannel(protocols);
        }

        public String toString() {
            return super.toString() + ", protocols=" + printProtocols(protocols);
        }


        protected static String printProtocols(Protocol[] protocols) {
            StringBuilder sb=new StringBuilder("[");
            boolean first=true;
            for(Protocol prot: protocols) {
                if(first)
                    first=false;
                else
                    sb.append(", ");
                sb.append(prot.getName());
            }
            sb.append("]");
            return sb.toString();
        }
    }


    /**
     * Forwards to site 'to' via route 'gateway'. Example: if site HF is reachable via NET1, if NET2 is not directly
     * connected to HF, it needs to have a ForwardConfig with to="HF" and gateway="NET1". This means that a message to
     * site HF will be forwarded to NET1, which then forwards it to HF.
     */
    public static class ForwardConfig {
        protected final String to;
        protected final String gateway;

        public ForwardConfig(String to, String gateway) {
            this.to=to;
            this.gateway=gateway;
        }

        public String gateway() {return gateway;}
        public String to()      {return to;}

        public String toString() {
            return "forward to=" + to + " gw=" + gateway;
        }
    }

    public static void main(String[] args) throws Exception {
        InputStream input=new FileInputStream("/home/bela/relay2.xml");
        Map sites=new HashMap<>();
        RelayConfig.parse(input, sites);
        System.out.println("sites:");
        for(Map.Entry entry: sites.entrySet())
            System.out.println(entry.getKey() + ":\n" + entry.getValue() + "\n");

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy