You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2015/02/26 12:44:04 UTC
[2/2] mina-sshd git commit: [SSHD-413]
org.apache.sshd.common.Closeable should extend java.io.Closeable
[SSHD-413] org.apache.sshd.common.Closeable should extend java.io.Closeable
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/2f3228a7
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/2f3228a7
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/2f3228a7
Branch: refs/heads/master
Commit: 2f3228a75d7db30ed1655f88302c431e3d740bfb
Parents: eb369ab
Author: Guillaume Nodet <gn...@apache.org>
Authored: Thu Feb 26 11:46:19 2015 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Thu Feb 26 11:46:19 2015 +0100
----------------------------------------------------------------------
.../java/org/apache/sshd/common/Closeable.java | 2 +-
.../sshd/common/channel/AbstractChannel.java | 2 +-
.../apache/sshd/common/io/mina/MinaService.java | 33 ++++--
.../apache/sshd/common/io/mina/MinaSession.java | 2 +-
.../apache/sshd/common/util/CloseableUtils.java | 31 ++++-
.../sshd/server/channel/ChannelSession.java | 3 +-
.../sshd/common/util/CloseableUtilsTest.java | 118 +++++++++++++++++++
7 files changed, 171 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java b/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
index fa9a21d..6afac75 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
@@ -27,7 +27,7 @@ import org.apache.sshd.common.future.CloseFuture;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface Closeable {
+public interface Closeable extends java.io.Closeable {
/**
* Close this resource asynchronously and return a future.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
index c2d4231..1d04b17 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
@@ -155,7 +155,7 @@ public abstract class AbstractChannel extends CloseableUtils.AbstractInnerClosea
return new GracefulChannelCloseable();
}
- public class GracefulChannelCloseable implements Closeable {
+ public class GracefulChannelCloseable extends CloseableUtils.IoBaseCloseable {
protected volatile boolean closing;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
index 1981eb8..ee795b3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
@@ -23,7 +23,6 @@ import java.util.Map;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandler;
-import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.service.IoProcessor;
import org.apache.mina.core.service.IoService;
import org.apache.mina.core.session.IdleStatus;
@@ -33,14 +32,13 @@ import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.util.CloseableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*/
-public abstract class MinaService extends IoHandlerAdapter implements org.apache.sshd.common.io.IoService, IoHandler, Closeable {
+public abstract class MinaService extends CloseableUtils.AbstractCloseable implements org.apache.sshd.common.io.IoService, IoHandler, Closeable {
protected final Logger log = LoggerFactory.getLogger(getClass());
@@ -61,17 +59,10 @@ public abstract class MinaService extends IoHandlerAdapter implements org.apache
getIoService().dispose();
}
- public CloseFuture close(boolean immediately) {
+ @Override
+ protected void doCloseImmediately() {
getIoService().dispose();
- return CloseableUtils.closed();
- }
-
- public boolean isClosed() {
- return getIoService().isDisposed();
- }
-
- public boolean isClosing() {
- return getIoService().isDisposing();
+ super.doCloseImmediately();
}
public Map<Long, org.apache.sshd.common.io.IoSession> getManagedSessions() {
@@ -87,6 +78,22 @@ public abstract class MinaService extends IoHandlerAdapter implements org.apache
return sessions;
}
+ public void sessionOpened(IoSession session) throws Exception {
+ // Empty handler
+ }
+
+ public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
+ // Empty handler
+ }
+
+ public void messageSent(IoSession session, Object message) throws Exception {
+ // Empty handler
+ }
+
+ public void inputClosed(IoSession session) throws Exception {
+ session.close(true);
+ }
+
public void sessionCreated(IoSession session) throws Exception {
org.apache.sshd.common.io.IoSession ioSession = new MinaSession(this, session);
session.setAttribute(org.apache.sshd.common.io.IoSession.class, ioSession);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java
index 6f07207..ed8f380 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java
@@ -82,7 +82,7 @@ public class MinaSession extends CloseableUtils.AbstractInnerCloseable implement
@Override
protected Closeable getInnerCloseable() {
- return new Closeable() {
+ return new CloseableUtils.IoBaseCloseable() {
public boolean isClosing() {
return session.isClosing();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
index 94acdf5..97ff2d4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
@@ -18,6 +18,8 @@
*/
package org.apache.sshd.common.util;
+import java.io.IOException;
+import java.io.InterruptedIOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -44,6 +46,22 @@ import org.slf4j.LoggerFactory;
*/
public class CloseableUtils {
+ // TODO once JDK 8+ becomes the minimum for this project, make it a static method in the Closeable interface
+ public static void close(Closeable closeable) throws IOException {
+ if (closeable == null) {
+ return;
+ }
+
+ if ((!closeable.isClosed()) && (!closeable.isClosing())) {
+ CloseFuture future=closeable.close(true);
+ try {
+ future.await();
+ } catch(InterruptedException e) {
+ throw new InterruptedIOException(e.getClass().getSimpleName() + " while await future closure: " + e.getMessage());
+ }
+ }
+ }
+
public static CloseFuture closed() {
CloseFuture future = new DefaultCloseFuture(null);
future.setClosed();
@@ -130,7 +148,14 @@ public class CloseableUtils {
}
- private static class SimpleCloseable implements Closeable {
+ public static abstract class IoBaseCloseable implements Closeable {
+ // TODO once JDK 8+ becomes the minimum for this project, make it a default method instead of this class
+ public void close() throws IOException {
+ CloseableUtils.close(this);
+ }
+ }
+
+ private static class SimpleCloseable extends IoBaseCloseable {
protected final DefaultCloseFuture future;
protected final AtomicBoolean closing;
@@ -160,7 +185,7 @@ public class CloseableUtils {
private static class ParallelCloseable extends SimpleCloseable {
- final Iterable<? extends Closeable> closeables;
+ private final Iterable<? extends Closeable> closeables;
private ParallelCloseable(Object lock, Iterable<? extends Closeable> closeables) {
super(lock);
@@ -253,7 +278,7 @@ public class CloseableUtils {
}
}
- public static abstract class AbstractCloseable implements Closeable {
+ public static abstract class AbstractCloseable extends IoBaseCloseable {
protected enum State {
Opened, Graceful, Immediate, Closed
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index 16a3ec3..658c050 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -48,6 +48,7 @@ import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.DefaultCloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.util.Buffer;
+import org.apache.sshd.common.util.CloseableUtils;
import org.apache.sshd.common.util.IoUtils;
import org.apache.sshd.common.util.LoggingFilterOutputStream;
import org.apache.sshd.server.AsyncCommand;
@@ -213,7 +214,7 @@ public class ChannelSession extends AbstractServerChannel {
.build();
}
- public class CommandCloseable implements Closeable {
+ public class CommandCloseable extends CloseableUtils.IoBaseCloseable {
public boolean isClosed() {
return commandExitFuture.isClosed();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2f3228a7/sshd-core/src/test/java/org/apache/sshd/common/util/CloseableUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/util/CloseableUtilsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/util/CloseableUtilsTest.java
new file mode 100644
index 0000000..3bb8994
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/util/CloseableUtilsTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.common.util;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.future.CloseFuture;
+import org.apache.sshd.common.future.DefaultCloseFuture;
+import org.apache.sshd.util.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class CloseableUtilsTest extends BaseTest {
+ public CloseableUtilsTest() {
+ super();
+ }
+
+ @Test
+ public void testCloseImmediateNotCalledIfAlreadyClosed() throws IOException {
+ Closeable closeable=new CloseableUtils.IoBaseCloseable() {
+ public CloseFuture close(boolean immediately) {
+ Assert.fail("Unexpected call to close(" + immediately + ")");
+ return null;
+ }
+
+ public boolean isClosed() {
+ return true;
+ }
+
+ public boolean isClosing() {
+ return false;
+ }
+ };
+ closeable.close();
+ }
+
+ @Test
+ public void testCloseImmediateNotCalledIfIsClosing() throws IOException {
+ Closeable closeable=new CloseableUtils.IoBaseCloseable() {
+ public CloseFuture close(boolean immediately) {
+ Assert.fail("Unexpected call to close(" + immediately + ")");
+ return null;
+ }
+
+ public boolean isClosed() {
+ return false;
+ }
+
+ public boolean isClosing() {
+ return true;
+ }
+ };
+ closeable.close();
+ }
+
+ @Test
+ public void testCloseImmediateCalledAndWait() throws Exception {
+ final DefaultCloseFuture future=new DefaultCloseFuture(this);
+ final AtomicInteger callsCount=new AtomicInteger(0);
+ final Closeable closeable=new CloseableUtils.IoBaseCloseable() {
+ public CloseFuture close(boolean immediately) {
+ Assert.assertTrue("Closure is not immediate", immediately);
+ Assert.assertEquals("Multiple close immediate calls", 1, callsCount.incrementAndGet());
+ return future;
+ }
+
+ public boolean isClosed() {
+ return false;
+ }
+
+ public boolean isClosing() {
+ return false;
+ }
+ };
+ ExecutorService service=ThreadUtils.newSingleThreadExecutor(getCurrentTestName());
+ try {
+ Future<?> task=service.submit(new Runnable() {
+ public void run() {
+ try {
+ closeable.close();
+ } catch(IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ future.setClosed(); // signal close complete
+ task.get(5L, TimeUnit.SECONDS); // make sure #await call terminated
+ Assert.assertEquals("Close immediate not called", 1, callsCount.get());
+ } finally {
+ service.shutdownNow();
+ }
+ }
+}