1. 개요

이 사용방법(예제)에서는 시스템을 통해 흐르는 메시지를 모니터링하는 데 도움이 되는 Wire Tap Enterprise Integration Pattern(EIP)에 대해 설명합니다 .

이 패턴을 사용하면  메시지를 채널에서 영구적으로 소비하지 않고 메시지를 가로챌 수 있습니다 .

2. 와이어 탭 패턴

Wire Tap은 지점간 채널을 통해 이동하는 메시지를 검사합니다 . 메시지를 수신하고 사본을 만들어 Tap Destination으로 보냅니다  .

와이어 탭 EnterpriseIntegrationPattern

이를 더 잘 이해하기 위해 ActiveMQ 및  Camel을 사용하여 Spring Boot 애플리케이션을 생성해 보겠습니다 .

3. 메이븐 의존성

camel-spring-boot-dependencies를 추가해봅시다 .

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-spring-boot-dependencies</artifactId>
            <version>${camel.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

이제 camel-spring-boot-starter를 추가합니다 .

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-spring-boot-starter</artifactId>
</dependency>

경로를 통해 흐르는 메시지를 보려면 ActiveMQ 도 포함해야 합니다 .

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-activemq-starter</artifactId>
</dependency>

4. 메시징 교환

메시지 객체를 만들어 봅시다:

public class MyPayload implements Serializable {
    private String value;
    ...
}

이 메시지를 direct:source 전송하여 경로를 시작합니다.

try (CamelContext context = new DefaultCamelContext()) {
    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
    connectionFactory.setTrustAllPackages(true);
    context.addComponent("direct", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
    addRoute(context);

    try (ProducerTemplate template = context.createProducerTemplate()) {
        context.start();

        MyPayload payload = new MyPayload("One");
        template.sendBody("direct:source", payload);
        Thread.sleep(10000);
    } finally {
        context.stop();
    }
}

다음으로 경로를 추가하고 목적지를 탭합니다.

5. 교환 탭하기

wireTap 메서드 사용하여  탭 대상의  Endpoints URI를   설정합니다 . Camel은  메시지 교환 패턴을 InOnly 로 설정하기  때문에 wireTap 응답을 기다리지 않습니다 . Wire Tap 프로세서는 별도의 스레드 에서 이를 처리합니다  .

wireTap("direct:tap").delay(1000)

낙타의 와이어 탭 노드는 교환을 탭할 때 두 가지 맛을 지원합니다.

5.1. 전통적인 와이어 탭

기존 Wire Tap 경로를 추가해 보겠습니다.

RoutesBuilder traditionalWireTapRoute() {
    return new RouteBuilder() {
        public void configure() {

            from("direct:source").wireTap("direct:tap")
                .delay(1000)
                .bean(MyBean.class, "addTwo")
                .to("direct:destination");

            from("direct:tap").log("Tap Wire route: received");

            from("direct:destination").log("Output at destination: '${body}'");
        }
    };
}

여기에서 Camel은  Exchange 만 복사   합니다 .  심층 복제는 수행하지 않습니다모든 복사본은  원본 교환의 개체를 공유할 수 있습니다.

 여러 메시지를 동시에 처리하는 동안 최종 페이로드가 손상될 가능성이 있습니다 . 이를 방지하기 위해 페이로드를 탭 대상으로 전달하기 전에 페이로드의 딥 클론을 생성할 수 있습니다. 

5.2. 새 교환 보내기

Wire Tap EIP는 Exchange 사본으로 미리 채워진 Expression  또는  Processor를 지원 합니다 . 식은   메시지 본문을 설정하는 데만 사용할 수 있습니다 . 

프로세서  변형  교환이 채워지는 방식(설정 속성, 헤더 등)에 대해 완전한 권한을 부여합니다.

 페이로드에서 딥 클로닝을 구현해 보겠습니다  .

public class MyPayload implements Serializable {

    private String value;
    ...
    public MyPayload deepClone() {
        MyPayload myPayload = new MyPayload(value);
        return myPayload;
   }
}

이제  원래 교환의 복사본을 입력으로 사용하여 Processor 클래스를 구현해 보겠습니다.

public class MyPayloadClonePrepare implements Processor {

    public void process(Exchange exchange) throws Exception {
        MyPayload myPayload = exchange.getIn().getBody(MyPayload.class);
        exchange.getIn().setBody(myPayload.deepClone());
        exchange.getIn().setHeader("date", new Date());
    }
}

wireTap  직후에 onPrepare를 사용하여 호출합니다 .

RoutesBuilder newExchangeRoute() throws Exception {
    return new RouteBuilder() {
        public void configure() throws Exception {

        from("direct:source").wireTap("direct:tap")
            .onPrepare(new MyPayloadClonePrepare())
            .end()
            .delay(1000);

        from("direct:tap").bean(MyBean.class, "addThree");
        }
     };
}

6. 결론

이 기사에서는 특정 메시지 Endpoints을 통과하는 메시지를 모니터링하기 위해 Wire Tap 패턴을 구현했습니다. Apache Camel의 wireTap을 사용하여 메시지를 복사하고 기존 흐름을 변경하지 않고 다른 Endpoints으로 보냅니다.

Camel은 교환을 탭하는 두 가지 방법을 지원합니다. 전통적인 Wire Tap에서는 원본 교환이 복사됩니다. 두 번째로 새로운 거래소를 만들 수 있습니다. Expression 을 사용하여 메시지 본문의 새 값으로 이 새로운 교환을 채우 거나 Processor 를 사용하여 헤더와 선택적으로 본문을 설정할 수 있습니다 .

코드 샘플은  GitHub에서 사용할 수 있습니다 .

Generic footer banner