从数据库动态获取sftp连接属性并在spring集成中获取sftpConnectionFactory

时间:2015-08-23 11:35:00

标签: spring-integration

我要求我从数据库获取SFTP连接属性,并使用来自数据库的属性动态创建sftpSessionFactory

${sftp.host}下方,${sftp.port}${sftp.user}${sftp.password}属性值应来自数据库。

<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
    <property name="host" value="${sftp.host}"/>
    <property name="port" value="${sftp.port}" />
    <property name="user" value="${sftp.user}"/>
    <property name="password" value="${sftp.password}"/>
</bean>

如何通过从数据库获取属性来创建SFTP连接?

的web.xml

<!-- Loads the Spring application contexts -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath*:context/application-context-*.xml
    </param-value>
</context-param>

应用程序上下文的services.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

<context:annotation-config />
<context:component-scan base-package="com.abc.xyz.batch.services" />


<bean id="freemarkerConfiguration"
    class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
    <property name="preferFileSystemAccess" value="false" />
    <property name="templateLoaderPath" value="classpath:templates/" />
    <property name="freemarkerSettings">
        <props>
            <prop key="default_encoding">UTF-8</prop>
            <prop key="locale">ar_AR</prop>
        </props>
    </property>
</bean>

<bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="cacheSeconds" value="0" />
    <property name="defaultEncoding" value="UTF-8" />
    <property name="useCodeAsDefaultMessage" value="true" />
    <property name="basenames">
        <list>
            <value>classpath:validation-messages</value>
        </list>
    </property>
</bean>

EnvironmentLookupService.java

@Service
public class EnvironmentLookupService {

    private static final Logger logger = LoggerFactory.getLogger(EnvironmentLookupService.class);

    @Autowired
    @Qualifier("transactionManager")
    private PlatformTransactionManager txManager;

    @Autowired
    private ConfigDao configDao;

    private final Map<String, String> config = new HashMap<String, String>();

    /**
     * Loads all lookups used in xyz from database
     */
    @PostConstruct
    public void loadLookupData() {
        logger.info("loading lookup cache");
        new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                loadLookups();
            }
        });
        // initialize();
    }

    /**
     * Refreshes the lookup caches
     */
    @Scheduled(cron = "${core.lookups.cache.refresh.cron}")
    public void refreshCache() {
        loadLookupData();
    }

    /**
     * Loads all lookups from database
     */
    protected void loadLookups() {
        final List<IConfig> list = configDao.findAll();
        for (final IConfig property : list) {
            config.put(property.getKey(), property.getValue());
        }

    }

    /**
     * Will return configuration value for the key provided
     *
     * @param key
     * @return String
     */
    public String retriveConfigValue(EConfig key) {
        return config.get(key.getValue());
    }

}

DynamicSftpChannelResolver.java

@Service
public class DynamicSftpChannelResolver {

    @Autowired
    private EnvironmentLookupService lookupService;

    ConfigurableApplicationContext confAppContext;


    @PostConstruct
    public void setEnvironmentForSftpConnection() {

        confAppContext = new ClassPathXmlApplicationContext("classpath*:context/*integration-context.xml");

        final StandardEnvironment stdEnvironment = new StandardEnvironment();
        final Properties props = new Properties();

        props.setProperty(EConfig.SFTP_HOST.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_HOST));
        props.setProperty(EConfig.SFTP_PORT.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_PORT));
        props.setProperty(EConfig.SFTP_USER.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_USER));
        props.setProperty(EConfig.SFTP_PASSWORD.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_PASSWORD));

        final PropertiesPropertySource propPropertySource = new PropertiesPropertySource("sftp", props);
        stdEnvironment.getPropertySources().addLast(propPropertySource);
        confAppContext.setEnvironment(stdEnvironment);
    }

}

弹簧整合-context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-file="http://www.springframework.org/schema/integration/file"
    xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:int-ws="http://www.springframework.org/schema/integration/ws"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">


    <tx:annotation-driven transaction-manager="transactionManager" />

    <context:property-placeholder />
    <!-- <context:property-placeholder ignore-unresolvable="true" location="classpath:*.properties"/>    -->

    <bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
        <property name="host" value="${sftp.host}"/>
        <property name="port" value="${sftp.port}" />
        <property name="user" value="${sftp.user}"/>
        <property name="password" value="${sftp.password}"/>
    </bean>


    <int:channel id="ch.file.download"></int:channel  >

    <int:channel id="ch.file.type.access"></int:channel  >
    <int:channel id="ch.file.type.excel"></int:channel  >
    <int:channel id="ch.file.type.csv"></int:channel  >
    <int:channel id="ch.file.validated"></int:channel>


    <int-sftp:inbound-channel-adapter id="sftp.file.client.download"

        session-factory="sftpSessionFactory" channel="ch.file.download"
        auto-create-local-directory="true" remote-directory="${sftp.remote.directory}"
        local-filename-generator-expression="#this" 
        temporary-file-suffix=".downloading" 
        local-directory="${sftp.local.directory}"
        >
        <int:poller fixed-rate="1000"/>
    </int-sftp:inbound-channel-adapter>

完成上述所有操作后sftpSessionFactory未创建。也不例外。 我没有加载guest * integration-conotext.xml。 你能告诉我,出了什么问题吗?。

1 个答案:

答案 0 :(得分:0)

您的web.xml可以选择按模式classpath*:context/application-context-*.xml加载任何XML配置。但Spring Integration配置名称看起来像spring-integration-context.xml

从我的角度来看,这并不重要,最好在问题上使用<context:import>

从另一方面请求查看自Spring Integration DelegatingSessionFactory以来的新4.2功能,该功能允许在运行时针对SessionFactory检索目标requestMessage

还有一点。我使用Commons Configuration从DataBase加载Properties,并将最后一个用于properties-placeholder

<bean id="databaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
    <constructor-arg ref="dataSource"/>
    <constructor-arg value="PROPERTIES"/>
    <constructor-arg value="PROPERTY"/>
    <constructor-arg value="PROPERTYVALUE"/>
</bean>

<bean id="propertiesFromDB" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
      p:staticMethod="org.apache.commons.configuration.ConfigurationConverter.getProperties"
      p:arguments-ref="databaseConfiguration"/>

<context:property-placeholder properties-ref="propertiesFromDB"/>

如果这足以让你在启动时只从DB加载一次。