Package org.hudsonci.utils.tasks

Source Code of org.hudsonci.utils.tasks.OpenServerSocket$Connection

/**
* The MIT License
*
* Copyright (c) 2010-2011 Sonatype, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.hudsonci.utils.tasks;

import hudson.remoting.Callable;
import hudson.remoting.Channel;
import hudson.remoting.RemoteInputStream;
import hudson.remoting.RemoteOutputStream;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

/**
* Opens a server socket on a node and facilitates accepting connections.
*
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @since 2.1.0
*/
public class OpenServerSocket
    implements Callable<OpenServerSocket.Acceptor,IOException>
{
    private static final Logger log = LoggerFactory.getLogger(OpenServerSocket.class);

    public static final int DEFAULT_SO_TIMEOUT = 30 * 1000;

    /**
     * Used to accept a new connection on the remote server socket.
     */
    public interface Acceptor
        extends Closeable
    {
        int getPort();

        Connection accept(boolean close) throws IOException;

        Connection accept() throws IOException;
    }

    /**
     * Represents the accepted connection.
     */
    public interface Connection
        extends Closeable
    {
        InputStream getInput();

        OutputStream getOutput();
    }

    public Acceptor call() throws IOException {
        return new AcceptorImpl();
    }

    protected void customize(final ServerSocket serverSocket) throws SocketException {
        assert serverSocket != null;
        serverSocket.setSoTimeout(DEFAULT_SO_TIMEOUT);
    }

    // TODO: Document behavior on both sides of channel so its easier to comprehend whats going on here

    private class AcceptorImpl
        implements Acceptor, Serializable
    {
        private static final long serialVersionUID = 1L;

        private transient final ServerSocket serverSocket;

        public AcceptorImpl() throws IOException {
            serverSocket = new ServerSocket();
            serverSocket.bind(null);
            customize(serverSocket);
            log.debug("Created acceptor");
        }

        public Connection accept(final boolean close) throws IOException {
            log.debug("Accepting");
            Socket socket = serverSocket.accept();
            log.debug("Accepted: {}", socket);
            if (close) {
                close();
            }
            return new ConnectionImpl(socket);
        }

        public Connection accept() throws IOException {
            return accept(false);
        }

        public void close() throws IOException {
            log.debug("Closing");
            serverSocket.close();
        }

        public int getPort() {
            return serverSocket.getLocalPort();
        }

        /**
         * Executed on remote, returns a proxy.
         */
        private Object writeReplace() {
            return Channel.current().export(Acceptor.class, this);
        }
    }

    private class ConnectionImpl
        implements Connection, Serializable
    {
        private static final long serialVersionUID = 1L;

        private InputStream input;

        private OutputStream output;

        public ConnectionImpl(final InputStream input, final OutputStream output) {
            assert input != null;
            this.input = input;
            assert output != null;
            this.output = output;
            log.debug("Created connection");
        }

        private ConnectionImpl(final Socket socket) throws IOException {
            // assert socket != null
            this(new SocketInputStream(socket), new SocketOutputStream(socket));
            // TODO: How to close the socket?
        }

        public InputStream getInput() {
            return input;
        }

        public OutputStream getOutput() {
            return output;
        }

        public void close() throws IOException {
            // FIXME: nop for now, trying to close the streams causes problems
        }

        /**
         * Executed on remote, returns connection wrapper with remote streams.
         */
        private Object writeReplace() {
            return new ConnectionImpl(new RemoteInputStream(input), new RemoteOutputStream(output));
        }

        /**
         * Re-establishes buffering.
         */
        private Object readResolve() {
            this.input = new BufferedInputStream(input);
            this.output = new BufferedOutputStream(output);
            return this;
        }
    }
}
TOP

Related Classes of org.hudsonci.utils.tasks.OpenServerSocket$Connection

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.