2017-01-07 3 views
0

새 파일을 위해 폴더를 모니터링하고 각 파일을 가져 와서 RESTful 서비스 (내 다른 앱 중 하나)를 사용해야하는 간단한 애플리케이션을 처리하는 데 시간이 너무 많이 걸리고 있습니다.) 및 스프링 통합 FTP 바운드 채널 어댑터를 사용하여 상기 응답 파일을 전송Monitor 폴더가있는 문제가 WebService를 사용하고 FTP를 통해 파일을 보냅니다. 아웃 바운드 채널

이는 다음 구조했습니다

enter image description here

이니셜 :

package com.ftpoutbound; 

import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.boot.web.support.SpringBootServletInitializer; 

import com.ftpoutbound.client.FtpoutboundApp; 
public class ServletInitializer extends SpringBootServletInitializer { 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(FtpoutboundApp.class); 
    } 

} 

나는 FtpoutboundApp에 콩을 정의

package com.ftpoutbound.client; 

import java.io.File; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import org.springframework.context.ApplicationContext; 
import org.apache.commons.net.ftp.FTPFile; 
import org.apache.log4j.Logger; 
import org.springframework.beans.BeansException; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 
import org.springframework.boot.context.event.ApplicationReadyEvent; 
import org.springframework.context.ApplicationContextAware; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.event.EventListener; 
import org.springframework.expression.common.LiteralExpression; 
import org.springframework.integration.annotation.Gateway; 
import org.springframework.integration.annotation.IntegrationComponentScan; 
import org.springframework.integration.annotation.MessagingGateway; 
import org.springframework.integration.annotation.ServiceActivator; 
import org.springframework.integration.file.FileNameGenerator; 
import org.springframework.integration.file.remote.session.CachingSessionFactory; 
import org.springframework.integration.file.remote.session.SessionFactory; 
import org.springframework.integration.ftp.outbound.FtpMessageHandler; 
import org.springframework.integration.ftp.session.DefaultFtpSessionFactory; 
import org.springframework.messaging.Message; 
import org.springframework.messaging.MessageHandler; 
import org.springframework.scheduling.annotation.EnableScheduling; 
import org.springframework.web.client.RestTemplate; 

import com.ftpoutbound.monitor.MonitorDirectory; 

@Configuration 
@SpringBootApplication 
@ComponentScan({ "com.ftpoutbound" }) 
@IntegrationComponentScan 
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) 
@EnableScheduling 
public class FtpoutboundApp implements ApplicationContextAware { 

    final static Logger logger = Logger.getLogger(FtpoutboundApp.class); 

    @Autowired 
    private MonitorDirectory monitor; 

    @Autowired 
    MyGateway gateway; 

    @Value("${remotedirectory}") 
    private String remotedirectory; 

    @Value("${remotehost}") 
    private String remotehost; 

    @Value("${remoteport}") 
    private int remoteport; 

    @Value("${remoteuser}") 
    private String remoteuser; 

    @Value("${remotepassword}") 
    private String remotepassword; 

    @Value("${outbound214sname}") 
    private String outbound214sname; 

    public static void main(String[] args) { 
     SpringApplication.run(FtpoutboundApp.class, args); 
    } 

    public void createGateway(File file214) { 
     try { 
      gateway.sendToFtp(file214); 
      file214.delete(); 
     } catch (Exception e) { 
      logger.error("ERROR APP OUTBOUND\n"); 
      logger.error(e); 
     } 
    } 

    @Bean 
    public SessionFactory<FTPFile> ftpSessionFactory() { 
     DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory(); 
     sf.setHost(remotehost); 
     sf.setPort(remoteport); 
     sf.setUsername(remoteuser); 
     sf.setPassword(remotepassword); 
     return new CachingSessionFactory<FTPFile>(sf); 
    } 

    @Bean 
    @ServiceActivator(inputChannel = "ftpChannel") 
    public MessageHandler handler() { 
     FtpMessageHandler handler = new FtpMessageHandler(ftpSessionFactory()); 
     handler.setRemoteDirectoryExpression(new LiteralExpression(remotedirectory)); 
     handler.setFileNameGenerator(new FileNameGenerator() { 

      @Override 
      public String generateFileName(Message<?> message) { 
       String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); 
       String time = new SimpleDateFormat("HHmmssssssss").format(new Date()); 
       return outbound214sname + "." + date + time; 
      } 
     }); 
     return handler; 
    } 

    @MessagingGateway 
    public interface MyGateway { 

     @Gateway(requestChannel = "ftpChannel") 
     void sendToFtp(File file); 
    } 

    @EventListener 
    public void afterApplicationReady(ApplicationReadyEvent event) { 
     try { 
      logger.info("INICIO DE MONITOREO DE ARCHIVOS HG"); 
      monitor.startMonitoring(); 
     } catch (IOException e) { 
      logger.error("ERROR EN MONITOREO DE FOLDER ENTRADA ARCHIVOS HG:\n" + e); 
     } catch (InterruptedException e) { 
      logger.error("INTERRUPCIÓN EN MONITOREO DE FOLDER ENTRADA ARCHIVOS HG:\n" + e); 
     } 
    } 

    @Bean 
    RestTemplate restTemplate() { 
     return new RestTemplate(); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
    } 

} 

이 모니터는 FtpoutboundApp에서 시작 : 내가 예약 주석을 사용하고 Watchservice 중 하나

package com.ftpoutbound.monitor; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.nio.file.ClosedWatchServiceException; 
import java.nio.file.FileSystems; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.nio.file.StandardWatchEventKinds; 
import java.nio.file.WatchEvent; 
import java.nio.file.WatchKey; 
import java.nio.file.WatchService; 

import org.apache.log4j.Logger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 

import com.ftpoutbound.client.FtpoutboundApp; 
import com.ftpoutbound.restfulclient.httpPost; 

@Component 
public class MonitorDirectory { 

    final static Logger logger = Logger.getLogger(MonitorDirectory.class); 

    @Autowired 
    private httpPost httppost; 

    @Value("${inboundhgfilesfolder}") 
    private String inboundhgfilesfolder; 

    @Value("${inboundhgfilesfolderbak}") 
    private String inboundhgfilesfolderbak; 

    @Value("${hglin}") 
    private String hglin; 

    @Scheduled(fixedRate = 10000) 
    public void startMonitoring() throws IOException, InterruptedException { 
     try { 
      listFiles(); 
     } catch (Exception e) { 
      logger.error("ERROR MONITOREANDO FOLDER"); 
      logger.error(e); 
     } 
    } 

    public void listFiles() throws Exception { 
     File directory = new File(inboundhgfilesfolder); 
     File[] fList = directory.listFiles(); 
     for (File file : fList) { 
      String fileName = file.getName(); 
      if (file.isFile()) { 
       readFile(fileName); 
       Thread.sleep(1000); 
      } 
     } 
    } 

    public void readFile(String fileName) throws IOException { 

     String hgFile = fileName.substring(0, 7); 
     if (hgFile.equals(hglin)) { 

      InputStream input = new FileInputStream(inboundhgfilesfolder + fileName); 
      StringBuilder builder = new StringBuilder(); 
      int ch; 
      while ((ch = input.read()) != -1) { 
       builder.append((char) ch); 
      } 
      try { 
       httppost.get214fromRestful(builder.toString()); 
      } catch (Exception e) { 
       logger.error("ERROR EN POST REQUEST DESDE APP OUTBOUND:\n" + e); 
      } 
     } 
     moveFile(fileName); 
    } 

    public void moveFile(String fileName) { 

     Path source = Paths.get(inboundhgfilesfolder + fileName); 
     Path newdir = Paths.get(inboundhgfilesfolderbak + fileName); 
     try { 
      Files.move(source, newdir); 
     } catch (IOException e) { 
      logger.error("ERROR MOVIENDO ARCHIVO:\n" + e); 
     } 
    } 
} 

그리고 편안하고을 소비하는 HttpClient를 작동하지 이후 앱

package com.ftpoutbound.restfulclient; 

import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 

import org.apache.log4j.Logger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.stereotype.Component; 
import org.springframework.web.client.RestTemplate; 

import com.ftpoutbound.client.FtpoutboundApp; 

@Component 
public class httpPost { 

    final static Logger logger = Logger.getLogger(httpPost.class); 

    @Value("${restful214url}") 
    private String restful214url; 

    @Value("${outbound214sfolder}") 
    private String outbound214sfolder; 

    @Autowired 
    private FtpoutboundApp ftpoutbound; 

    public void get214fromRestful(String hgfile) throws Exception { 
     logger.info("OBTENIENDO 214"); 
     logger.info("DIRECCION" + restful214url); 
     logger.info("ARCHIVO" + hgfile); 

     RestTemplate restTemplate = new RestTemplate(); 
     String result = restTemplate.postForObject(restful214url, hgfile, String.class); 

     File file = createFile214local(result.toString()); 
     logger.info("RESULTADO DE POST:"); 
     logger.info(result.toString()); 

     ftpoutbound.createGateway(file); 

    } 

    private File createFile214local(String hgfile) { 

     logger.info("ESCRIBIENDO 214"); 
     File file = new File(outbound214sfolder + "214.tmp"); 
     try { 
      file.createNewFile(); 
      FileWriter fw = new FileWriter(file.getAbsoluteFile()); 
      BufferedWriter bw = new BufferedWriter(fw); 
      bw.write(hgfile); 
      bw.close(); 

     } catch (IOException e) { 
      logger.error("ERROR ESCRIBIENDO FILE:\n->" + e); 
     } 

     return file; 
    } 

} 

하지만 앱이 작동하지 않는 것 같습니다. 에서 편안하고 겨 :

  logger.info("OBTENIENDO 214"); 
      logger.info("DIRECCION" + restful214url); 
      logger.info("ARCHIVO" + hgfile); 

나는 이것이 스레드의 문제 또는 무엇도 서버에 배포를 완료하지 않도록 APP 발생하는 경우이 선이 확실하지 여전히 로그에 두 번 인쇄 발견, 나는 또 다른이 비슷한 응용 프로그램 (하나는 RESTful을 소모하지 않는다는 것만 제외하면), 다른 FTPInbound 채널 어댑터와 제대로 작동하지만 정상적으로 작동하지만 몇 일간 실종되었거나 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

저를 믿으십시오, 도움은 극단적으로 평가 될 것입니다.

+1

항상 첫 번째 단계는'org.springframework'에 대해 DEBUG 로깅을 활성화하는 것입니다. 당신은 많은 진단 로그 기록을 얻을 것이다. 로그를 얻지 않으면 jstack 또는 visualvm을 사용하여 스레드 덤프를 가져옵니다. –

+0

감사합니다. Gary, 디버그를하고 있지만 내 응용 프로그램에 좋은 논리가 있습니다. ftpoutboun beans 정의 -> @EventListener로 모니터링을 시작하고 모니터에서 RESTful을 사용하고 -> ftpoutbound.createGateway (file)를 호출하여 파일을 보냅니다. – viruskimera

답변

0

문제는 내 아웃 바운드 채널 구성 클래스는 ApplicationContextAware를 구현하고 내 Microservices 앱을 소모 할 때 앱을 정지하기 위해 RestTemplate을 일으키는 이었다, 그래서 나는 SpringBootServletInitializer를 확장하고 WebApplicationInitializer을 구현하기 위해 변경하고 일했다.