J'ai écrit un morceau de code qui utilise la passerelle sortante Spring SFTP et effectue une opération GET. La configuration complète est en Java (pas de XML). J'ai créé une fabrique de sessions de mise en cache qui permet un maximum de 10 sessions. En raison de quoi, après plusieurs requêtes GET quand il dépasse 10, la requête GET commence à échouer.Spring SFTP Outbound Gateway: Comment fermer la session après GET dans Java Config?
J'ai lu les documents et il a été écrit pour fermer la session après l'opération, mais je suis incapable de comprendre comment fermer cette session dans la configuration JAVA?
@org.springframework.integration.annotation.MessagingGateway
public interface FileOperationGateway {
@Gateway(requestChannel = "sftpChannelDownload")
InputStream downloadFromSftp(Message<Boolean> message);
}
@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(SFTP_HOST);
factory.setPort(SFTP_PORT);
factory.setUser(SFTP_USERNAME);
factory.setPassword(SFTP_PASSWORD);
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
/**
* Bean for Caching the session
*
*/
@Bean
@Autowired
public CachingSessionFactory<LsEntry> cachingSessionFactory(SessionFactory<LsEntry> sftpSessionFactory) {
CachingSessionFactory<LsEntry> cachingSessionFactory = new CachingSessionFactory<>(sftpSessionFactory, 10);
cachingSessionFactory.setSessionWaitTimeout(SFTP_SESSION_TIMEOUT);
return cachingSessionFactory;
}
/**
* Bean for Remote File Template
*
* @return
* @throws Exception
*/
@Bean
@Autowired
public RemoteFileTemplate<LsEntry> remoteFileTemplateDesigner(CachingSessionFactory<LsEntry> csf) throws Exception {
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("'" + SFTP_LOCATION + "'");
SftpRemoteFileTemplate rft = new SftpRemoteFileTemplate(csf);
rft.setRemoteDirectoryExpression(expression);
rft.setRemoteFileSeparator("/");
rft.setFileNameGenerator((msg) -> {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
Instant instant = timestamp.toInstant();
String fileNameFromHeader = msg.getHeaders().get(FileOperationConstants.FILE_HEADER_KEY).toString();
String newFileName;
if (fileNameFromHeader.lastIndexOf("/") != -1) {
newFileName = fileNameFromHeader.substring(fileNameFromHeader.lastIndexOf("/"));
} else if (fileNameFromHeader.lastIndexOf("\\") != -1) {
newFileName = fileNameFromHeader.substring(fileNameFromHeader.lastIndexOf("\\"));
} else
newFileName = fileNameFromHeader;
String fileNameOnly = newFileName.substring(0, newFileName.lastIndexOf("."));
String fileType = newFileName.substring(newFileName.lastIndexOf(".") + 1);
return (fileNameOnly + "__" + instant.toString() + "." + fileType);
});
rft.afterPropertiesSet();
return rft;
}
@Bean
@Autowired
@ServiceActivator(inputChannel = "sftpChannelDownload")
public SftpOutboundGatewaySpec downloadHandler(RemoteFileTemplate<LsEntry> rft) {
SftpOutboundGatewaySpec sogs = Sftp.outboundGateway(rft, FileOperationConstants.FILE_DOWNLOAD_COMMAND,
FileOperationConstants.FILE_DOWNLOAD_EXPRESSION);
sogs.options(Option.STREAM);
return sogs;
}
****** MISE À JOUR: ******
J'ai créé une nouvelle classe avec @messageEndpoint et placé le code de la session refermable en elle. J'ai ensuite appelé ce gestionnaire de ma classe de service (où je consommais le flux) Cela a fonctionné:
@MessageEndpoint
public class FileOperationCloseSessionMessageHandler {
@ServiceActivator(inputChannel = "sftpCloseSession")
public void closeSession(Message<Boolean> msg) throws IOException {
Closeable closeable = new IntegrationMessageHeaderAccessor(msg).getCloseableResource();
if (closeable != null) {
closeable.close();
}
}
}
Placée cette ligne dans la classe annotée @MessagingGateway
@Gateway(requestChannel = "sftpCloseSession")
void closeSession(Message<InputStream> msg);
Et puis appelé la méthode de la passerelle du service classe:
Message<InputStream> msg = msgGateway.downloadFromSftp(message);
InputStream is = msg.getPayload();
msgGateway.closeSession(msg);
Salut Gary, Merci pour la réponse. Je savais déjà que ce morceau de code "fermable" peut être utilisé pour fermer la session mais le problème est où et comment l'utiliser? devrais-je créer une nouvelle méthode @serviceActivator et placer ceci dans cela? Pouvez-vous s'il vous plaît montrer avec le code? –
J'ai trouvé la solution et l'ai mise à jour. Merci. –