geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jdil...@apache.org
Subject svn commit: r578538 - in /geronimo/sandbox/gshell/trunk/gshell-remote: gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/ gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/ gshell-remote-common/src/m...
Date Sun, 23 Sep 2007 02:24:56 GMT
Author: jdillon
Date: Sat Sep 22 19:24:55 2007
New Revision: 578538

URL: http://svn.apache.org/viewvc?rev=578538&view=rev
Log:
Adding session state holder on the client and server side to track all the bits we need to...
um track

Added:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
  (with props)
Modified:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientHandler.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/rsh/ConnectMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Request.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/RequestManager.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Requestor.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/session/SessionAttributeBinder.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/Transport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/base/BaseTransport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShellContainer.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerHandler.java

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java
Sat Sep 22 19:24:55 2007
@@ -27,9 +27,9 @@
 import org.apache.geronimo.gshell.remote.crypto.CryptoContext;
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.remote.message.rsh.CloseShellMessage;
+import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.EchoMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.ExecuteMessage;
-import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.LoginMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.OpenShellMessage;
 import org.apache.geronimo.gshell.remote.transport.Transport;
@@ -94,7 +94,7 @@
 
         response = transport.request(new ConnectMessage(crypto.getPublicKey()));
 
-        PublicKey serverKey = ((ConnectMessage.Result)response).getClientKey();
+        PublicKey serverKey = ((ConnectMessage.Result)response).getPublicKey();
 
         log.debug("Logging in: {}", username);
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientHandler.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientHandler.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientHandler.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientHandler.java
Sat Sep 22 19:24:55 2007
@@ -19,9 +19,14 @@
 
 package org.apache.geronimo.gshell.remote.client;
 
+import java.util.UUID;
+
+import org.apache.geronimo.gshell.common.tostring.ToStringBuilder;
+import org.apache.geronimo.gshell.common.tostring.ToStringStyle;
 import org.apache.geronimo.gshell.remote.message.MessageHandler;
 import org.apache.geronimo.gshell.remote.message.MessageVisitorSupport;
 import org.apache.geronimo.gshell.remote.message.rsh.EchoMessage;
+import org.apache.geronimo.gshell.remote.session.SessionAttributeBinder;
 import org.apache.mina.common.IoSession;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
@@ -43,6 +48,54 @@
         setVisitor(new Visitor());
     }
 
+    @Override
+    public void sessionClosed(final IoSession session) throws Exception {
+        assert session != null;
+
+        SessionState state = SESSION_STATE.unbind(session);
+
+        // If there is still state bound then clean it up
+        if (state != null) {
+            log.warn("Delinquent state detected: {}", state);
+
+            try {
+                state.destroy();
+            }
+            catch (Exception e) {
+                log.warn("Failed to clean up after delinquent state", e);
+            }
+        }
+    }
+
+    //
+    // SessionState
+    //
+
+    /**
+     * Session binding helper for {@link SessionState} instances.
+     */
+    private static final SessionAttributeBinder<SessionState> SESSION_STATE = new SessionAttributeBinder<SessionState>(SessionState.class);
+
+    /**
+     * Container for various bits of client state we are tracking.
+     */
+    private class SessionState
+    {
+        public final UUID id;
+
+        public SessionState(final UUID id) {
+            this.id = id;
+        }
+        
+        public void destroy() {}
+
+        public String toString() {
+            return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+                    .append("id", id)
+                    .toString();
+        }
+    }
+    
     //
     // MessageVisitor
     //

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
Sat Sep 22 19:24:55 2007
@@ -24,9 +24,9 @@
 import java.util.Set;
 
 import org.apache.geronimo.gshell.remote.message.rsh.CloseShellMessage;
+import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.EchoMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.ExecuteMessage;
-import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.LoginMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.OpenShellMessage;
 import org.apache.geronimo.gshell.remote.stream.WriteStreamMessage;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java
Sat Sep 22 19:24:55 2007
@@ -20,9 +20,9 @@
 package org.apache.geronimo.gshell.remote.message;
 
 import org.apache.geronimo.gshell.remote.message.rsh.CloseShellMessage;
+import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.EchoMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.ExecuteMessage;
-import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.LoginMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.OpenShellMessage;
 import org.apache.geronimo.gshell.remote.session.SessionAttributeBinder;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java
Sat Sep 22 19:24:55 2007
@@ -20,11 +20,11 @@
 package org.apache.geronimo.gshell.remote.message;
 
 import org.apache.geronimo.gshell.remote.message.rsh.CloseShellMessage;
+import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.EchoMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.ExecuteMessage;
-import org.apache.geronimo.gshell.remote.message.rsh.OpenShellMessage;
-import org.apache.geronimo.gshell.remote.message.rsh.ConnectMessage;
 import org.apache.geronimo.gshell.remote.message.rsh.LoginMessage;
+import org.apache.geronimo.gshell.remote.message.rsh.OpenShellMessage;
 import org.apache.mina.common.IoSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,8 +41,6 @@
     // FIXME: Abstract me...
     //
     
-    protected final Logger log = LoggerFactory.getLogger(getClass());
-
     protected MessageVisitorSupport() {}
 
     public void visitConnect(IoSession session, ConnectMessage msg) throws Exception {}

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/rsh/ConnectMessage.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/rsh/ConnectMessage.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/rsh/ConnectMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/rsh/ConnectMessage.java
Sat Sep 22 19:24:55 2007
@@ -20,6 +20,7 @@
 package org.apache.geronimo.gshell.remote.message.rsh;
 
 import java.security.PublicKey;
+import java.util.UUID;
 
 import org.apache.geronimo.gshell.remote.marshall.Marshaller;
 import org.apache.geronimo.gshell.remote.message.CryptoAwareMessageSupport;
@@ -37,12 +38,12 @@
     extends CryptoAwareMessageSupport
     implements HandshakeMessage
 {
-    private PublicKey clientKey;
+    private PublicKey publicKey;
 
-    protected ConnectMessage(final MessageType type, final PublicKey clientKey) {
+    protected ConnectMessage(final MessageType type, final PublicKey publicKey) {
         super(type);
 
-        this.clientKey = clientKey;
+        this.publicKey = publicKey;
     }
 
     public ConnectMessage(final PublicKey clientKey) {
@@ -53,16 +54,16 @@
         this(null);
     }
 
-    public PublicKey getClientKey() {
-        if (clientKey == null) {
-            throw new IllegalStateException("Missing client key");
+    public PublicKey getPublicKey() {
+        if (publicKey == null) {
+            throw new IllegalStateException("Missing public key");
         }
 
-        return clientKey;
+        return publicKey;
     }
 
-    public void setClientKey(final PublicKey clientKey) {
-        this.clientKey = clientKey;
+    public void setPublicKey(final PublicKey publicKey) {
+        this.publicKey = publicKey;
     }
 
     public void process(final IoSession session, final MessageVisitor visitor) throws Exception
{
@@ -80,7 +81,7 @@
             throw new IllegalStateException();
         }
 
-        clientKey = getCryptoContext().deserializePublicKey(bytes);
+        publicKey = getCryptoContext().deserializePublicKey(bytes);
     }
 
     public void writeExternal(final ByteBuffer out) throws Exception {
@@ -88,21 +89,45 @@
 
         super.writeExternal(out);
 
-        Marshaller.writeBytes(out, getClientKey().getEncoded());
+        Marshaller.writeBytes(out, getPublicKey().getEncoded());
     }
 
     /**
-     * Reply from server to client which contains the server's public key.
+     * Indicates the first part of the connection handshake was successful.
      */
     public static class Result
         extends ConnectMessage
     {
-        public Result(final PublicKey publicKey) {
-            super(MessageType.CONNECT_RESULT, publicKey);
+        private UUID clientId;
+
+        public Result(final UUID clientId, final PublicKey serverKey) {
+            super(MessageType.CONNECT_RESULT, serverKey);
+
+            this.clientId = clientId;
         }
 
         public Result() {
-            this(null);
+            this(null, null);
+        }
+
+        public UUID getClientID() {
+            return clientId;
+        }
+
+        public void readExternal(final ByteBuffer in) throws Exception {
+            assert in != null;
+
+            super.readExternal(in);
+
+            clientId = Marshaller.readUuid(in);
+        }
+
+        public void writeExternal(final ByteBuffer out) throws Exception {
+            assert out != null;
+
+            super.writeExternal(out);
+
+            Marshaller.writeUuid(out, clientId);
         }
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Request.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Request.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Request.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Request.java
Sat Sep 22 19:24:55 2007
@@ -29,9 +29,9 @@
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import org.apache.geronimo.gshell.common.Duration;
 import org.apache.geronimo.gshell.common.tostring.ToStringBuilder;
 import org.apache.geronimo.gshell.common.tostring.ToStringStyle;
-import org.apache.geronimo.gshell.common.Duration;
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/RequestManager.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/RequestManager.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/RequestManager.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/RequestManager.java
Sat Sep 22 19:24:55 2007
@@ -28,10 +28,10 @@
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-import org.apache.geronimo.gshell.common.tostring.ToStringBuilder;
-import org.apache.geronimo.gshell.common.tostring.ToStringStyle;
 import org.apache.geronimo.gshell.common.Duration;
 import org.apache.geronimo.gshell.common.NamedThreadFactory;
+import org.apache.geronimo.gshell.common.tostring.ToStringBuilder;
+import org.apache.geronimo.gshell.common.tostring.ToStringStyle;
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.remote.session.SessionAttributeBinder;
 import org.slf4j.Logger;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Requestor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Requestor.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Requestor.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/request/Requestor.java
Sat Sep 22 19:24:55 2007
@@ -21,9 +21,9 @@
 
 import java.util.concurrent.TimeUnit;
 
+import org.apache.geronimo.gshell.common.Duration;
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.remote.transport.Transport;
-import org.apache.geronimo.gshell.common.Duration;
 import org.apache.mina.common.IoFutureListener;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.common.WriteFuture;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/session/SessionAttributeBinder.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/session/SessionAttributeBinder.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/session/SessionAttributeBinder.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/session/SessionAttributeBinder.java
Sat Sep 22 19:24:55 2007
@@ -44,6 +44,12 @@
         this(type.getName() + "." + suffix);
     }
 
+    public boolean isBound(final IoSession session) {
+        assert session != null;
+        
+        return session.containsAttribute(key);
+    }
+
     @SuppressWarnings({"unchecked"})
     public T lookup(final IoSession session) {
         assert session != null;
@@ -51,7 +57,7 @@
         T obj = (T) session.getAttribute(key);
 
         if (obj == null) {
-            throw new IllegalStateException(key + " not bound");
+            throw new NotBoundException(key);
         }
 
         return obj;
@@ -70,19 +76,21 @@
         return obj;
     }
 
-    public void bind(final IoSession session, final T obj) {
+    public T bind(final IoSession session, final T obj) {
         assert session != null;
         assert obj != null;
         
         Object prev = session.getAttribute(key);
 
         if (prev != null) {
-            throw new IllegalStateException(key + " already bound");
+            throw new AlreadyBoundException(key);
         }
 
         session.setAttribute(key, obj);
-    }
 
+        return obj;
+    }
+    
     @SuppressWarnings({"unchecked"})
     public T rebind(final IoSession session, final T obj) {
         assert session != null;
@@ -100,5 +108,21 @@
         assert session != null;
 
         return (T) session.removeAttribute(key);
+    }
+
+    public static class NotBoundException
+        extends RuntimeException
+    {
+        public NotBoundException(final String key) {
+            super(key);
+        }
+    }
+
+    public static class AlreadyBoundException
+        extends RuntimeException
+    {
+        public AlreadyBoundException(final String key) {
+            super(key);
+        }
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/Transport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/Transport.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/Transport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/Transport.java
Sat Sep 22 19:24:55 2007
@@ -24,8 +24,8 @@
 import java.net.URI;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.common.Duration;
+import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.mina.common.IoService;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.common.WriteFuture;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/base/BaseTransport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/base/BaseTransport.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/base/BaseTransport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/base/BaseTransport.java
Sat Sep 22 19:24:55 2007
@@ -26,6 +26,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.geronimo.gshell.common.Duration;
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.remote.message.MessageHandler;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
@@ -34,7 +35,6 @@
 import org.apache.geronimo.gshell.remote.stream.SessionInputStream;
 import org.apache.geronimo.gshell.remote.stream.SessionOutputStream;
 import org.apache.geronimo.gshell.remote.transport.Transport;
-import org.apache.geronimo.gshell.common.Duration;
 import org.apache.mina.common.CloseFuture;
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoConnector;

Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java?rev=578538&view=auto
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
(added)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
Sat Sep 22 19:24:55 2007
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.geronimo.gshell.remote.server;
+
+import org.apache.geronimo.gshell.command.IO;
+import org.apache.geronimo.gshell.remote.stream.SessionInputStream;
+import org.apache.geronimo.gshell.remote.stream.SessionOutputStream;
+import org.apache.mina.common.IoSession;
+
+/**
+ * Container for <em>remote</em> input/output handles.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class RemoteIO
+    extends IO
+{
+    public RemoteIO(final IoSession session) {
+        super(SessionInputStream.BINDER.lookup(session), SessionOutputStream.BINDER.lookup(session),
false);
+    }
+}

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteIO.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShellContainer.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShellContainer.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShellContainer.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShellContainer.java
Sat Sep 22 19:24:55 2007
@@ -19,13 +19,17 @@
 
 package org.apache.geronimo.gshell.remote.server;
 
+import java.util.UUID;
+
 import org.apache.geronimo.gshell.remote.session.SessionAttributeBinder;
 import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
 import org.codehaus.plexus.DefaultPlexusContainer;
 import org.codehaus.plexus.PlexusContainerException;
+import org.codehaus.plexus.classworlds.ClassWorld;
 
 /**
- * ???
+ * Extended Plexus container to access internals to manage state as needed.
  *
  * @version $Rev$ $Date$
  */
@@ -40,5 +44,24 @@
 
     public void disposeAllComponents() {
         super.disposeAllComponents();
+    }
+
+    //
+    // Factory Access
+    //
+
+    public static RemoteShellContainer create(final ClassWorld classWorld) throws PlexusContainerException
{
+        assert classWorld != null;
+
+        //
+        // TODO: Setup some more reasonable configuration, like logging settings and such...
+        //       also may want to provide a plexus.xml for this puppy to read er something?
+        //
+        
+        ContainerConfiguration config = new DefaultContainerConfiguration();
+        config.setName("gshell.remote-shell:" + UUID.randomUUID());
+        config.setClassWorld(classWorld);
+
+        return new RemoteShellContainer(config);
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerHandler.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerHandler.java?rev=578538&r1=578537&r2=578538&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerHandler.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerHandler.java
Sat Sep 22 19:24:55 2007
@@ -29,10 +29,11 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.geronimo.gshell.DefaultEnvironment;
-import org.apache.geronimo.gshell.command.IO;
 import org.apache.geronimo.gshell.common.Duration;
 import org.apache.geronimo.gshell.common.NamedThreadFactory;
 import org.apache.geronimo.gshell.common.Notification;
+import org.apache.geronimo.gshell.common.tostring.ToStringBuilder;
+import org.apache.geronimo.gshell.common.tostring.ToStringStyle;
 import org.apache.geronimo.gshell.lookup.EnvironmentLookup;
 import org.apache.geronimo.gshell.lookup.IOLookup;
 import org.apache.geronimo.gshell.remote.RemoteShell;
@@ -48,14 +49,11 @@
 import org.apache.geronimo.gshell.remote.message.rsh.OpenShellMessage;
 import org.apache.geronimo.gshell.remote.server.auth.UserAuthenticator;
 import org.apache.geronimo.gshell.remote.session.SessionAttributeBinder;
-import org.apache.geronimo.gshell.remote.stream.SessionInputStream;
 import org.apache.geronimo.gshell.remote.stream.SessionOutputStream;
 import org.apache.geronimo.gshell.shell.Environment;
 import org.apache.mina.common.IoSession;
-import org.codehaus.plexus.ContainerConfiguration;
-import org.codehaus.plexus.DefaultContainerConfiguration;
 import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.PlexusContainerException;
+import org.codehaus.plexus.classworlds.ClassWorld;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
@@ -71,18 +69,10 @@
     extends MessageHandler
     implements Initializable
 {
-    //
-    // TODO: Introduce a context object which we can stuff any kinda of data we want into
for the client connection... and have one binder, etc...
-    //
-
-    private static final SessionAttributeBinder<PublicKey> CLIENT_KEY_BINDER = new
SessionAttributeBinder<PublicKey>(RshServerHandler.class, "clientpk");
-
-    private static final SessionAttributeBinder<UUID> SECTOKEN = new SessionAttributeBinder<UUID>(RshServerHandler.class,
"sectoken");
-
-    private static final SessionAttributeBinder<ScheduledFuture> TIMEOUT_BINDER = new
SessionAttributeBinder<ScheduledFuture>(RshServerHandler.class, "timeout");
-
     @Requirement
-    private PlexusContainer parentContainer;
+    private PlexusContainer container;
+
+    private ClassWorld classWorld;
 
     @Requirement
     private CryptoContext crypto;
@@ -92,16 +82,20 @@
 
     private ScheduledThreadPoolExecutor scheduler;
 
-    private UUID securityToken;
+    private final UUID securityToken = UUID.randomUUID();
 
     public void initialize() throws InitializationException {
         setVisitor(new Visitor());
 
-        ThreadFactory tf = new NamedThreadFactory(getClass());
+        //
+        // FIXME: I'm not sure this is really the correct thing to be doing... but I need
a classworld to
+        //        to boot up remote shell containers... so we steal it from here.
+        //
 
-        scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
tf);
+        classWorld = container.getContainerRealm().getWorld();
 
-        securityToken = UUID.randomUUID();
+        ThreadFactory tf = new NamedThreadFactory(getClass());
+        scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
tf);
     }
 
     @Override
@@ -109,7 +103,26 @@
         assert session != null;
 
         // Schedule a task to timeout the handshake process
-        scheduleTimeout(session);
+        scheduleTimeout(session, AUTH_TIMEOUT);
+    }
+
+    @Override
+    public void sessionClosed(final IoSession session) throws Exception {
+        assert session != null;
+
+        SessionState state = SESSION_STATE.unbind(session);
+
+        // If there is still state bound then clean it up
+        if (state != null) {
+            log.warn("Delinquent state detected: {}", state);
+
+            try {
+                state.destroy();
+            }
+            catch (Exception e) {
+                log.warn("Failed to clean up after delinquent state", e);
+            }
+        }
     }
 
     @Override
@@ -117,77 +130,90 @@
         assert session != null;
         assert obj != null;
 
-        UUID token = SECTOKEN.lookup(session, null);
+        SessionState state = SESSION_STATE.lookup(session, null);
+
+        if (state != null && securityToken.equals(state.sectoken)) {
+            log.debug("Message is already authenticated");
 
-        if (securityToken.equals(token)) {
             super.messageReceived(session, obj);
         }
         else if (obj instanceof HandshakeMessage) {
+            log.debug("Message requires handshake/authentication");
+
             super.messageReceived(session, obj);
         }
         else {
             // If we get to here, then the message is not valid, so complain, then kill the
session
-            log.error("Unauthenticated message: {}", obj);
+            log.error("Invalid message: {}", obj);
+
+            //
+            // TODO: See if we can just toss an IOException here instead?
+            //
 
             session.close();
         }
     }
 
     //
-    // Timeout Support
+    // SessionState
     //
 
-    //
-    // TODO: Move this timeout stuff to a component, a few things need this functionality,
probably more than I can think of too..
-    //
-    
-    private static final Duration AUTH_TIMEOUT = new Duration(15, TimeUnit.SECONDS);
+    /**
+     * Session binding helper for {@link SessionState} instances.
+     */
+    private static final SessionAttributeBinder<SessionState> SESSION_STATE = new SessionAttributeBinder<SessionState>(SessionState.class);
+
+    /**
+     * Container for various bits of state we are tracking.
+     */
+    private class SessionState
+    {
+        /** The remote client's unique identifier. */
+        public final UUID id = UUID.randomUUID();
 
-    private ScheduledFuture scheduleTimeout(final IoSession session, final Duration timeout)
{
-        assert session != null;
-        assert timeout != null;
+        /** The remove client's public key. */
+        public PublicKey pk;
 
-        Runnable task = new Runnable() {
-            public void run() {
-                log.error("Timeout waiting for handshake or authentication from: {}", session.getRemoteAddress());
-                
-                session.close();
-            }
-        };
+        /** The shared security token */
+        public UUID sectoken;
 
-        ScheduledFuture tf = scheduler.schedule(task, timeout.value, timeout.unit);
+        /** The remote client's logged in username. */
+        public String username;
 
-        TIMEOUT_BINDER.rebind(session, tf);
+        /** The container which the remote shell is running in. */
+        public RemoteShellContainer container;
 
-        return tf;
-    }
+        /** The I/O context for the remote shell. */
+        public RemoteIO io;
 
-    private ScheduledFuture scheduleTimeout(final IoSession session) {
-        return scheduleTimeout(session, AUTH_TIMEOUT);
-    }
+        /** The environment for the remote shell. */
+        public Environment env;
 
-    private boolean cancelTimeout(final IoSession session) {
-        assert session != null;
+        /** The remote shell instance. */
+        public RemoteShell shell;
 
-        ScheduledFuture tf = TIMEOUT_BINDER.lookup(session);
+        public void destroy() {
+            shell.close();
 
-        return tf.cancel(false);
+            container.disposeAllComponents();
+        }
+
+        public int hashCode() {
+            return id.hashCode();
+        }
+
+        public String toString() {
+            return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+                    .append("id", id)
+                    .append("username", username)
+                    .toString();
+        }
     }
 
     //
     // MessageVisitor
     //
 
-    //
-    // TODO: Introduce a context object which we can stuff any kinda of data we want into
for the remote shell session... and have one binder, etc...
-    //
-
-    private static final SessionAttributeBinder<IO> IO_BINDER = new SessionAttributeBinder<IO>(IO.class);
-
-    private static final SessionAttributeBinder<Environment> ENV_BINDER = new SessionAttributeBinder<Environment>(Environment.class);
-
-    private static final SessionAttributeBinder<RemoteShell> SHELL_BINDER = new SessionAttributeBinder<RemoteShell>(RemoteShell.class);
-
     private class Visitor
         extends MessageVisitorSupport
     {
@@ -204,20 +230,23 @@
                 log.warn("Aborting handshake processing; timeout has triggered");
             }
             else {
-                PublicKey key = msg.getClientKey();
+                // Setup the initial client state
+                SessionState state = SESSION_STATE.bind(session, new SessionState());
 
-                // Stuff the remote public key into the session
-                CLIENT_KEY_BINDER.bind(session, key);
+                log.info("Initiating state for client: {}", state.id);
 
                 //
-                // TODO: Do we want to pass the client back some token which it needs to
put onto messages that are sent for more security?
+                // TODO: Should we track anything else from the session in our state, like
the address or something?
                 //
+                
+                // Hold on to the client's public key
+                state.pk = msg.getPublicKey();
 
-                // And then send back our public key to the remote client
-                msg.reply(new ConnectMessage.Result(crypto.getPublicKey()));
+                // Reply to the client with some details about the connection
+                msg.reply(new ConnectMessage.Result(state.id, crypto.getPublicKey()));
 
                 // Schedule a task to timeout the login process
-                scheduleTimeout(session);
+                scheduleTimeout(session, AUTH_TIMEOUT);
             }
         }
 
@@ -231,6 +260,7 @@
             }
             else {
                 String username = msg.getUsername();
+
                 String password = msg.getPassword();
 
                 if (!userAuthenticator.authenticate(username, password)) {
@@ -241,9 +271,14 @@
                     msg.reply(new LoginMessage.Failure(reason));
                 }
                 else {
-                    // Mark the session as authenticated
-                    SECTOKEN.bind(session, securityToken);
+                    SessionState state = SESSION_STATE.lookup(session);
+
+                    // Mark the session as authenticated (which is done by setting the sectoken)
+                    state.sectoken = securityToken;
 
+                    // Remember our username
+                    state.username = username;
+                    
                     log.info("Successfull authentication for user: {}, at location: {}",
username, session.getRemoteAddress());
 
                     msg.reply(new LoginMessage.Success());
@@ -255,44 +290,25 @@
         // Remote Shell Session
         //
 
-        private RemoteShellContainer createContainer() throws PlexusContainerException {
-            // Create a new container which will be the parent for our remote shells
-            ContainerConfiguration config = new DefaultContainerConfiguration();
-
-            String name = "gshell.remote-shell:" + UUID.randomUUID();
-
-            config.setName(name);
-
-            config.setClassWorld(parentContainer.getContainerRealm().getWorld());
-
-            return new RemoteShellContainer(config);
-        }
-
         @Override
         public void visitOpenShell(final IoSession session, final OpenShellMessage msg) throws
Exception {
             log.info("OPEN SHELL: {}", msg);
 
-            RemoteShellContainer shellContainer = createContainer();
-            RemoteShellContainer.BINDER.bind(session, shellContainer);
-
-            // Setup the I/O context (w/o auto-flushing)
-            IO io = new IO(SessionInputStream.BINDER.lookup(session), SessionOutputStream.BINDER.lookup(session),
false);
+            SessionState state = SESSION_STATE.lookup(session);
 
-            //
-            // TODO: We need to set the verbosity of this I/O context as specified by the
client
-            //
+            // Create a new container which will be the parent for our remote shells
+            state.container = RemoteShellContainer.create(classWorld);
 
-            IOLookup.set(shellContainer, io);
-            IO_BINDER.bind(session, io);
+            // Setup the I/O context (w/o auto-flushing)
+            state.io = new RemoteIO(session);
+            IOLookup.set(state.container, state.io);
 
             // Setup shell environemnt
-            Environment env = new DefaultEnvironment(io);
-            EnvironmentLookup.set(shellContainer, env);
-            ENV_BINDER.bind(session, env);
+            state.env = new DefaultEnvironment(state.io);
+            EnvironmentLookup.set(state.container, state.env);
 
             // Create a new shell instance
-            RemoteShell shell = (RemoteShell) shellContainer.lookup(RemoteShell.class);
-            SHELL_BINDER.bind(session, shell);
+            state.shell = (RemoteShell) state.container.lookup(RemoteShell.class);
 
             //
             // TODO: Send a meaningful response
@@ -305,22 +321,13 @@
         public void visitCloseShell(final IoSession session, final CloseShellMessage msg)
throws Exception {
             log.info("CLOSE SHELL: {}", msg);
 
-            log.info("Closing shell");
-
-            RemoteShell shell = SHELL_BINDER.unbind(session);
-
-            shell.close();
-
-            log.info("Unbinding resources");
+            SessionState state = SESSION_STATE.unbind(session);
 
-            IO_BINDER.unbind(session);
-
-            ENV_BINDER.unbind(session);
-
-            log.info("Destroying container");
-
-            RemoteShellContainer shellContainer = RemoteShellContainer.BINDER.unbind(session);
-            shellContainer.disposeAllComponents();
+            //
+            // TODO: This should just clean up the bits related to shell muck...
+            //
+            
+            state.destroy();
 
             //
             // TODO: Send a meaningful response
@@ -337,22 +344,14 @@
         public void visitExecute(final IoSession session, final ExecuteMessage msg) throws
Exception {
             log.info("EXECUTE: {}", msg);
 
-            RemoteShell shell = SHELL_BINDER.lookup(session);
+            SessionState state = SESSION_STATE.lookup(session);
 
-            try {
-                //
-                // TODO: Need to find a better place to stash this me thinks...
-                //
+            // Need to make sure that the execuing thread has the right I/O and environment
in context
+            IOLookup.set(state.container, state.io);
+            EnvironmentLookup.set(state.container, state.env);
 
-                RemoteShellContainer shellContainer = RemoteShellContainer.BINDER.lookup(session);
-
-                IO io = IO_BINDER.lookup(session);
-                IOLookup.set(shellContainer, io);
-
-                Environment env = ENV_BINDER.lookup(session);
-                EnvironmentLookup.set(shellContainer, env);
-
-                Object result = msg.execute(shell);
+            try {
+                Object result = msg.execute(state.shell);
 
                 log.debug("Result: {}", result);
 
@@ -410,5 +409,44 @@
                 msg.reply(new EchoMessage(text));
             }
         }
+    }
+
+    //
+    // Timeout Support
+    //
+
+    //
+    // TODO: Move this timeout stuff to a component, a few things need this functionality,
probably more than I can think of too..
+    //
+
+    private static final SessionAttributeBinder<ScheduledFuture> TIMEOUT_BINDER = new
SessionAttributeBinder<ScheduledFuture>(RshServerHandler.class, "timeout");
+
+    private static final Duration AUTH_TIMEOUT = new Duration(10, TimeUnit.SECONDS);
+
+    private ScheduledFuture scheduleTimeout(final IoSession session, final Duration timeout)
{
+        assert session != null;
+        assert timeout != null;
+
+        Runnable task = new Runnable() {
+            public void run() {
+                log.error("Timeout waiting for handshake or authentication from: {}", session.getRemoteAddress());
+
+                session.close();
+            }
+        };
+
+        ScheduledFuture tf = scheduler.schedule(task, timeout.value, timeout.unit);
+
+        TIMEOUT_BINDER.rebind(session, tf);
+
+        return tf;
+    }
+
+    private boolean cancelTimeout(final IoSession session) {
+        assert session != null;
+
+        ScheduledFuture tf = TIMEOUT_BINDER.lookup(session);
+
+        return tf.cancel(false);
     }
 }



Mime
View raw message