8.15. together-Gather

8.15.1. together-Gather

그림 8.11. “Earge-Gather Pattern” 에 표시된 대로, together -gather 패턴 을 사용하면 동적으로 지정된 수의 수신자에게 메시지를 라우팅하고 응답을 단일 메시지로 다시 집계할 수 있습니다.

그림 8.11. Earge-Gather Pattern

브로드캐스트 집계

8.15.2. dynamic together-gather 예

다음 예제에서는 여러 다른 공급 업체에서 베터에 가장 적합한 인용을 가져오는 애플리케이션을 간략하게 설명합니다. 이 예제에서는 동적 8.3절. “수신자 목록” 를 사용하여 모든 공급업체의 인용문을 요청하고 8.5절. “수집기” 를 사용하여 모든 응답에서 가장 적합한 인용문을 선택합니다. 이 애플리케이션의 경로는 다음과 같이 정의됩니다.

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="direct:start"/>
    <recipientList>
      <header>listOfVendors</header>
    </recipientList>
  </route>
  <route>
    <from uri="seda:quoteAggregator"/>
    <aggregate strategyRef="aggregatorStrategy" completionTimeout="1000">
      <correlationExpression>
        <header>quoteRequestId</header>
      </correlationExpression>
      <to uri="mock:result"/>
    </aggregate>
  </route>
</camelContext>

첫 번째 경로에서 8.3절. “수신자 목록”listOfVendors 헤더를 보고 수신자 목록을 가져옵니다. 따라서 이 애플리케이션에 메시지를 보내는 클라이언트는 listOfVendors 헤더를 메시지에 추가해야 합니다. 예 8.1. “메시징 클라이언트 샘플” 발신 메시지에 관련 헤더 데이터를 추가하는 메시징 클라이언트의 일부 샘플 코드를 보여줍니다.

예 8.1. 메시징 클라이언트 샘플

Map<String, Object> headers = new HashMap<String, Object>();
headers.put("listOfVendors", "bean:vendor1, bean:vendor2, bean:vendor3");
headers.put("quoteRequestId", "quoteRequest-1");
template.sendBodyAndHeaders("direct:start", "<quote_request item=\"beer\"/>", headers);

message는 metrics: vendor1 ,MeshMemberRoll:vendor:vendor:vendor 2, blank :vendor3 끝점에 배포됩니다. 이러한 빈은 모두 다음 클래스로 구현됩니다.

public class MyVendor {
    private int beerPrice;

    @Produce(uri = "seda:quoteAggregator")
    private ProducerTemplate quoteAggregator;

    public MyVendor(int beerPrice) {
        this.beerPrice = beerPrice;
    }

    public void getQuote(@XPath("/quote_request/@item") String item, Exchange exchange) throws Exception {
        if ("beer".equals(item)) {
            exchange.getIn().setBody(beerPrice);
            quoteAggregator.send(exchange);
        } else {
            throw new Exception("No quote available for " + item);
        }
    }
}

polkit 인스턴스, vendor1,vendor2vendor3 은 다음과 같이 Spring XML 구문을 사용하여 인스턴스화됩니다.

<bean id="aggregatorStrategy" class="org.apache.camel.spring.processor.scattergather.LowestQuoteAggregationStrategy"/>

<bean id="vendor1" class="org.apache.camel.spring.processor.scattergather.MyVendor">
  <constructor-arg>
    <value>1</value>
  </constructor-arg>
</bean>

<bean id="vendor2" class="org.apache.camel.spring.processor.scattergather.MyVendor">
  <constructor-arg>
    <value>2</value>
  </constructor-arg>
</bean>

<bean id="vendor3" class="org.apache.camel.spring.processor.scattergather.MyVendor">
  <constructor-arg>
    <value>3</value>
  </constructor-arg>
</bean>

각 Cryostat는 더의 경우 다른 가격으로 초기화됩니다(생성자 인수로 전달됨). 메시지가 각 8080 끝점으로 전송되면 MyVendor.getQuote 메서드에 도달합니다. 이 방법은 이 인용 요청이 베터인지 여부를 확인하기 위한 간단한 검사를 수행한 다음 이후 단계에서 검색을 위해 교환에 대한 beer의 가격을 설정합니다. message는 Cryostat Producing을 사용하여 다음 단계로 전달됩니다(@Produce 주석 참조).

다음 단계에서 모든 공급 업체에서 beer 따옴표를 가져 와서 어느 것이 가장 좋은지 (즉, 가장 낮은)를 찾고 싶습니다. 이를 위해 사용자 정의 집계 전략과 함께 8.5절. “수집기” 를 사용합니다. 8.5절. “수집기” 는 현재 인용문과 관련된 메시지를 식별해야 합니다. 이 메시지는 quoteRequestId 헤더의 값에 따라 메시지를 순환하여 수행됩니다(concience Expression에 전달됨). 예 8.1. “메시징 클라이언트 샘플” 에 표시된 대로 상관 관계 ID는 quoteRequest-1 로 설정됩니다(관계 ID는 고유해야 함). 세트 중 가장 낮은 인용문을 선택하려면 다음과 같이 사용자 정의 집계 전략을 사용할 수 있습니다.

public class LowestQuoteAggregationStrategy implements AggregationStrategy {
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        // the first time we only have the new exchange
        if (oldExchange == null) {
            return newExchange;
        }

        if (oldExchange.getIn().getBody(int.class) < newExchange.getIn().getBody(int.class)) {
            return oldExchange;
        } else {
            return newExchange;
        }
    }
}

8.15.3. 정적 together-gather 예

정적 8.3절. “수신자 목록” 을 사용하여 receiver를 명시적으로 지정할 수 있습니다. 다음 예제에서는 정적 192.0.2.-gather 시나리오를 구현하는 데 사용할 경로를 보여줍니다.

from("direct:start").multicast().to("seda:vendor1", "seda:vendor2", "seda:vendor3");

from("seda:vendor1").to("bean:vendor1").to("seda:quoteAggregator");
from("seda:vendor2").to("bean:vendor2").to("seda:quoteAggregator");
from("seda:vendor3").to("bean:vendor3").to("seda:quoteAggregator");

from("seda:quoteAggregator")
    .aggregate(header("quoteRequestId"), new LowestQuoteAggregationStrategy()).to("mock:result")