/**
*
* Copyright 2004 Hiram Chirino
* 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.gnet;
import EDU.oswego.cs.dl.util.concurrent.Latch;
import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.network.SelectorManager;
import org.apache.geronimo.network.protocol.AcceptableProtocol;
import org.apache.geronimo.network.protocol.ProtocolFactory;
import org.apache.geronimo.network.protocol.ProtocolFactory.AcceptedCallBack;
import org.apache.geronimo.network.protocol.ServerSocketAcceptor;
import org.apache.geronimo.network.protocol.SocketProtocol;
import org.apache.geronimo.pool.ClockPool;
import org.apache.geronimo.pool.ThreadPool;
import org.codehaus.activemq.message.WireFormat;
import org.codehaus.activemq.transport.TransportServerChannel;
import org.codehaus.activemq.transport.TransportServerChannelSupport;
import org.codehaus.activemq.util.JMSExceptionHelper;
import javax.jms.JMSException;
import java.net.URI;
/**
* An implementation of TransportServerChannel which uses
* the Geronimo network layer for connectivity.
*
* @version $Revision: 1.12 $
*/
public class GTransportServerChannel extends TransportServerChannelSupport implements TransportServerChannel {
protected static final int BACKLOG = 500;
private static final Log log = LogFactory.getLog(GTransportServerChannel.class);
private WireFormat wireFormat;
private SynchronizedBoolean closed;
private ThreadPool tp;
private ClockPool cp;
private SelectorManager sm;
private ServerSocketAcceptor ssa;
private ProtocolFactory pf;
private Latch startLatch;
/**
* Default Constructor
*
* @param bindAddr
* @throws JMSException
*/
public GTransportServerChannel(WireFormat wireFormat, URI bindAddr, SelectorManager selectorManager, ThreadPool threadPool, ClockPool clockPool) throws Exception {
super(bindAddr);
this.wireFormat = wireFormat;
this.sm = selectorManager;
this.tp = threadPool;
this.cp = clockPool;
closed = new SynchronizedBoolean(false);
startLatch = new Latch();
/*
ControlServerProtocolStack templateStack = new ControlServerProtocolStack();
*/
SocketProtocol spt = new SocketProtocol();
spt.setTimeout(30 * 1000);
spt.setSelectorManager(sm);
/*
templateStack.push(spt);
ControlServerProtocol csp = new ControlServerProtocol();
csp.setTimeout(30 * 1000);
csp.setThreadPool(tp);
csp.setClockPool(cp);
csp.setSelectorManager(sm);
csp.setControlServerListener(new ControlServerListener() {
public void shutdown() {
log.trace("SERVER SIDE SHUTDOWN");
}
});
templateStack.push(csp);
ControlServerProtocolWaiter waiter = new ControlServerProtocolWaiter();
waiter.push(new CountingProtocol());
templateStack.push(waiter);
*/
pf = new ProtocolFactory();
pf.setClockPool(cp);
pf.setMaxAge(Long.MAX_VALUE);
pf.setMaxInactivity(Long.MAX_VALUE);
//pf.setReclaimPeriod(Long.MAX_VALUE);
pf.setReclaimPeriod(10 * 1000);
pf.setTemplate(spt);
// pf.setTemplate(templateStack);
pf.setAcceptedCallBack(createAcceptedCallBack());
ssa = new ServerSocketAcceptor();
ssa.setSelectorManager(sm);
ssa.setTimeOut(5 * 1000);
ssa.setUri(bindAddr);
ssa.setAcceptorListener(pf);
}
/**
* @return
*/
private AcceptedCallBack createAcceptedCallBack() {
return new AcceptedCallBack() {
public void accepted(AcceptableProtocol p) {
try {
// Wait for start to be called before accepting connections..
startLatch.acquire();
if (p != null) {
GTransportChannel channel = new GTransportChannel(wireFormat, p, tp);
addClient(channel);
}
}
catch (Exception e) {
log.error("Caught while attempting to add new protocol: " + e, e);
}
}
};
}
/**
* start listeneing for events
*
* @throws JMSException if an error occurs
*/
public void start() throws JMSException {
super.start();
try {
ssa.startup();
}
catch (Exception e) {
JMSException jmsEx = new JMSException("Could not start ServerSocketAcceptor: " + e);
jmsEx.setLinkedException(e);
throw jmsEx;
}
startLatch.release();
}
/**
* close the ServerChannel
*/
public void stop() throws JMSException {
if (closed.commit(false, true)) {
super.stop();
try {
ssa.drain();
pf.drain();
}
catch (Throwable e) {
throw JMSExceptionHelper.newJMSException("Failed to stop: " + e, e);
}
}
}
/**
* @return pretty print of this
*/
public String toString() {
return "GTransportServerChannel@" + getUrl();
}
}