Package org.codehaus.activemq.transport.composite

Source Code of org.codehaus.activemq.transport.composite.CompositeTransportChannel

/**
*
* Copyright 2004 Protique Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
package org.codehaus.activemq.transport.composite;

import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.activemq.TimeoutExpiredException;
import org.codehaus.activemq.io.WireFormat;
import org.codehaus.activemq.message.Packet;
import org.codehaus.activemq.message.PacketListener;
import org.codehaus.activemq.message.Receipt;
import org.codehaus.activemq.message.ReceiptHolder;
import org.codehaus.activemq.transport.TransportChannel;
import org.codehaus.activemq.transport.TransportChannelProvider;
import org.codehaus.activemq.transport.TransportChannelSupport;
import org.codehaus.activemq.transport.TransportStatusEvent;
import org.codehaus.activemq.transport.TransportStatusEventListener;

import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* A Compsite implementation of a TransportChannel
*
* @version $Revision: 1.4 $
*/
public class CompositeTransportChannel extends TransportChannelSupport implements TransportStatusEventListener {
    private static final Log log = LogFactory.getLog(CompositeTransportChannel.class);

    protected WireFormat wireFormat;
    protected List uris;
    protected TransportChannel channel;
    protected SynchronizedBoolean closed;
    protected SynchronizedBoolean started;
    protected int maximumRetries = 10;
    protected long failureSleepTime = 500L;
    protected URI currentURI;
    private long establishConnectionTimeout = 30000L;


    public CompositeTransportChannel(WireFormat wireFormat) {
        this.wireFormat = wireFormat;
        this.uris = Collections.synchronizedList(new ArrayList());
        closed = new SynchronizedBoolean(false);
        started = new SynchronizedBoolean(false);
    }

    public CompositeTransportChannel(WireFormat wireFormat, List uris) {
        this(wireFormat);
        this.uris.addAll(uris);
    }

    public String toString() {
        return "CompositeTransportChannel: " + channel;
    }

    public void start() throws JMSException {
        if (started.commit(false, true)) {
            establishConnection(establishConnectionTimeout);
        }
    }

    /**
     * close the channel
     */
    public void stop() {
        if (closed.commit(false, true)) {
            if (channel != null) {
                try {
                    channel.stop();
                }
                catch (Exception e) {
                    log.warn("Caught while closing: " + e + ". Now Closed", e);
                }
                finally {
                    channel = null;
                    super.stop();
                }
            }
        }
    }
   
    /**
     * Forces disconnect by delegating to the child channel
     */
    public void forceDisconnect() {
      if (channel != null) channel.forceDisconnect();
    }
   
    public Receipt send(Packet packet) throws JMSException {
        return getChannel().send(packet);
    }


    public Receipt send(Packet packet, int timeout) throws JMSException {
        return getChannel().send(packet, timeout);
    }


    public void asyncSend(Packet packet) throws JMSException {
        getChannel().asyncSend(packet);
    }
   
  public ReceiptHolder asyncSendWithReceipt(Packet packet) throws JMSException {
    return getChannel().asyncSendWithReceipt(packet);
  }

    public void setPacketListener(PacketListener listener) {
        super.setPacketListener(listener);
        if (channel != null) {
            channel.setPacketListener(listener);
        }
    }


    public void setExceptionListener(ExceptionListener listener) {
        super.setExceptionListener(listener);
        if (channel != null) {
            channel.setExceptionListener(listener);
        }
    }


    public boolean isMulticast() {
        return false;
    }

    // Properties
    //-------------------------------------------------------------------------


    /**
     * Return the maximum amount of time spent trying to establish a connection
     * or a negative number to keep going forever
     *
     * @return
     */
    public long getEstablishConnectionTimeout() {
        return establishConnectionTimeout;
    }

    public void setEstablishConnectionTimeout(long establishConnectionTimeout) {
        this.establishConnectionTimeout = establishConnectionTimeout;
    }

    public int getMaximumRetries() {
        return maximumRetries;
    }

    public void setMaximumRetries(int maximumRetries) {
        this.maximumRetries = maximumRetries;
    }

    public long getFailureSleepTime() {
        return failureSleepTime;
    }

    public void setFailureSleepTime(long failureSleepTime) {
        this.failureSleepTime = failureSleepTime;
    }

    public List getUris() {
        return uris;
    }

    public void setUris(List list) {
        synchronized (uris) {
            uris.clear();
            uris.addAll(list);
        }
    }
   
    /**
     * Can this wireformat process packets of this version
     * @param version the version number to test
     * @return true if can accept the version
     */
    public boolean canProcessWireFormatVersion(int version){
        return channel != null ? channel.canProcessWireFormatVersion(version) : true;
    }
   
    /**
     * @return the current version of this wire format
     */
    public int getCurrentWireFormatVersion(){
        return channel != null ? channel.getCurrentWireFormatVersion() : 1;
    }

    // Implementation methods
    //-------------------------------------------------------------------------
   
    protected void establishConnection(long timeout) throws JMSException {

        // lets try connect
        boolean connected = false;
        long time = failureSleepTime;
        long startTime = System.currentTimeMillis();

        for (int i = 0; !connected && (i < maximumRetries || maximumRetries <= 0) && !closed.get() && !isPendingStop(); i++) {
            List list = new ArrayList(getUris());
            if (i > 0) {
                if (maximumRetries > 0 || timeout > 0) {
                    long current = System.currentTimeMillis();
                    if (timeout >= 0) {
                        if (current + time > startTime + timeout) {
                            time = startTime + timeout - current;
                        }
                    }
                    if (current > startTime + timeout || time <= 0) {
                        throw new TimeoutExpiredException("Could not connect to any of the URIs: " + list);
                    }
                }
                log.info("Could not connect; sleeping for: " + time + " millis and trying again");
                try {
                    Thread.sleep(time);
                }
                catch (InterruptedException e) {
                    log.warn("Sleep interupted: " + e, e);
                }
                if (maximumRetries > 0) {
                    time *= 2;
                }
            }

            while (!connected && !list.isEmpty() && !closed.get() && !isPendingStop()) {
                URI uri = extractURI(list);
                try {
                    attemptToConnect(uri);
                    configureChannel();
                    connected = true;
                    currentURI = uri;
                }
                catch (JMSException e) {
                    log.info("Could not connect to: " + uri + ". Reason: " + e);
                }
            }

        }
        if (!connected && !closed.get()) {
            StringBuffer buffer = new StringBuffer("");
            Object[] uriArray = getUris().toArray();
            for (int i = 0; i < uriArray.length; i++) {
                buffer.append(uriArray[i]);
                if (i < (uriArray.length - 1)) {
                    buffer.append(",");
                }
            }
            JMSException jmsEx = new JMSException("Failed to connect to resource(s): " + buffer.toString());
            throw jmsEx;
        }

    }


    protected TransportChannel getChannel() throws JMSException {
        if (channel == null) {
            throw new JMSException("No TransportChannel connection available");
        }
        return channel;
    }

    protected void configureChannel() {
        ExceptionListener exceptionListener = getExceptionListener();
        if (exceptionListener != null) {
            channel.setExceptionListener(exceptionListener);
        }
        PacketListener packetListener = getPacketListener();
        if (packetListener != null) {
            channel.setPacketListener(packetListener);
        }
       
        channel.addTransportStatusEventListener(this);
    }

    protected URI extractURI(List list) throws JMSException {
        int idx = 0;
        if (list.size() > 1) {
            do {
                idx = (int) (Math.random() * list.size());
            }
            while (idx < 0 || idx >= list.size());
        }
        return (URI) list.remove(idx);
    }

    protected void attemptToConnect(URI uri) throws JMSException {
        channel = TransportChannelProvider.create(wireFormat, uri);
        if (started.get()) {
            channel.start();
        }
    }
   
  public void statusChanged(TransportStatusEvent event) {
    // Delegate to own listeners
    fireStatusEvent(event);
  }
 
  public boolean isTransportConnected() {
    return channel == null ? false : channel.isTransportConnected();
  }
}
TOP

Related Classes of org.codehaus.activemq.transport.composite.CompositeTransportChannel

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.