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, blank :vendor 2: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,vendor2 및 vendor3 은 다음과 같이 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")