geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jdil...@apache.org
Subject svn commit: r577065 - 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/crypto/ gshell-remote-common/src/ma...
Date Tue, 18 Sep 2007 21:04:37 GMT
Author: jdillon
Date: Tue Sep 18 14:04:33 2007
New Revision: 577065

URL: http://svn.apache.org/viewvc?rev=577065&view=rev
Log:
More bits to get the remote shell crapo working, can execute remote commands now, and the
result is passed back, as well as any exceptions as faults
Still having some problem getting the IO briding crapo to work, some simple commands like
"echo foo" will work, and write back to the client's IO now...
but it will freakout after a while... not sure why... blah
Have to give each remoteshell its own fresh container to avoid pulling in unwanted components
from the invoking shell
Have to invoke remoteshell's execute() bits in a seperate thread to prevent the message system
from blocking up
And other stuff that is related

Modified:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java
    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-common/src/main/java/org/apache/geronimo/gshell/remote/crypto/CryptoContext.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CloseShellMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/ExecuteMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.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/MessageVisitorSupport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/OpenShellMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/WriteStreamMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.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/RemoteShellProxy.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java
Tue Sep 18 14:04:33 2007
@@ -23,6 +23,7 @@
 
 import jline.Terminal;
 import org.apache.geronimo.gshell.ExitNotification;
+import org.apache.geronimo.gshell.remote.stream.StreamFeeder;
 import org.apache.geronimo.gshell.ansi.Renderer;
 import org.apache.geronimo.gshell.command.IO;
 import org.apache.geronimo.gshell.console.Console;
@@ -49,6 +50,8 @@
 
     private Terminal terminal;
 
+    private StreamFeeder outputFeeder;
+
     private boolean opened;
 
     public RemoteShellProxy(final RshClient client, final IO io, final Terminal terminal)
throws Exception {
@@ -61,13 +64,17 @@
         this.terminal = terminal;
 
         //
-        // TODO: send over some client-side details, like the terminal features, etc)
+        // TODO: send over some client-side details, like the terminal features, etc, as
well, verbosity too)
         //       If any problem or denial occurs, throw an exception, once created the proxy
is considered valid.
         //
         
         client.openShell();
 
-        this.opened = true;
+        // Copy the client's input stream to our outputstream so users see command output
+        outputFeeder = new StreamFeeder(client.getInputStream(), io.outputStream);
+        outputFeeder.createThread().start();
+
+        this.opened = true;             
     }
 
     public Environment getEnvironment() {
@@ -94,6 +101,8 @@
 
     public void close() {
         try {
+            outputFeeder.close();
+
             client.closeShell();
         }
         catch (Exception e) {
@@ -139,6 +148,10 @@
         log.debug("Starting interactive console; args: {}", args);
 
         //
+        // FIXME: We need a hook into the session state here so that we can abort the console
muck when the session closes
+        //
+        
+        //
         // TODO: Request server to load...
         //
         // loadUserScript(branding.getInteractiveScriptName());
@@ -190,6 +203,9 @@
                 //
                 // FIXME:
                 //
+                
+                log.error("FIXME: " + error, error);
+
 
                 return Result.CONTINUE;
             }

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=577065&r1=577064&r2=577065&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
Tue Sep 18 14:04:33 2007
@@ -74,6 +74,7 @@
         log.info("Starting handshake", username);
 
         HandShakeMessage.Result handShakeResult = (HandShakeMessage.Result) transport.request(new
HandShakeMessage(crypto.getPublicKey()));
+        
         PublicKey serverKey = handShakeResult.getPublicKey();
 
         log.info("Logging in: {}", username);
@@ -104,48 +105,53 @@
 
         log.info("Response: {}", resp);
     }
-    
-    public Object execute(final String line) throws Exception {
-        assert line != null;
 
-        log.info("Executing: {}", line);
+    private Object doExecute(final ExecuteMessage msg) throws Exception {
+        assert msg != null;
+
+        ExecuteMessage.Result result = (ExecuteMessage.Result) transport.request(msg);
 
-        transport.send(new ExecuteMessage(line));
+        // Handle result faults
+        if (result instanceof ExecuteMessage.Fault) {
+            ExecuteMessage.Fault fault = (ExecuteMessage.Fault)result;
 
-        //
-        // TODO: Need to handle the command result
-        //
+            //
+            // FIXME: Use better exception type here
+            //
+            
+            throw new Exception("Remote command execution fault", fault.getCause());
+        }
 
-        return null;
+        Object rv = result.getResult();
+
+        log.info("Command result: {}", rv);
+
+        return rv;
     }
 
-    public Object execute(final Object... args) throws Exception {
-        assert args != null;
+    public Object execute(final String line) throws Exception {
+        assert line != null;
 
-        log.info("Executing: {}", args);
+        log.info("Executing (String): {}", line);
+
+        return doExecute(new ExecuteMessage(line));
+    }
 
-        transport.send(new ExecuteMessage(args));
+    public Object execute(final Object... args) throws Exception {
+        assert args != null;
 
-        //
-        // TODO: Need to handle the command result
-        //
+        log.info("Executing (Object[]): {}", args);
 
-        return null;
+        return doExecute(new ExecuteMessage(args));
     }
 
     public Object execute(final String path, final Object[] args) throws Exception {
         assert path != null;
         assert args != null;
 
-        log.info("Executing: {}, {}", path, args);
-
-        transport.send(new ExecuteMessage(path, args));
-
-        //
-        // TODO: Need to handle the command result
-        //
+        log.info("Executing (String,Object[]): {}, {}", path, args);
 
-        return null;
+        return doExecute(new ExecuteMessage(path, args));
     }
 
     public InputStream getInputStream() {

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/crypto/CryptoContext.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/crypto/CryptoContext.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/crypto/CryptoContext.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/crypto/CryptoContext.java
Tue Sep 18 14:04:33 2007
@@ -29,6 +29,8 @@
 import javax.crypto.Cipher;
 
 import org.codehaus.plexus.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Provides an abstraction of the crypto bits which are required for some remote shell communications.
@@ -38,6 +40,8 @@
 @Component(role= CryptoContext.class)
 public class CryptoContext
 {
+    private Logger log = LoggerFactory.getLogger(getClass());
+    
     //
     // TODO: See if we should use DSA or RSA for this...
     //

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CloseShellMessage.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/CloseShellMessage.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CloseShellMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CloseShellMessage.java
Tue Sep 18 14:04:33 2007
@@ -33,18 +33,6 @@
         super(MessageType.CLOSE_SHELL);
     }
 
-    public void readExternal(final ByteBuffer in) throws Exception {
-        assert in != null;
-
-        super.readExternal(in);
-    }
-
-    public void writeExternal(final ByteBuffer out) throws Exception {
-        assert out != null;
-
-        super.writeExternal(out);
-    }
-
     public void process(final MessageVisitor visitor) throws Exception {
         assert visitor != null;
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.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/CryptoAwareMessageSupport.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
Tue Sep 18 14:04:33 2007
@@ -57,36 +57,28 @@
     protected String decryptString(final ByteBuffer in) throws Exception {
         assert in != null;
 
-        int len = in.getInt();
-
-        if (len == -1) {
+        byte[] bytes = readBytes(in);
+        
+        if (bytes == null) {
             return null;
         }
-        else {
-            byte[] bytes = new byte[len];
-
-            in.get(bytes);
 
-            bytes = getCryptoContext().decrypt(bytes);
+        bytes = getCryptoContext().decrypt(bytes);
 
-            return new String(bytes);
-        }
+        return new String(bytes);
     }
 
     protected void encryptString(final ByteBuffer out, final Key key, final String str) throws
Exception {
         assert out != null;
         assert key != null;
 
-        if (str == null) {
-            out.putInt(-1);
-        }
-        else {
-            byte[] bytes = getCryptoContext().encrypt(key, str.getBytes());
-
-            out.putInt(bytes.length);
+        byte[] bytes = null;
 
-            out.put(bytes);
+        if (str != null) {
+            bytes = getCryptoContext().encrypt(key, str.getBytes());
         }
+
+        writeBytes(out, bytes);
     }
 
     protected void encryptString(final ByteBuffer out, final String str) throws Exception
{

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/ExecuteMessage.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/ExecuteMessage.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/ExecuteMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/ExecuteMessage.java
Tue Sep 18 14:04:33 2007
@@ -66,10 +66,6 @@
         return flavor.execute(this, executor);
     }
 
-    //
-    // TODO: Optimize this
-    //
-    
     public void readExternal(final ByteBuffer in) throws Exception {
         assert in != null;
 
@@ -79,7 +75,7 @@
 
         this.path = readString(in);
 
-        this.args = (Object[]) in.getObject();
+        this.args = (Object[]) readObject(in);
     }
 
     public void writeExternal(final ByteBuffer out) throws Exception {
@@ -90,8 +86,8 @@
         out.putEnum(flavor);
 
         writeString(out, path);
-        
-        out.putObject(args);
+
+        writeObject(out, args);
     }
 
     public void process(final MessageVisitor visitor) throws Exception {
@@ -104,7 +100,7 @@
     // Flavor
     //
     
-    private enum Flavor
+    private static enum Flavor
     {
         STRING,         // execute(String)
         OBJECTS,        // execute(Object[])
@@ -128,6 +124,70 @@
 
             // This should never happen
             throw new Error();
+        }
+    }
+
+    /**
+     * Container for the normal result of an execute command.
+     */
+    public static class Result
+        extends MessageSupport
+    {
+        private Object result;
+
+        protected Result(final MessageType type, final Object result) {
+            super(type);
+
+            this.result = result;
+        }
+
+        public Result(final Object result) {
+            this(MessageType.EXECUTE_RESULT, result);
+
+            this.result = result;
+        }
+
+        public Result() {
+            this(null, null);
+        }
+
+        public Object getResult() {
+            return result;
+        }
+        
+        public void readExternal(final ByteBuffer in) throws Exception {
+            assert in != null;
+
+            super.readExternal(in);
+
+            result = readObject(in);
+        }
+
+        public void writeExternal(final ByteBuffer out) throws Exception {
+            assert out != null;
+
+            super.writeExternal(out);
+
+            writeObject(out, result);
+        }
+    }
+
+    /**
+     * Container for any exceptions thrown durring execution.
+     */
+    public static class Fault
+        extends Result
+    {
+        public Fault(final Throwable cause) {
+            super(MessageType.EXECUTE_RESULT, cause);
+        }
+
+        public Fault() {
+            this(null);
+        }
+
+        public Throwable getCause() {
+            return (Throwable) getResult();
         }
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.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/HandShakeMessage.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java
Tue Sep 18 14:04:33 2007
@@ -69,18 +69,13 @@
 
         super.readExternal(in);
 
-        int len = in.getInt();
-
-        if (len == -1) {
-            publicKey = null;
+        byte[] bytes = readBytes(in);
+        
+        if (bytes == null) {
+            throw new IllegalStateException();
         }
-        else {
-            byte[] bytes = new byte[len];
-
-            in.get(bytes);
 
-            publicKey = getCryptoContext().deserializePublicKey(bytes);
-        }
+        publicKey = getCryptoContext().deserializePublicKey(bytes);
     }
 
     public void writeExternal(final ByteBuffer out) throws Exception {
@@ -88,16 +83,7 @@
 
         super.writeExternal(out);
 
-        if (publicKey == null) {
-            out.putInt(-1);
-        }
-        else {
-            byte[] bytes = publicKey.getEncoded();
-
-            out.putInt(bytes.length);
-
-            out.put(bytes);
-        }
+        writeBytes(out, getPublicKey().getEncoded());
     }
 
     /**

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.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/LoginMessage.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java
Tue Sep 18 14:04:33 2007
@@ -41,10 +41,10 @@
     private String username;
 
     //
-    // FIXME: Need to update the toString() for this message to omit the passwd
+    // NOTE: Marked as transiet to prevent the ToStringBuilder from displaying its value.
     //
     
-    private String password;
+    private transient String password;
 
     public LoginMessage(final PublicKey serverKey, final String username, final String password)
{
         super(MessageType.LOGIN);

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.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/MessageSupport.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java
Tue Sep 18 14:04:33 2007
@@ -19,7 +19,11 @@
 
 package org.apache.geronimo.gshell.remote.message;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.Charset;
 import java.util.UUID;
@@ -173,6 +177,150 @@
         out.putLong(sequence);
     }
 
+    //
+    // Boolean Serialization
+    //
+
+    private static final byte TRUE = 1;
+
+    private static final byte FALSE = 0;
+
+    protected boolean readBoolean(final ByteBuffer in) {
+        assert in != null;
+
+        byte b = in.get();
+
+        if (b == TRUE) {
+            return true;
+        }
+        else if (b == FALSE) {
+            return false;
+        }
+        else {
+            throw new Error();
+        }
+    }
+
+    protected void writeBoolean(final ByteBuffer out, final boolean bool) {
+        assert out != null;
+
+        if (bool) {
+            out.put(TRUE);
+        }
+        else {
+            out.put(FALSE);
+        }
+    }
+
+    //
+    // Byte[] Serialization
+    //
+
+    protected byte[] readBytes(final ByteBuffer in) {
+        assert in != null;
+
+        boolean isNull = readBoolean(in);
+
+        if (isNull) {
+            return null;
+        }
+
+        int len = in.getInt();
+
+        byte[] bytes = new byte[len];
+
+        in.get(bytes);
+
+        return bytes;
+    }
+
+    protected void writeBytes(final ByteBuffer out, final byte[] bytes) {
+        assert out != null;
+
+        if (bytes == null) {
+            writeBoolean(out, true);
+        }
+        else {
+            writeBoolean(out, false);
+
+            out.putInt(bytes.length);
+
+            out.put(bytes);
+        }
+    }
+
+    //
+    // ByteBuffer Serialization
+    //
+
+    protected ByteBuffer readBuffer(final ByteBuffer in) {
+        assert in != null;
+
+        byte[] bytes = readBytes(in);
+
+        if (bytes == null) {
+            return null;
+        }
+
+        return ByteBuffer.wrap(bytes);
+    }
+
+    protected void writeBuffer(final ByteBuffer out, final ByteBuffer buffer) {
+        assert out != null;
+
+        if (buffer == null) {
+            writeBytes(out, null);
+        }
+        else {
+            writeBoolean(out, false);
+            
+            out.putInt(buffer.remaining());
+
+            out.put(buffer);
+        }
+    }
+
+    //
+    // Object Serialization
+    //
+
+    protected Object readObject(final ByteBuffer in) throws IOException, ClassNotFoundException
{
+        assert in != null;
+
+        byte[] bytes = readBytes(in);
+
+        if (bytes == null) {
+            return null;
+        }
+        
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+
+        return ois.readObject();
+    }
+
+    protected void writeObject(final ByteBuffer out, final Object obj) throws IOException
{
+        assert out != null;
+
+        byte[] bytes = null;
+
+        if (obj != null) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+            oos.writeObject(obj);
+            oos.flush();
+
+            bytes = baos.toByteArray();
+        }
+
+        writeBytes(out, bytes);
+    }
+
+    //
+    // String Serialization
+    //
+
     private static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
 
     protected String readString(final ByteBuffer in) throws CharacterCodingException {
@@ -183,9 +331,8 @@
         if (len == -1) {
             return null;
         }
-        else {
-            return in.getString(len, UTF_8_CHARSET.newDecoder());
-        }
+
+        return in.getString(len, UTF_8_CHARSET.newDecoder());
     }
 
     protected void writeString(final ByteBuffer out, final String str) throws CharacterCodingException
{
@@ -202,32 +349,38 @@
         }
     }
 
-    private void writeUuid(final ByteBuffer out, final UUID uuid) throws Exception {
-        assert out != null;
+    //
+    // UUID Serialization
+    //
 
-        if (uuid == null) {
-            out.put((byte)0);
-        }
-        else {
-            out.put((byte)1);
+    protected UUID readUuid(final ByteBuffer in) throws Exception {
+        assert in != null;
 
-            out.putLong(uuid.getMostSignificantBits());
-            out.putLong(uuid.getLeastSignificantBits());
+        boolean isNull = readBoolean(in);
+
+        if (isNull) {
+            return null;
         }
-    }
 
-    private UUID readUuid(final ByteBuffer in) throws Exception {
-        assert in != null;
+        long msb = in.getLong();
+        
+        long lsb = in.getLong();
+
+        return new UUID(msb, lsb);
+    }
 
-        byte isnull = in.get();
+    protected void writeUuid(final ByteBuffer out, final UUID uuid) throws Exception {
+        assert out != null;
 
-        if (isnull == 1) { // not null
-            long msb = in.getLong();
-            long lsb = in.getLong();
-            return new UUID(msb, lsb);
+        if (uuid == null) {
+            writeBoolean(out, true);
         }
         else {
-            return null;
+            writeBoolean(out, false);
+
+            out.putLong(uuid.getMostSignificantBits());
+            
+            out.putLong(uuid.getLeastSignificantBits());
         }
     }
 }

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=577065&r1=577064&r2=577065&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
Tue Sep 18 14:04:33 2007
@@ -34,6 +34,8 @@
     OPEN_SHELL          (OpenShellMessage.class),
     CLOSE_SHELL         (CloseShellMessage.class),
     EXECUTE             (ExecuteMessage.class),
+    EXECUTE_RESULT      (ExecuteMessage.Result.class),
+    EXECUTE_FAULT       (ExecuteMessage.Fault.class),
     WRITE_STREAM        (WriteStreamMessage.class),
     ;
 

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=577065&r1=577064&r2=577065&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
Tue Sep 18 14:04:33 2007
@@ -22,7 +22,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import org.apache.geronimo.gshell.remote.stream.IoSessionInputStream;
+import org.apache.geronimo.gshell.remote.stream.SessionInputStream;
 import org.apache.geronimo.gshell.remote.transport.Transport;
 import org.apache.mina.common.IoSession;
 import org.slf4j.Logger;
@@ -74,6 +74,8 @@
     public void visitWriteStream(final WriteStreamMessage msg) throws Exception {
         assert msg != null;
 
+        log.debug("Writing stream: {}", msg);
+
         IoSession session = msg.getSession();
 
         // Look up the bound stream in the session context
@@ -84,11 +86,11 @@
         if (stream == null) {
             log.error("Stream is not registered: {}", key);
         }
-        else if (!(stream instanceof IoSessionInputStream)) {
+        else if (!(stream instanceof SessionInputStream)) {
             log.error("Stream is not for input: {}", key);
         }
         else {
-            IoSessionInputStream in = (IoSessionInputStream)stream;
+            SessionInputStream in = (SessionInputStream)stream;
             in.write(msg.getBuffer());
         }
     }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/OpenShellMessage.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/OpenShellMessage.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/OpenShellMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/OpenShellMessage.java
Tue Sep 18 14:04:33 2007
@@ -33,18 +33,6 @@
         super(MessageType.OPEN_SHELL);
     }
 
-    public void readExternal(final ByteBuffer in) throws Exception {
-        assert in != null;
-
-        super.readExternal(in);
-    }
-
-    public void writeExternal(final ByteBuffer out) throws Exception {
-        assert out != null;
-
-        super.writeExternal(out);
-    }
-
     public void process(final MessageVisitor visitor) throws Exception {
         assert visitor != null;
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/WriteStreamMessage.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/WriteStreamMessage.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/WriteStreamMessage.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/WriteStreamMessage.java
Tue Sep 18 14:04:33 2007
@@ -20,8 +20,6 @@
 package org.apache.geronimo.gshell.remote.message;
 
 import org.apache.mina.common.ByteBuffer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Write a buffer to a stream.
@@ -31,8 +29,6 @@
 public class WriteStreamMessage
     extends MessageSupport
 {
-    public final Logger log = LoggerFactory.getLogger(getClass());
-
     private String name;
 
     private ByteBuffer buffer;
@@ -44,8 +40,10 @@
 
         if (buffer != null) {
             ByteBuffer tmp = ByteBuffer.allocate(buffer.remaining());
+
             tmp.put(buffer);
             tmp.flip();
+
             this.buffer = tmp;
         }
     }
@@ -77,12 +75,7 @@
 
         name = readString(in);
 
-        int len = in.getInt();
-
-        byte[] bytes = new byte[len];
-        in.get(bytes);
-
-        buffer = ByteBuffer.wrap(bytes);
+        buffer = readBuffer(in);
     }
 
     public void writeExternal(final ByteBuffer out) throws Exception {
@@ -92,9 +85,7 @@
 
         writeString(out, name);
 
-        out.putInt(buffer.remaining());
-
-        out.put(buffer);
+        writeBuffer(out, buffer);
     }
 
     public void process(final MessageVisitor visitor) throws Exception {

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.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/tcp/TcpProtocolHandler.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java
Tue Sep 18 14:04:33 2007
@@ -25,8 +25,8 @@
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.remote.message.MessageResponseInspector;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
-import org.apache.geronimo.gshell.remote.stream.IoSessionInputStream;
-import org.apache.geronimo.gshell.remote.stream.IoSessionOutputStream;
+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.mina.common.IdleStatus;
 import org.apache.mina.common.IoHandler;
@@ -147,26 +147,27 @@
     //
 
     public void sessionCreated(final IoSession session) throws Exception {
-        log.info("Session created: {}", session);
+        log.debug("Session created: {}", session);
     }
 
     public void sessionOpened(final IoSession session) throws Exception {
         assert session != null;
 
-        log.info("Session opened: {}", session);
+        log.debug("Session opened: {}", session);
 
         //
         // Once the session has been opened, bind streams to the session context.
         //
 
-        setInputStream(session, new IoSessionInputStream());
-        setOutputStream(session, new IoSessionOutputStream(session));
+        setInputStream(session, new SessionInputStream());
+        
+        setOutputStream(session, new SessionOutputStream(session));
     }
 
     public void sessionClosed(final IoSession session) throws Exception {
         assert session != null;
 
-        log.info("Session closed: {}", session);
+        log.debug("Session closed: {}", session);
 
         IOUtil.close(removeInputStream(session));
         
@@ -176,7 +177,7 @@
     public void sessionIdle(final IoSession session, final IdleStatus status) throws Exception
{
         assert session != null;
 
-        log.info("Session idle: {}, status: {}", session, status);
+        log.debug("Session idle: {}, status: {}", session, status);
 
         if (status == IdleStatus.READER_IDLE) {
             log.warn("Read timeout");
@@ -187,7 +188,7 @@
         assert session != null;
         assert obj != null;
 
-        log.info("Message received: {}", obj);
+        log.debug("Message received: {}", obj);
 
         //
         // TODO: Need to handle Exception muck, and send faul messages back to clients
@@ -229,7 +230,7 @@
     public void messageSent(final IoSession session, final Object obj) throws Exception {
         assert session != null;
 
-        log.info("Message sent: {}", obj);
+        log.debug("Message sent: {}", obj);
 
         if (obj instanceof Request) {
             //

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransport.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/tcp/TcpTransport.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransport.java
Tue Sep 18 14:04:33 2007
@@ -32,6 +32,7 @@
 import org.apache.geronimo.gshell.remote.message.Message;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
 import org.apache.geronimo.gshell.remote.transport.Transport;
+import org.apache.geronimo.gshell.common.tostring.ReflectionToStringBuilder;
 import org.apache.mina.common.CloseFuture;
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoSession;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.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/RemoteShell.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java
Tue Sep 18 14:04:33 2007
@@ -63,9 +63,6 @@
     @Requirement
     private Environment env;
 
-    @Requirement
-    private IO io;
-
     private boolean opened = true;
     
     private void ensureOpened() {
@@ -86,7 +83,7 @@
 
     public Environment getEnvironment() {
         ensureOpened();
-
+        
         return env;
     }
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.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/RshServerMessageVisitor.java?rev=577065&r1=577064&r2=577065&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java
Tue Sep 18 14:04:33 2007
@@ -19,6 +19,11 @@
 
 package org.apache.geronimo.gshell.remote.server;
 
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
 import org.apache.geronimo.gshell.DefaultEnvironment;
 import org.apache.geronimo.gshell.ExitNotification;
 import org.apache.geronimo.gshell.command.IO;
@@ -32,7 +37,11 @@
 import org.apache.geronimo.gshell.remote.message.OpenShellMessage;
 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.DefaultPlexusContainer;
 import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.component.factory.ComponentFactory;
@@ -57,6 +66,45 @@
     // Remote Shell Access
     //
 
+    private ClassWorld getClassWorld() {
+        return container.getContainerRealm().getWorld();
+    }
+
+    private RemoteShell createRemoteShell(final IoSession session) throws Exception {
+        assert session != null;
+
+        log.info("Creating remote shell");
+        
+        // We need to create a new container (not a child container) to allow the remote
shell a full unpollute namespace for components
+        ContainerConfiguration config = new DefaultContainerConfiguration();
+        config.setName("gshell.rsh");
+        config.setClassWorld(getClassWorld());
+        PlexusContainer container = new DefaultPlexusContainer(config);
+        session.setAttribute(PlexusContainer.class.getName(), container);
+
+        // Setup the I/O context (w/o auto-flushing)
+        IO io = new IO(getInputStream(session), getOutputStream(session), false);
+
+        //
+        // FIXME: We need to set the verbosity of this I/O context as specified by the client
+        //
+
+        IOLookup.set(container, io);
+        session.setAttribute(IO.class.getName(), io);
+
+        // Setup shell environemnt
+        Environment env = new DefaultEnvironment(io);
+        EnvironmentLookup.set(container, env);
+        session.setAttribute(Environment.class.getName(), env);
+
+        // Create a new shell instance
+        RemoteShell shell = (RemoteShell) container.lookup(RemoteShell.class);
+
+        log.info("Created remote shell: {}", shell);
+        
+        return shell;
+    }
+
     private RemoteShell getRemoteShell(final IoSession session) {
         assert session != null;
 
@@ -118,20 +166,8 @@
 
         IoSession session = msg.getSession();
 
-        // Setup the I/O context
-        IO io = new IO(getInputStream(session), getOutputStream(session));
-        IOLookup ioLookup = (IOLookup) container.lookup(ComponentFactory.class, IOLookup.class.getSimpleName());
-        ioLookup.set(io);
-
-        // Setup the shell environemnt
-        Environment env = new DefaultEnvironment(io);
-        EnvironmentLookup envLookup = (EnvironmentLookup) container.lookup(ComponentFactory.class,
EnvironmentLookup.class.getSimpleName());
-        envLookup.set(env);
-
-        // Create a new shell instance
-        RemoteShell shell = (RemoteShell) container.lookup(RemoteShell.class);
-
-        // Bind it to the session
+        // Create a new shell instance and bind it to the session
+        RemoteShell shell = createRemoteShell(session);
         setRemoteShell(session, shell);
 
         //
@@ -161,30 +197,56 @@
         msg.reply(new EchoMessage("CLOSE SHELL SUCCESS"));
     }
 
+    private ExecutorService executorService = Executors.newCachedThreadPool();
+
     public void visitExecute(final ExecuteMessage msg) throws Exception {
         assert msg != null;
 
-        log.info("EXECUTE: {}", msg);
+        log.info("EXECUTE (QUEUE): {}", msg);
 
-        IoSession session = msg.getSession();
+        final IoSession session = msg.getSession();
 
-        try {
-            RemoteShell shell = getRemoteShell(session);
+        final RemoteShell shell = getRemoteShell(session);
 
-            Object result = msg.execute(shell);
+        Runnable executeCommandTask = new Runnable() {
+            public void run() {
+                log.info("EXECUTE: {}", msg);
+                
+                try {
+                    //
+                    // TODO: Need to find a better place to stash this me thinks...
+                    //
+                    
+                    // Need to make sure we bind the correct bits into the lookups, since
they are thread specific
+                    PlexusContainer container = (PlexusContainer) session.getAttribute(PlexusContainer.class.getName());
+
+                    IO io = (IO) session.getAttribute(IO.class.getName());
+                    IOLookup.set(container, io);
+
+                    Environment env = (Environment) session.getAttribute(Environment.class.getName());
+                    EnvironmentLookup.set(container, env);
+
+                    Object result = msg.execute(shell);
+
+                    msg.reply(new ExecuteMessage.Result(result));
+                }
+                catch (ExitNotification n) {
+                    //
+                    // TODO: Send client message with this detail...
+                    //
+
+                    log.info("Remote shell requested exit: {}", n);
+
+                    session.close();
+                }
+                catch (Throwable t) {
+                    log.error("Unhandled failure; sending to client: " + t, t);
+
+                    msg.reply(new ExecuteMessage.Fault(t));
+                }
+            }
+        };
 
-            //
-            // TODO: Send response
-            //
-        }
-        catch (ExitNotification n) {
-            //
-            // TODO: Send client message with this detail...
-            //
-
-            log.info("Remote shell requested exit: {}", n);
-            
-            session.close();
-        }
+        executorService.submit(executeCommandTask);
     }
 }



Mime
View raw message