Package flex.messaging.cluster

Source Code of flex.messaging.cluster.ClusterManager

/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
*  [2002] - [2007] Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated
* and its suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package flex.messaging.cluster;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Map;
import java.util.Collections;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import flex.messaging.Destination;
import flex.messaging.MessageBroker;
import flex.messaging.config.ClusterSettings;
import flex.messaging.endpoints.Endpoint;
import flex.messaging.util.ClassUtil;

/**
* @exclude
* The manager of all clusters defined in services-config.xml, and the broker
* for the clusters created for clustered destinations.
*
* @author neville
*/
public class ClusterManager
{
    private MessageBroker broker;

    // name=clusterId value=clusterInstance
    private Map clusters;

    private Map clustersForDestination;

    // name=clusterId value=propsFile
    private Map clusterConfig;

    // name=clusterId value=ClusterSettings
    private Map clusterSettings;

    private Map backendSharedForDestination;

    private Cluster defaultCluster;

    private String defaultClusterId;

    public ClusterManager(MessageBroker broker)
    {
        this.broker = broker;
        this.clusters = new HashMap();
        this.clusterConfig = new HashMap();
        this.clusterSettings = new HashMap();
        this.clustersForDestination = new HashMap();
        this.backendSharedForDestination = new HashMap();
    }

    public MessageBroker getMessageBroker()
    {
        return broker;
    }

    public Cluster getDefaultCluster()
    {
        return defaultCluster;
    }

    public String getDefaultClusterId()
    {
        return defaultClusterId;
    }

    public void invokeServiceOperation(String serviceType, String destinationName,
                                       String operationName, Object[] params)
    {
        Cluster c = getCluster(serviceType,destinationName);
        ArrayList newParams = new ArrayList(Arrays.asList(params));
        newParams.add(0, serviceType);
        newParams.add(1, destinationName);
        c.broadcastServiceOperation(operationName, newParams.toArray());
    }

    public void invokePeerToPeerOperation(String serviceType, String destinationName,
                                          String operationName, Object[] params, Object targetAddress)
    {
        Cluster c = getCluster(serviceType,destinationName);
        ArrayList newParams = new ArrayList(Arrays.asList(params));
        newParams.add(0, serviceType);
        newParams.add(1, destinationName);
        c.sendPointToPointServiceOperation(operationName, newParams.toArray(), targetAddress);
    }

    public boolean isDestinationClustered(String serviceType, String destinationName)
    {
        return getCluster(serviceType, destinationName) != null;
    }

    public boolean isBackendShared(String serviceType, String destinationName)
    {
        String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);

        Boolean shared = (Boolean) backendSharedForDestination.get(destKey);

        if (shared == null)
            return false;

        return shared.booleanValue();
    }

    public List getClusterMemberAddresses(String serviceType, String destinationName)
    {
        Cluster c= getCluster(serviceType, destinationName);
        if (c == null)
            return Collections.EMPTY_LIST;

        return c.getMemberAddresses();
    }

    public void prepareCluster(ClusterSettings settings)
    {
        if (settings.getPropsFileName() == null)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10201, new Object[] { settings.getClusterName(), settings.getPropsFileName() });
            throw cx;
        }

        InputStream propsFile;

        try
        {
            propsFile = broker.resolveInternalPath(settings.getPropsFileName());
        }
        catch (Throwable t)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10208, new Object[] { settings.getPropsFileName() });
            cx.setRootCause(t);
            throw cx;
        }

        if (propsFile == null)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10208, new Object[] { settings.getPropsFileName() });
            throw cx;
        }
        else
        {
            try
            {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setNamespaceAware(false);
                factory.setValidating(false);
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse(propsFile);
                if (settings.isDefault())
                {
                    defaultClusterId = settings.getClusterName();
                }
                clusterConfig.put(settings.getClusterName(), doc.getDocumentElement());
                clusterSettings.put(settings.getClusterName(), settings);
            }
            catch (Exception ex)
            {
                ClusterException cx = new ClusterException();
                cx.setMessage(10213);
                cx.setRootCause(ex);
                throw cx;
            }
        }

    }

    public Object getLocalAddress(String serviceType, String destinationName)
    {
        Cluster c = getCluster(serviceType, destinationName);
        if (c == null)
            return null;

        return c.getLocalAddress();
    }

    public Cluster getClusterById(String clusterId)
    {
        return (Cluster) clusters.get(clusterId);
    }

    public Cluster getCluster(String serviceType, String destinationName)
    {
        Cluster cluster = null;
        try
        {
            String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);

            cluster = (Cluster)clustersForDestination.get(destKey);

            if (cluster == null)
                cluster = defaultCluster;
        }
        catch (NoClassDefFoundError nex)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10202, new Object[] { destinationName });
            cx.setRootCause(nex);
            throw cx;
        }
        return cluster;
    }

    public void destroyClusters()
    {
        for (Iterator iter=clusters.keySet().iterator(); iter.hasNext(); )
        {
            Cluster cluster = (Cluster) clusters.get(iter.next());
            cluster.destroy();
            iter.remove();
        }
    }

    public void clusterDestinationChannel(String clusterId, String serviceType, String destinationName,
                                          String channelId, String endpointUrl, int endpointPort, boolean sharedBackend)
    {
        Cluster cluster = getClusterById(clusterId);
        String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
        if (cluster == null)
        {
            if (!clusterConfig.containsKey(clusterId))
            {
                ClusterException cx = new ClusterException();
                cx.setMessage(10207, new Object[] { destinationName, clusterId });
                throw cx;
            }
            cluster = createCluster(clusterId, serviceType, destinationName);
        }
        else
        {
            clustersForDestination.put(destKey, cluster);
        }
        backendSharedForDestination.put(destKey, sharedBackend ? Boolean.TRUE : Boolean.FALSE);

        if (cluster.getURLLoadBalancing())
            cluster.addLocalEndpointForChannel(serviceType, destinationName,
                                               channelId, endpointUrl, endpointPort);
    }

    public void clusterDestination(Destination destination)
    {
        String clusterId = destination.getNetworkSettings().getClusterId();
        String serviceType = destination.getServiceType();
        String destinationName = destination.getId();
        boolean sharedBackend = destination.getNetworkSettings().isSharedBackend();
        List channelIds = destination.getChannels();

        if (clusterId == null)
            clusterId = getDefaultClusterId();

        ClusterSettings cls = (ClusterSettings) clusterSettings.get(clusterId);
       
        if (cls == null)
        {
            ClusterException ce = new ClusterException();
            ce.setMessage(10217, new Object[] {destination.getId(), clusterId});
            throw ce;
        }
       
        for (Iterator iter=channelIds.iterator(); iter.hasNext();)
        {
            String channelId = (String)iter.next();               
            Endpoint endpoint = broker.getEndpoint(channelId);                                     
            String endpointUrl = endpoint.getUrl();
            int endpointPort = endpoint.getPort();

            // This is only an error if we are using client side url-based load balancing.  If
            // there is a HW load balancer, then we can assume the server.name served up by the
            // SWF can be used to access the cluster members.  With client side load balancing,
            // the clients need the direct URLs of all of the servers.
            if (cls.getURLLoadBalancing())
            {
                // Ensure that the endpoint URI does not contain any replacement tokens.
                int tokenStart = endpointUrl.indexOf("{");
                if (tokenStart != -1)
                {
                    int tokenEnd = endpointUrl.indexOf("}", tokenStart);
                    if (tokenEnd == -1)
                        tokenEnd = endpointUrl.length();
                    else
                        tokenEnd++;

                    ClusterException ce = new ClusterException();
                    ce.setMessage(10209, new Object[] {destination.getId(), channelId, endpointUrl.substring(tokenStart, tokenEnd)});
                    throw ce;
                }
            }

            clusterDestinationChannel(clusterId, serviceType, destinationName, channelId, endpointUrl, endpointPort, sharedBackend);
      }       
    }
   
    public List getEndpointsForDestination(String serviceType, String destinationName)
    {
        Cluster c = getCluster(serviceType, destinationName);
        if (c != null)
        {
            return c.getAllEndpoints(serviceType, destinationName);
        }
        return null;
    }

    private Cluster createCluster(String clusterId, String serviceType, String destinationName)
    {
        String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
        Element propsFile = (Element) clusterConfig.get(clusterId);
        ClusterSettings cls = (ClusterSettings) clusterSettings.get(clusterId);
        Cluster cluster = null;
        Class clusterClass = ClassUtil.createClass(cls.getImplementationClass());
        Constructor clusterConstructor = null;
        try
        {
            clusterConstructor = clusterClass.getConstructor(new Class[] {ClusterManager.class, String.class, Element.class});
        }
        catch (Exception e)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10210);
            cx.setRootCause(e);
            throw cx;
        }
        try
        {
            cluster = (Cluster)clusterConstructor.newInstance(new Object[] {this, clusterId, propsFile});
            cluster.setURLLoadBalancing(cls.getURLLoadBalancing());
        }
        catch (Exception e)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10211);
            cx.setRootCause(e);
            throw cx;
        }
        clustersForDestination.put(destKey, cluster);
        clusters.put(clusterId, cluster);

        if (defaultClusterId != null && defaultClusterId.equals(clusterId))
            defaultCluster = cluster;

        return cluster;
    }
}
TOP

Related Classes of flex.messaging.cluster.ClusterManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.