2017-11-05 15 views
1

私は、クライアントがミドルウェアを通って流れるメッセージを購読/購読解除し、メッセージのペイロードを指定のコールバックにポストすることで(指定された基準に従って)通知を受けることができるWebフック通知サービスを開発していますURL。 メッセージ配信は次のようになります。あなたが見ることができるように統合フローの条件付きハンドラ

flowBuilder 
    .enrichHeaders(e->e.header(MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE,true)) 
    .handle(Http.outboundChannelAdapter(message-> { 
       String subscriptionId = message.getHeaders().get(SUBSCRIPTION_ID_HEADER_NAME, String.class); 
       return subscriptionsStore.get(UUID.fromString(subscriptionId)).getCallbackUrl(); //potential NPE if subscription was removed 

      },restTemplateBuilder.build()) 

.get() 

uriFunctionの実装では、サブスクリプションID(メッセージヘッダの一部)によってsubscriptionsStoreからコールバックURLをフェッチします。

私の質問は、クライアントがすでに自分のサブスクリプションIDを登録解除していて、条件付きハンドラの後にいる状況です。私は、サブスクリプションIDを持つメッセージをフィルタリングすることができます知っている

は、サブスクリプション・ストアにまだ存在しているが、クライアントはまだuriFunctionにNREを引き起こしfilter間とhandle操作を退会可能性があるとして、これは、適切な解決策ではありません。

もう1つの解決策は、コールバックURLでフィルタリングし、次に空でない値を持つヘッダでフィルタリングすることですが、元のメッセージのヘッダーもペイロードも妥協したくありません。

私は別のアプローチを考えることができますいくつかの静的な値として非既存のサブスクリプションのURIを計算し、この特定のURI値のためのHTTP OKリプレイをシミュレートするためRestTempalteにインターセプターを追加する...

だから私の質問

おかげ

UPDATE

012 ...私は程度認識していないよ標準EIPや他のSpring統合機能を使用して、このケースを処理する適切な方法についてです

public static class DedicatedMessage extends GenericMessage<Object> implements MessageDecorator{ 
     @Getter 
     @Transient 
     private Subscription subscription; 


     public DedicatedMessage(Subscription subscription,Object payload,Map<String,Object> headers) { 
      super(payload,headers); 
      this.subscription = subscription; 
     } 

     @Override 
     public Message<?> decorateMessage(Message<?> message) { 
      return new DedicatedMessage (subscription,message.getPayload(),message.getHeaders()); 
     } 
    } 

として流れを変更:このapporachで

flowBuilder 
    .enrichHeaders(e->e.header(MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE,true)) 
    .handle((payload, headers) -> { 
         String subscriptionId = (String) headers.get(SUBSCRIPTION_ID_HEADER_NAME); 
         Subscription subscription = subscriptionsCache.get(UUID.fromString(subscriptionId)); 
         return Optional.ofNullable(subscription) 
           .map(s-> new DedicatedMessage(s, payload,headers)) 
           .orElse(null); 
        }) 
    .handle(Http.outboundChannelAdapter(message->((DedicatedMessage)message).getSubscription().getCallbackUrl() 
          ,restTemplateBuilder.build()) 
.get() 

すべての問題を

私はコンテキストを保持しているDedicatedMessageクラスを追加しましたか?

答えて

1

私はあなたのNRE略語が何を意味するのかわからないが、あなたはあなたのsubscriptionsStore.get()方法からNoSuchSubscriptionExceptionをスローして、/そのendpoint.advice()チェーンのアウトバウンドチャネルアダプタに適用ExpressionEvaluatingRequestHandlerAdviceでその例外を報告して無視することができます。

+0

null参照例外、申し訳ありませんが、subscriptionStore.get(id)がnullを返すとスローされたNPEでした。アドバイスを適用して例外を処理しようとします。 –

+0

'get()'をラップし、 'null'を返す場合は例外をスローする必要があります。 –

+0

はい、確かに、私はあなたのアドバイスを明日試してみます。しかし、条件付きハンドラが春の統合に含める候補者かもしれないと思いませんか? –