Repository: mina-sshd
Updated Branches:
  refs/heads/master 4b19c2a53 -> 57c5ed623


Take into account the timeout value provided in RemoteSession#exec call


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/57c5ed62
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/57c5ed62
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/57c5ed62

Branch: refs/heads/master
Commit: 57c5ed6234b5102e09603178246739d81c3ceea8
Parents: 4b19c2a
Author: Lyor Goldstein <[email protected]>
Authored: Mon Sep 21 08:41:28 2015 +0300
Committer: Lyor Goldstein <[email protected]>
Committed: Mon Sep 21 08:41:28 2015 +0300

----------------------------------------------------------------------
 .../sshd/git/pack/GitPackCommandFactory.java    |   1 -
 .../sshd/git/pgm/GitPgmCommandFactory.java      |   5 +-
 .../sshd/git/transport/GitSshdSession.java      | 132 +++++++++++++++++++
 .../git/transport/GitSshdSessionFactory.java    | 131 +-----------------
 .../git/transport/GitSshdSessionProcess.java    | 102 ++++++++++++++
 5 files changed, 238 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/57c5ed62/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java 
b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
index 191ca5d..1eeefdf 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
@@ -51,5 +51,4 @@ public class GitPackCommandFactory implements CommandFactory {
             return new UnknownCommand(command);
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/57c5ed62/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java 
b/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
index 86db60e..f508ab9 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
@@ -28,6 +28,7 @@ import org.apache.sshd.server.command.UnknownCommand;
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
 public class GitPgmCommandFactory implements CommandFactory {
+    public static final String GIT_COMMAND_PREFIX = "git ";
 
     private final String rootDir;
     private final CommandFactory delegate;
@@ -43,8 +44,8 @@ public class GitPgmCommandFactory implements CommandFactory {
 
     @Override
     public Command createCommand(String command) {
-        if (command.startsWith("git ")) {
-            return new GitPgmCommand(rootDir, command.substring("git 
".length()));
+        if (command.startsWith(GIT_COMMAND_PREFIX)) {
+            return new GitPgmCommand(rootDir, 
command.substring(GIT_COMMAND_PREFIX.length()));
         } else if (delegate != null) {
             return delegate.createCommand(command);
         } else {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/57c5ed62/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
----------------------------------------------------------------------
diff --git 
a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java 
b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
new file mode 100644
index 0000000..ff2191e
--- /dev/null
+++ b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
@@ -0,0 +1,132 @@
+/*
+ * 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.sshd.git.transport;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.channel.ChannelExec;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.RemoteSession;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FS;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public class GitSshdSession extends AbstractLoggingBean implements 
RemoteSession {
+    /**
+     * Property used to configure the SSHD {@link 
org.apache.sshd.common.FactoryManager} with
+     * the default timeout (millis) to connect to the remote SSH server.
+     * If not specified then {@link #DEFAULT_CONNECT_TIMEOUT} is used.
+     */
+    public static final String CONNECT_TIMEOUT_PROP = 
"git-ssh-connect-timeout";
+    public static final long DEFAULT_CONNECT_TIMEOUT = 
TimeUnit.SECONDS.toMillis(30L);
+
+    /**
+     * Property used to configure the SSHD {@link 
org.apache.sshd.common.FactoryManager} with
+     * the default timeout (millis) to authenticate with the remote SSH server.
+     * If not specified then {@link #DEFAULT_AUTH_TIMEOUT} is used.
+     */
+    public static final String AUTH_TIMEOUT_PROP = "git-ssh-connect-timeout";
+    public static final long DEFAULT_AUTH_TIMEOUT = 
TimeUnit.SECONDS.toMillis(15L);
+
+    /**
+     * Property used to configure the SSHD {@link 
org.apache.sshd.common.FactoryManager} with
+     * the default timeout (millis) to open a channel to the remote SSH server.
+     * If not specified then {@link #DEFAULT_CHANNEL_OPEN__TIMEOUT) is used.
+     */
+    public static final String CHANNEL_OPEN_TIMEOUT_PROPT = 
"git-ssh-channel-open-timeout";
+    public static final long DEFAULT_CHANNEL_OPEN_TIMEOUT = 
TimeUnit.SECONDS.toMillis(7L);
+
+    private final SshClient client;
+    private final ClientSession session;
+
+    public GitSshdSession(URIish uri, CredentialsProvider credentialsProvider, 
FS fs, int tms) throws IOException, InterruptedException {
+        String user = uri.getUser();
+        final String pass = uri.getPass();
+        String host = uri.getHost();
+        int port = uri.getPort();
+        char[] pass2 = null;
+
+        if (!credentialsProvider.isInteractive()) {
+            CredentialItem.Username usrItem = new CredentialItem.Username();
+            CredentialItem.Password pwdItem = new CredentialItem.Password();
+            if (credentialsProvider.get(uri, usrItem, pwdItem)) {
+                if (user == null) {
+                    user = usrItem.getValue();
+                } else if (user.equals(usrItem.getValue())) {
+                    pass2 = pwdItem.getValue();
+                }
+            }
+        }
+
+        client = createClient();
+
+        client.start();
+
+        session = client.connect(user, host, port)
+                        .verify(FactoryManagerUtils.getLongProperty(client, 
CONNECT_TIMEOUT_PROP, DEFAULT_CONNECT_TIMEOUT))
+                        .getSession();
+        if (log.isDebugEnabled()) {
+            log.debug("Connected to {}:{}", host, port);
+        }
+        if (pass != null) {
+            session.addPasswordIdentity(pass);
+        }
+        if (pass2 != null) {
+            session.addPasswordIdentity(new String(pass2));
+        }
+        session.auth().verify(FactoryManagerUtils.getLongProperty(session, 
AUTH_TIMEOUT_PROP, DEFAULT_AUTH_TIMEOUT));
+        if (log.isDebugEnabled()) {
+            log.debug("Authenticated: {}", session);
+        }
+    }
+
+    @Override
+    public Process exec(String commandName, int timeout) throws IOException {
+        if (log.isTraceEnabled()) {
+            log.trace("exec({}) session={}, timeout={} sec.", commandName, 
session, timeout);
+        }
+
+        ChannelExec channel = session.createExecChannel(commandName);
+        channel.open().verify(FactoryManagerUtils.getLongProperty(channel, 
CHANNEL_OPEN_TIMEOUT_PROPT, DEFAULT_CHANNEL_OPEN_TIMEOUT));
+        return new GitSshdSessionProcess(channel, commandName, timeout);
+    }
+
+    @Override
+    public void disconnect() {
+        if (session.isOpen()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Disconnecting from {}", session);
+            }
+        }
+
+        client.close(true);
+    }
+
+    protected SshClient createClient() {
+        return SshClient.setUpDefaultClient();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/57c5ed62/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
 
b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
index 0e19278..545657d 100644
--- 
a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
+++ 
b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
@@ -18,21 +18,7 @@
  */
 package org.apache.sshd.git.transport;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.sshd.client.SshClient;
-import org.apache.sshd.client.channel.ChannelExec;
-import org.apache.sshd.client.channel.ClientChannel;
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.FactoryManagerUtils;
-import org.apache.sshd.common.util.ValidateUtils;
 import org.eclipse.jgit.errors.TransportException;
-import org.eclipse.jgit.transport.CredentialItem;
 import org.eclipse.jgit.transport.CredentialsProvider;
 import org.eclipse.jgit.transport.RemoteSession;
 import org.eclipse.jgit.transport.SshSessionFactory;
@@ -45,30 +31,6 @@ import org.eclipse.jgit.util.FS;
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
 public class GitSshdSessionFactory extends SshSessionFactory {
-    /**
-     * Property used to configure the SSHD {@link 
org.apache.sshd.common.FactoryManager} with
-     * the default timeout (millis) to connect to the remote SSH server.
-     * If not specified then {@link #DEFAULT_CONNECT_TIMEOUT} is used
-     */
-    public static final String CONNECT_TIMEOUT_PROP = 
"git-ssh-connect-timeout";
-    public static final long DEFAULT_CONNECT_TIMEOUT = 
TimeUnit.SECONDS.toMillis(30L);
-
-    /**
-     * Property used to configure the SSHD {@link 
org.apache.sshd.common.FactoryManager} with
-     * the default timeout (millis) to authenticate with the remote SSH server.
-     * If not specified then {@link #DEFAULT_AUTH_TIMEOUT} is used
-     */
-    public static final String AUTH_TIMEOUT_PROP = "git-ssh-connect-timeout";
-    public static final long DEFAULT_AUTH_TIMEOUT = 
TimeUnit.SECONDS.toMillis(15L);
-
-    /**
-     * Property used to configure the SSHD {@link 
org.apache.sshd.common.FactoryManager} with
-     * the default timeout (millis) to open a channel to the remote SSH server.
-     * If not specified then {@link #DEFAULT_CHANNEL_OPEN__TIMEOUT);
-     */
-    public static final String CHANNEL_OPEN_TIMEOUT_PROPT = 
"git-ssh-channel-open-timeout";
-    public static final long DEFAULT_CHANNEL_OPEN_TIMEOUT = 
TimeUnit.SECONDS.toMillis(7L);
-
     public GitSshdSessionFactory() {
         super();
     }
@@ -76,100 +38,9 @@ public class GitSshdSessionFactory extends 
SshSessionFactory {
     @Override
     public RemoteSession getSession(URIish uri, CredentialsProvider 
credentialsProvider, FS fs, int tms) throws TransportException {
         try {
-            return new SshdSession(uri, credentialsProvider, fs, tms);
+            return new GitSshdSession(uri, credentialsProvider, fs, tms);
         } catch (Exception e) {
             throw new TransportException("Unable to connect", e);
         }
     }
-
-    protected SshClient createClient() {
-        return SshClient.setUpDefaultClient();
-    }
-
-    public class SshdSession implements RemoteSession {
-        private final SshClient client;
-        private final ClientSession session;
-
-        public SshdSession(URIish uri, CredentialsProvider 
credentialsProvider, FS fs, int tms) throws IOException, InterruptedException {
-            String user = uri.getUser();
-            final String pass = uri.getPass();
-            String host = uri.getHost();
-            int port = uri.getPort();
-            char[] pass2 = null;
-
-            if (!credentialsProvider.isInteractive()) {
-                CredentialItem.Username usrItem = new 
CredentialItem.Username();
-                CredentialItem.Password pwdItem = new 
CredentialItem.Password();
-                if (credentialsProvider.get(uri, usrItem, pwdItem)) {
-                    if (user == null) {
-                        user = usrItem.getValue();
-                    } else if (user.equals(usrItem.getValue())) {
-                        pass2 = pwdItem.getValue();
-                    }
-                }
-            }
-
-            client = createClient();
-
-            client.start();
-            session = client.connect(user, host, port)
-                            
.verify(FactoryManagerUtils.getLongProperty(client, CONNECT_TIMEOUT_PROP, 
DEFAULT_CONNECT_TIMEOUT))
-                            .getSession();
-            if (pass != null) {
-                session.addPasswordIdentity(pass);
-            }
-            if (pass2 != null) {
-                session.addPasswordIdentity(new String(pass2));
-            }
-            session.auth().verify(FactoryManagerUtils.getLongProperty(client, 
AUTH_TIMEOUT_PROP, DEFAULT_AUTH_TIMEOUT));
-        }
-
-        @Override
-        public Process exec(String commandName, int timeout) throws 
IOException {
-            final ChannelExec channel = session.createExecChannel(commandName);
-            channel.open().verify(FactoryManagerUtils.getLongProperty(client, 
CHANNEL_OPEN_TIMEOUT_PROPT, DEFAULT_CHANNEL_OPEN_TIMEOUT));
-            return new Process() {
-                @Override
-                public OutputStream getOutputStream() {
-                    return channel.getInvertedIn();
-                }
-
-                @Override
-                public InputStream getInputStream() {
-                    return channel.getInvertedOut();
-                }
-
-                @Override
-                public InputStream getErrorStream() {
-                    return channel.getInvertedErr();
-                }
-
-                @Override
-                public int waitFor() throws InterruptedException {
-                    Collection<ClientChannel.ClientChannelEvent> res =
-                            
channel.waitFor(EnumSet.of(ClientChannel.ClientChannelEvent.CLOSED), 
Long.MAX_VALUE);
-                    if (res.contains(ClientChannel.ClientChannelEvent.CLOSED)) 
{
-                        return 0;
-                    } else {
-                        return -1;
-                    }
-                }
-                @Override
-                public int exitValue() {
-                    Integer status = 
ValidateUtils.checkNotNull(channel.getExitStatus(), "No channel status 
available");
-                    return status.intValue();
-                }
-
-                @Override
-                public void destroy() {
-                    channel.close(true);
-                }
-            };
-        }
-
-        @Override
-        public void disconnect() {
-            client.close(true);
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/57c5ed62/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionProcess.java
----------------------------------------------------------------------
diff --git 
a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionProcess.java
 
b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionProcess.java
new file mode 100644
index 0000000..a96b5f3
--- /dev/null
+++ 
b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionProcess.java
@@ -0,0 +1,102 @@
+/*
+ * 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.sshd.git.transport;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.channel.ChannelExec;
+import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public class GitSshdSessionProcess extends Process {
+    protected final ChannelExec channel;
+    protected final String commandName;
+    protected final long waitTimeout;
+    protected final Logger log;
+
+    public GitSshdSessionProcess(ChannelExec channel, String commandName, int 
timeoutSec) {
+        this.channel = ValidateUtils.checkNotNull(channel, "No exec channel");
+        this.commandName = commandName;
+        this.waitTimeout = (timeoutSec > 0) ? 
TimeUnit.SECONDS.toMillis(timeoutSec) : Long.MAX_VALUE;
+        this.log = LoggerFactory.getLogger(getClass());
+    }
+
+    @Override
+    public OutputStream getOutputStream() {
+        return channel.getInvertedIn();
+    }
+
+    @Override
+    public InputStream getInputStream() {
+        return channel.getInvertedOut();
+    }
+
+    @Override
+    public InputStream getErrorStream() {
+        return channel.getInvertedErr();
+    }
+
+    @Override   // TODO in Java-8 implement also waitFor(long, TimeUnit)
+    public int waitFor() throws InterruptedException {
+        Collection<ClientChannel.ClientChannelEvent> res =
+                
channel.waitFor(EnumSet.of(ClientChannel.ClientChannelEvent.CLOSED), 
waitTimeout);
+        if (log.isTraceEnabled()) {
+            log.trace("waitFor({}) channel={}, timeout={} millis.: {}",
+                      commandName, channel, waitTimeout, res);
+        }
+        if (res.contains(ClientChannel.ClientChannelEvent.CLOSED)) {
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+
+    @Override
+    public int exitValue() {
+        Integer status = channel.getExitStatus();
+        if (status == null) {   // NOTE: MUST use IllegalThreadStateException 
as per the Javadoc
+            throw new IllegalThreadStateException("No channel status 
available");
+        }
+        if (log.isTraceEnabled()) {
+            log.trace("exitValue({}) channel={}, timeout={} millis.: {}",
+                      commandName, channel, waitTimeout, status);
+        }
+        return status.intValue();
+    }
+
+    @Override
+    public void destroy() {
+        channel.close(true);
+    }
+
+    @Override
+    public String toString() {
+        return "channel=" + channel + ", cmd=" + commandName + ", timeout=" + 
waitTimeout;
+    }
+}

Reply via email to