2016-08-24 16 views
1

私は、Springブート1.4.0.RELEASE、Spring統合4.3.1.RELEASE、Spring統合DSL 1.2.0.M1を使用しています。私は、ファイルを使用して(ローカルの作業ディレクトリにファイルを転送、FTPからファイルを読み込みますアプリケーションと(インバウンドチャネルアダプタを使用して)ローカルファイルシステムを書いているSpring統合 - 'Dispatcherにはサブスクライバがありません'をデバッグする方法は?

:私は何をしようとしている

アウトバウンドゲートウェイ)を処理して、それらを最終的な宛先(ファイルアウトバウンドゲートウェイ/アダプタ)に移動します。

「Dispatcherにチャネルのサブスクライバがありません」という問題が発生しています。私はおそらく、文脈の中の何かが壊れていて、統合コンポーネントが起動していないことを意味していると思います。コンテキスト自体は、デバッグするときにアクティブであることを示します。

私の実際の設定はかなり大きいので、私の解決策を見つけるために誰かを探しているわけではありません。私はどこを見るべきか、どのコンポーネントが不平を言っているかを理解するためのガイダンスを探しています。

実際のエラーは以下のとおりです。

DEBUG [integration.channel.ExecutorChannel] [task-scheduler-1] preSend on channel 'errorChannel', message: ErrorMessage [payload=org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:test.fileReadingFlow.channel#1'. 

fileReadingFlowは、ディレクトリ(基本的に、私は尋ねたものについてhere。その中には何もコンプレックスがあるからファイルを読み込むInboundChannelAdapterである。アダプタはに送信し、.log()ハンドラにメッセージを送信するヘッダを豊かにハンドラ(Files.outboundgateway)、そして最後にMessageChannel私が試した何

:。

  • を私はMessageChannel Sと物事Lのチェーンを歩いてきましたine up(スペルミスがない、すべてBeanが存在する)。
  • 私はfileReadingFlowにさらにLoggingHandlerを追加して、メッセージのエラー箇所を特定しました。
  • 私はfileReadingFlowの部分を削除して、メッセージをさらに遠ざけることができるかどうかを確認しました。
  • Componentを削除しました。問題が見つかるかどうか確認しています。
  • org.springframework.integrationのデバッグログを追加しました。エラーまたは警告に似たものは表示されません。私が見つけた何

は、流れが(でもenrichHeadersを)ログイン以外の何かをしようとした最初の時間は、ディスパッチャエラーが発生したことだった、とのメッセージがerrorChannelで終わりました。 fileReadingFlowを変更してファイルを読み込み、メッセージを記録し、空のハンドラで終了すると、ディスパッチャエラーが発生しました。したがって、私はかなりの問題はfileReadingFlow自体ではないと確信しています。

Componentを1つずつ削除する以外に、エラーの原因を突き止める方法はありますか?

EDIT:

出典:

@Bean(name = "fileReadingFlow") 
@Scope("prototype") 
@Profile("test") 
public IntegrationFlow testFileReadingFlow(MyEntity entity) { 

    return IntegrationFlows.from(s -> s.file(new File("someFolder"))) 
      .filter(fileListFilterBuilder.buildFileListFilter(File.class)) 
      , endpointConfigurer -> endpointConfigurer.poller(poller) 
    ) 
      .log(DEBUG, "com.myco.testFileReadingFlow") 
      .enrichHeaders(h -> 
        h.header("entity", entity) 
          .header(FOLDER_NAME, entity.getFolder()) 
      ) 
      .log(DEBUG, "com.myco.testFileReadingFlow", message -> "after headers") 
      .handle(Files.outboundGateway("workingFolder").deleteSourceFiles(true).autoCreateDirectory(true)) 
       .log(DEBUG, "com.myco.testFileReadingFLow", message -> "sending message to aggregatingFileChannel " + message) 
       .channel("aggregatingFileChannel") 
       .get(); 
    } 
@Bean 
public MessageChannel aggregatingFileChannel() { 
    return MessageChannels.executor(Executors.newCachedThreadPool()).get(); 

} 

@Bean 
public IntegrationFlow aggregatingFlow() { 

    // Read from the aggregatingFileChannel 
    return from("aggregatingFileChannel") 
      <...> 
      .get(); 
} 

アプリケーション:

@SpringBootApplication 
@EnableConfigurationProperties 
@EntityScan(
     basePackages = { "com.myco.model" } 
) 
@EnableJpaRepositories(basePackages = {"com.myco.rest"}) 
public class Application { 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class).web(false).run(args); 

     MyEntitySvc entitySvc = context.getBean(MyEntitySvc.class); 

     List<MyEntity> entities = entitySvc.findAllActive(); 

     AutowireCapableBeanFactory beanFactory = context.getBeanFactory(); 

     entities.forEach(entity -> { 
      IntegrationFlow flow = (IntegrationFlow) context.getBean("fileReadingFlow", entity); 

      beanFactory.getBean(entity.getFolder() + MyConstants.ADAPTER, Lifecycle.class).start(); 
    } 

策:以下の私のコメントはパー

@Prototype方法はいくつかの点で作業を行ったが、私それを壊し、簡単に変更をロールバックできませんでした。 GaryとArtemの提案を使用して、IntegrationFlowContextメソッドを使用するように変更しました。私が元々持っていたランタイムスタートアップ、プロファイルドインジェクションインジェクションなどを保持するために、私はIntegrationFlowの定義を@Configurationクラスから@Serviceクラスに移しました。そうすれば、ApplicationProfileを知らせなくても、IntegrationFlowContextServiceに注入して、異なるプロファイルの異なるバージョンを実装することができます。主な方法は、BeanContextから抽出し、手動で開始してServiceを取得し、メソッドを呼び出すことにあります。

@Service 
@Profile("test") 
public class TestFlowSvc implements FlowSvc { 
    public IntegrationFlow testFileReadingFlow(Vendor vendor) { 
     return // As previous Flow 
    } 

    public void startFileReadingFlow(MyEntity entity) { 

     IntegrationFlow flow = testFileReadingFlow(entity); 

     integrationFlowContext.register(flow, true); 
    } 
} 

アプリケーション:アクティブSubscriberのないいくつかのSubscribableChannel(春の統合の期間中MessageHandler)があるとき

@SpringBootApplication 
@EnableConfigurationProperties 
@EntityScan(
     basePackages = { "com.myco.model" } 
) 
@EnableJpaRepositories(basePackages = {"com.myco.rest"}) 
public class Application { 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class).web(false).run(args); 

     MyEntitySvc entitySvc = context.getBean(MyEntitySvc.class); 
     FlowSvc flowSvc = context.getBean(FlowSvc.class); 
     List<MyEntity> entities = entitySvc.findAllActive(); 

     entities.forEach(entity -> { 
      flowSvc.startFileReadingFlow(entity); 
    } 

答えて

1

我々はDispatcher has no Subscribersエラーが発生しています。 "アクティブ"は、定義されていないか、または停止状態にあることを意味します。

ので、application:test.fileReadingFlow.channel#1MessageChannelであなたの問題のために、私はそのfileReadingFlowIntegrationFlow 1より多くの時間に見ると第二匿名DirectChannel上にあるものを見つけるだろう。

のために、MessageChannelが存在するため、このような問題をデバッグする簡単な方法はわかりませんが、何も記録されません。

fileReadingFlowIntegrationFlowの定義を示して、問題を一緒に修正してください。

ちょうど停止状態であってもよい
.handle(Files.outboundGateway()) 

:それはこの1つでなければなりませんあなたの関連質問に探し

実際のコードまではわかりませんが、

+1

デバッグログを有効にしてこのようなメッセージを探してください... '14:20:51.967 [メイン] INFO oscsDefaultLifecycleProcessor - 相で開始豆0 ' ' 14:20:51.968 [メイン] INFOのosichannel。 DirectChannel - Channel 'application.fromKafka.channel#0'に1人の加入者があります。 ' –

+0

@Artemサンプルフローを追加しました。 @Gary、私はそのようなメッセージを見た。私の 'fileReadingFlow'には何もありません。プロトタイプスコープであり、手動で開始した(編集に含まれていた)ためだと仮定しました。 – JudgingNotJudging

+0

プロトタイプスコープBeanへの参照がないため、インスタンスは作成されません。いずれにしても、 'IntegrationFlow' Beanのプロトタイプスコープを使用することはできません。内部的に多くのBeanを生成します。 –

関連する問題