Skip to content

Commit 40a0e02

Browse files
committed
KARAF-7174: Implement a SSH channel resource clearner whiteboard
1 parent a8d9901 commit 40a0e02

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

log/src/main/java/org/apache/karaf/log/command/LogTail.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.karaf.shell.api.action.Command;
2323
import org.apache.karaf.shell.api.action.lifecycle.Reference;
2424
import org.apache.karaf.shell.api.action.lifecycle.Service;
25+
import org.apache.karaf.shell.api.console.ChannelResourceCleaner;
2526
import org.apache.karaf.shell.api.console.Session;
2627
import org.ops4j.pax.logging.spi.PaxAppender;
2728
import org.osgi.framework.BundleContext;
@@ -31,7 +32,8 @@
3132

3233
@Command(scope = "log", name = "tail", description = "Continuously display log entries. Use ctrl-c to quit this command")
3334
@Service
34-
public class LogTail extends DisplayLog {
35+
public class LogTail extends DisplayLog implements ChannelResourceCleaner {
36+
3537
@Reference
3638
Session session;
3739

@@ -52,6 +54,9 @@ public Object execute() throws Exception {
5254
PaxAppender appender = event -> printEvent(out, event, minLevel);
5355
ServiceTracker<LogService, LogService> tracker = new LogServiceTracker(context, LogService.class, null, appender);
5456
tracker.open();
57+
58+
context.registerService(ChannelResourceCleaner.class, this, null);
59+
5560
try {
5661
synchronized (this) {
5762
wait();
@@ -65,6 +70,12 @@ public Object execute() throws Exception {
6570
out.println();
6671
return null;
6772
}
73+
74+
@Override
75+
public void close() {
76+
System.out.println("STOP TAIL");
77+
stopTail();
78+
}
6879

6980
private synchronized void stopTail() {
7081
notifyAll();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.karaf.shell.api.console;
20+
21+
public interface ChannelResourceCleaner {
22+
23+
void close();
24+
25+
}

shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import java.nio.file.Path;
2323
import java.nio.file.Paths;
2424
import java.time.Duration;
25+
import java.util.Collection;
2526
import java.util.Collections;
2627

2728
import org.apache.karaf.shell.api.action.lifecycle.Manager;
29+
import org.apache.karaf.shell.api.console.ChannelResourceCleaner;
2830
import org.apache.karaf.shell.api.console.CommandLoggingFilter;
2931
import org.apache.karaf.shell.api.console.Session;
3032
import org.apache.karaf.shell.api.console.SessionFactory;
@@ -34,8 +36,11 @@
3436
import org.apache.karaf.util.tracker.annotation.Managed;
3537
import org.apache.karaf.util.tracker.annotation.RequireService;
3638
import org.apache.karaf.util.tracker.annotation.Services;
39+
import org.apache.sshd.common.channel.Channel;
40+
import org.apache.sshd.common.channel.ChannelListener;
3741
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
3842
import org.apache.sshd.common.keyprovider.KeyPairProvider;
43+
import org.apache.sshd.common.session.SessionListener;
3944
import org.apache.sshd.core.CoreModuleProperties;
4045
import org.apache.sshd.scp.server.ScpCommandFactory;
4146
import org.apache.sshd.server.SshServer;
@@ -189,6 +194,20 @@ protected SshServer createSshServer(SessionFactory sessionFactory) {
189194
server.setKeyExchangeFactories(SshUtils.buildKexAlgorithms(kexAlgorithms));
190195
server.setSignatureFactories(SshUtils.buildSigAlgorithms(sigAlgorithms));
191196
server.setShellFactory(new ShellFactoryImpl(sessionFactory));
197+
server.addSessionListener(new SessionListener() {
198+
@Override
199+
public void sessionDisconnect(org.apache.sshd.common.session.Session session, int reason, String msg, String language, boolean initiator) {
200+
try {
201+
Collection<ServiceReference<ChannelResourceCleaner>> references = bundleContext.getServiceReferences(ChannelResourceCleaner.class, null);
202+
for (ServiceReference<ChannelResourceCleaner> reference : references) {
203+
ChannelResourceCleaner cleaner = bundleContext.getService(reference);
204+
cleaner.close();
205+
}
206+
} catch (Exception e) {
207+
// no-op
208+
}
209+
}
210+
});
192211

193212
if (sftpEnabled) {
194213
server.setCommandFactory(new ScpCommandFactory.Builder().withDelegate((channel, cmd) -> new ShellCommand(sessionFactory, cmd)).build());

0 commit comments

Comments
 (0)