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")