2016-10-07 12 views
1

現在、私は、Spring Integration DSLを使用し、AMQPインバウンドゲートウェイに異なるサービスアクティベータを持つアプリケーションを持っています。各サービスアクティベータには、外部Webサービス(CXF )、しかし、このすべてのロジックは、Spring Integrationコンポーネントなしでコード内にあります。外部Webサービスモニタリングを使用したSpring統合アプリケーション

これらのサービスアクティベータは監視され、このアプリケーションからのデータを返す出力チャネルでは、キューにヘッダーを送信するAMQPアダプタが使用されます(その後、すべてのヘッダーが処理され、後で分析するためにデータベースに保存されます)。これはうまくいきます。これらのサービスアクティベータはヘッダーの経過時間も持っています。

エラーが発生した場合、各操作の経過時間、サービスエンドポイントと操作が呼び出された外部Webサービス呼び出しを監視する必要があります。

私は、各サービスアクティベータのロジックコードをSpringインテグレーションフローに変換し、各サービスアクティベータでヘッダー内のWebサービスの操作名で新しいゲートウェイを呼び出し、私がやっていたすべての流れを監視しています。

この手動アプローチがより良いアプローチであるかどうかはわかりません。したがって、CXFやSpring WSと同様のインターセプタなどでサービス操作の名前を取得する方法があるのだろうかと思います。手動でヘッダーに操作の名前を設定しないでください。あなたのお勧めは何ですか?ここではより多くのコンテキストを持つことが

は、Spring Integrationコンフィグレーションです:

@Bean 
public IntegrationFlow inboundFlow() { 
    return IntegrationFlows.from(Amqp.inboundGateway(simpleMessageListenerContainer()) 
      .mappedReplyHeaders(AMQPConstants.AMQP_CUSTOM_HEADER_FIELD_NAME_MATCH_PATTERN) 
      .mappedRequestHeaders(AMQPConstants.AMQP_CUSTOM_HEADER_FIELD_NAME_MATCH_PATTERN) 
      .errorChannel(gatewayErrorChannel()) 
      .requestChannel(gatewayRequestChannel()) 
      .replyChannel(gatewayResponseChannel()) 
     ) 
     .enrichHeaders(new Consumer<HeaderEnricherSpec>() { 
       @Override 
       public void accept(HeaderEnricherSpec t) { 
        t.headerExpression(AMQPConstants.START_TIMESTAMP, "T(java.lang.System).currentTimeMillis()"); 
       } 

     }) 
     .transform(getCustomFromJsonTransformer()) 
     .route(new HeaderValueRouter(AMQPConstants.OPERATION_ROUTING_KEY)) 
     .get(); 
} 

@Bean 
public MessageChannel gatewayRequestChannel() { 
    return MessageChannels.publishSubscribe().get(); 
} 

@Bean 
public MessageChannel gatewayResponseChannel() { 
    return MessageChannels.publishSubscribe().get(); 
} 

private IntegrationFlow loggerOutboundFlowTemplate(MessageChannel fromMessageChannel) { 
    return IntegrationFlows.from(fromMessageChannel) 
     .handle(Amqp.outboundAdapter(new RabbitTemplate(getConnectionFactory())) 
      .exchangeName(LOGGER_EXCHANGE_NAME) 
      .routingKey(LOGGER_EXCHANGE_ROUTING_KEY) 
      .mappedRequestHeaders("*")) 
     .get(); 
} 

そしてここでは、一般的なサービスの活性化因子である、あなたが見ることができるよう、すべてこのロジックは、統合の流れのようになります。

@ServiceActivator(inputChannel="myServiceActivator", outputChannel = ConfigurationBase.MAP_RESPONSE_CHANNEL_NAME) 
public Message<Map<String, Object>> myServiceActivator(Map<String, Object> input, @Header(AMQPConstants.SESSION) UserSession session) throws MyException { 
    Message<Map<String, Object>> result = null; 
    Map<String, Object> mapReturn = null; 

    ExternalService port = serviceConnection.getExternalService(); 
    try { 
     if (input.containsKey(MappingConstants.TYPE)) { 
      Request request = transformer 
        .transformRequest(input, session); 

      Response response = port 
        .getSomething(request); 

      utils.processBackendCommonErrors(response.getCode(), response.getResponse()); 
      mapReturn = transformer.convertToMap(response); 
     } else { 
      Request request = transformer 
        .transformRequest(input, session); 

      Response response = port 
        .getSomethingElse(request); 

      utils.processBackendCommonErrors(response.getCode(), 
        response.getResponse()); 
      mapReturn = transformer.convertToMap(response); 
     } 
    } catch (RuntimeException e) { 
     String message = "unexcepted exception from the back-end"; 
     logger.warn(message, e); 
     throw MyException.generateTechnicalException(message, null, e); 
    } 

    result = MessageBuilder.withPayload(mapReturn) 
      .build(); 

    return result; 
} 

答えて

0

これまでのところとても良いです。あるいは、私は問題を理解していないか、それがどこにあるのか明確ではありません。とにかく

あなたがコードを指しているように見えるので、あなたは常にプロキシAOPを持つ任意の春サービスは、することができます

Response response = port 
       .getSomething(request); 

この(または類似)メソッドが呼び出された、いくつかのMethodInterceptorが必要なトレースを実行することができますロジックおよびさらなる分析や他の何かのためにいくつかのMessageChannelに結果を送信がする:私はすべてのことは、現在のサービスの活性化剤(SA)で、私のヘッダに含まれているログインしてい

public Object invoke(MethodInvocation invocation) throws Throwable { 
    // Extract required operation name and start_date from the MethodInvocation 
    Object result = invocation.proceed(); 
    // Extract required data from the response 
    // Build message and send to the channel 
    return result; 
} 
+0

を、SA名はヘッダにあるので、ログcontai SAが実行されるnsと同じ方法で、外部サービスの名前と呼ばれる操作をヘッダに入れたいと考えています。私は新しい統合の流れを使うことができると思うが、操作の名前を持つ新しいゲートウェイを最初の呼び出しからヘッダーとして挿入する必要があるので、WS操作の名前を取得する自動方法があるのだろうか。手動で名前操作を設定することはありません。 – jcastaneyra

+0

「操作」とはどういう意味ですか?それはどこにある?それを誰がコントロールしているの?だから、そのものを使って、メッセージのヘッダーとしてログに提供してください。 –

+0

私は、サードパーティのWebサービスのメソッドや操作、AOP、Webサービスのインターセプタまたはヘッダーエンリッチャを使用する場合、Webサービスメソッドの名前を取得し、ヘッダーとして手動で名前を設定せずにこのメソッド名をヘッダーに入れることができますゲートウェイを呼び出すとき – jcastaneyra

関連する問題