[
https://issues.apache.org/jira/browse/CAMEL-25896?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-25896.
---------------------------------
Resolution: Fixed
Fixed by https://github.com/apache/camel/pull/28195 (merged to main for 4.24.0).
_Claude Code on behalf of davsclaus_
> camel-ftp - Let sendNoop=false also skip the consumer's pre-poll noop (SFTP
> sends [email protected] on every poll)
> ---------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25896
> URL: https://issues.apache.org/jira/browse/CAMEL-25896
> Project: Camel
> Issue Type: Improvement
> Components: camel-ftp, camel-mina-sftp, camel-sftp
> Affects Versions: 4.18.5, 4.23.0
> Reporter: Johan Almqvist
> Priority: Minor
> Fix For: 4.24.0
>
>
> h3. Problem
> Before every poll, {{RemoteFileConsumer.connectIfNecessary()}} calls
> {{getOperations().sendNoop()}}. For the JSch-based sftp component,
> {{SftpOperations.sendNoop()}} calls {{Session.sendKeepAliveMsg()}}, which
> sends a {{[email protected]}} global request. The {{sendNoop}} option
> (CAMEL-8807) is read only by {{RemoteFileProducer}}, so a consumer cannot
> turn this off. The code is the same in 4.18.5, in 4.23.0 and on main, where
> {{RemoteFileConsumer}} now lives in camel-ftp-common.
> ProFTPD's mod_sftp does not support that request. It replies with a failure
> and writes one SFTPLog line for each one:
> {noformat}
> <timestamp> mod_sftp/<version>[<pid>]: client sent GLOBAL_REQUEST for
> '[email protected]', denying
> {noformat}
> With the default {{delay=500}}, that is about two lines a second, roughly
> 170,000 a day, for each route polling the server. The volume grows with every
> route, and it buries authentication failures and other real errors in the
> same log. mod_sftp writes the line for every global request it does not
> handle (the same code in 1.3.7 to 1.3.9, 1.3.10rc4 and master), so the server
> cannot silence it without turning SFTPLog off entirely.
> h3. For the JSch-based sftp component the keepalive does not change the
> outcome
> * {{Session.sendKeepAliveMsg()}} writes the request and returns without
> waiting for the reply, so it cannot tell a live server from a dead one.
> * {{SftpOperations.sendNoop()}} only sends it when {{isConnected()}} is true.
> Otherwise it returns false without sending anything.
> * If the write throws, {{sendNoop()}} returns false and
> {{connectIfNecessary()}} calls {{connect()}}. That returns at once while
> {{isConnected()}} is still true, so nothing reconnects at that point. If JSch
> has already marked the session disconnected, {{isConnected()}} alone triggers
> the same reconnect.
> * When the server closes the socket (the CAMEL-6591 case), JSch's reader
> thread marks the session disconnected, so {{isConnected()}} already returns
> false and {{sendNoop()}} sends nothing.
> * A session that dies without the client noticing is recovered as it is
> today: the poll fails, {{RemoteFilePollingConsumerPollStrategy.rollback()}}
> force-disconnects, and the next poll reconnects.
> So for an sftp consumer the result is the same as calling {{isConnected()}},
> plus one packet per poll.
> h3. Proposal
> Let {{sendNoop}} also apply to the consumer's pre-poll check. With
> {{sendNoop=false}}, the consumer relies on {{isConnected()}}:
> {code:java}
> protected void connectIfNecessary() {
> boolean isConnected = false;
> try {
> if (getEndpoint().getConfiguration().isSendNoop()) {
> isConnected = getOperations().sendNoop();
> } else {
> isConnected = getOperations().isConnected();
> }
> } catch (Exception ex) {
> // unchanged
> }
> // unchanged from here
> }
> {code}
> * The default stays {{true}}. The only users affected are those who already
> set {{sendNoop=false}} on a consumer URI, where it is ignored today (for
> example a URI shared between {{from()}} and {{to()}}). That is worth a line
> in the upgrade guide.
> * {{RemoteFileConsumer}} is shared, so this also applies to ftp, ftps and
> mina-sftp. There {{sendNoop()}} is a real round trip (FTP {{NOOP}}, MINA
> {{stat("/")}}). With {{sendNoop=false}}, a connection the server has closed
> is found only when the poll fails, and the poll strategy then reconnects on
> the next poll. That is the same trade-off {{sendNoop=false}} already makes
> for producers.
> * The {{@UriParam}} label changes from {{producer,advanced}} to
> {{common,advanced}} (as {{fastExistsCheck}} uses). The description and the
> {{setSendNoop()}} Javadoc cover the pre-poll check as well as the pre-write
> check. Regenerating updates the component JSON, the catalog and the endpoint
> DSL.
> * Tests: a consumer counterpart of the existing producer {{sendNoop=false}}
> test for ftp and sftp, and a unit test that with {{sendNoop=false}} the
> consumer calls {{isConnected()}} instead of {{sendNoop()}} and still
> reconnects when it returns false.
> h3. Alternatives considered
> * Going back to {{sendIgnore()}}: CAMEL-10149 moved away from it because
> ProFTPD closed the connection on {{SSH_MSG_IGNORE}}.
> * {{disconnect=true}}: no keepalive, but a full SSH handshake and login on
> every poll.
> * camel-mina-sftp: its {{sendNoop()}} is an SFTP {{stat("/")}} with no global
> request, but switching components is not always an option.
> * Changing {{SftpOperations.sendNoop()}} for everyone, either to return
> {{isConnected()}} or to make a real round trip. That would change the default
> for every SFTP user, so this issue proposes an opt-in that matches
> CAMEL-8807, but either would also solve it.
> h3. Workaround today
> The only way to stop the keepalive today is to subclass {{SftpOperations}},
> {{SftpEndpoint}} and {{SftpComponent}} and register the subclass as {{sftp}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)