Apache Camel-빠른 가이드
인도의 Bigbasket과 같은 마을의 대형 온라인 식료품 점에서 IT 솔루션을 설계하도록 초대하는 상황을 생각해보십시오. 안정적이고 확장 가능한 솔루션은 오늘날 직면하고있는 소프트웨어 유지 관리 문제를 극복하는 데 도움이됩니다. 이 온라인 상점은 지난 10 년 동안 사업을 운영해 왔습니다. 상점은 고객으로부터 다양한 범주의 제품에 대한 온라인 주문을 수락하고이를 각 공급 업체에 배포합니다. 예를 들어 비누, 기름, 우유를 주문한다고 가정 해 보겠습니다. 이 세 가지 품목은 각각의 공급자에게 배포됩니다. 그런 다음 세 공급 업체는 전체 주문이 배송 센터에서 처리되는 공통 배포 지점으로 소모품을 보냅니다. 이제 그들이 현재 직면하고있는 문제를 살펴 보겠습니다.
이 상점이 사업을 시작했을 때 쉼표로 구분 된 일반 텍스트 파일로 주문을 받고있었습니다. 일정 기간 동안 상점은 메시지 기반 주문 배치로 전환되었습니다. 나중에 일부 소프트웨어 개발자는 XML 기반 주문 배치를 제안했습니다. 결국 상점은 웹 서비스 인터페이스까지 적용했습니다. 이제 진짜 문제가 있습니다. 주문은 이제 다른 형식으로 제공됩니다. 분명히 회사가 주문 수락 형식을 업그레이드 할 때마다 고객의 마음에 혼란을 일으키지 않도록 이전에 배포 된 인터페이스를 깨고 싶지 않았습니다.
동시에 비즈니스가 계속 성장함에 따라 매장은 정기적으로 새로운 공급 업체를 레퍼토리에 추가했습니다. 그러한 각 공급자는 주문을 수락하기위한 자체 프로토콜을 가지고 있습니다. 다시 한 번 통합 문제에 직면 해 있습니다. 당사의 애플리케이션 아키텍처는 고유 한 주문 배치 메커니즘으로 새로운 공급 업체를 수용 할 수 있도록 확장 가능해야합니다.
전체 상황은 다음 그림에 나와 있습니다.
이제 Apache Camel이 설명 된 시나리오에 대해 우아하고 유지 관리 가능하며 확장 가능한 솔루션 아키텍처를 제공하기 위해 어떻게 구출 할 수 있는지 살펴 보겠습니다.
솔루션을 진행하기 전에 작은 가정을해야합니다. 이 튜토리얼의 모든 논의를 위해 온라인 주문이 XML 형식으로 이루어 졌다고 가정합니다. 토론 전체에서 사용할 주문 파일의 일반적인 형식은 다음과 같습니다.
<?xml version = "1.0" encoding = "UTF-8"?>
<OrderID Order = "001">
<order product = "soaps">
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
</order>
<order product = "Oil">
<items>
<item>
<Brand>Saffola</Brand>
<Type>Gold</Type>
<Quantity>2</Quantity>
<Price>649</Price>
</item>
<item>
<Brand>Fortune</Brand>
<Type>Sunlite</Type>
<Quantity>1</Quantity>
<Price>525</Price>
</item>
</items>
</order>
<order product = "Milk">
<items>
<item>
<Product>Milk</Product>
<Brand>Amul</Brand>
<Type>Pure</Type>
<Quantity>2</Quantity>
<Price>60</Price>
</item>
</items>
</order>
</OrderID>
이 튜토리얼의 Camel 예제를 설명하기 위해 위의 XML 템플릿을 사용할 것입니다.
Camel은 일부 엔드 포인트에서 메시지를 수신하여 다른 엔드 포인트로 보내는 블랙 박스입니다. 블랙 박스 내에서 메시지를 처리하거나 단순히 리디렉션 할 수 있습니다.
그렇다면 왜이를위한 프레임 워크가 있습니까? 도입 사례 연구에서 볼 수 있듯이 실제 상황에서는 ftp, http 및 jms와 같은 자체 프로토콜을 따르는 많은 발신자와 수신자가있을 수 있습니다. 시스템은 보낸 사람 A의 메시지가 B & C에게만 전달되어야하는 것과 같은 많은 복잡한 규칙을 요구할 수 있습니다. 상황에서 메시지를 수신자가 예상하는 다른 형식으로 변환해야 할 수 있습니다. 이 번역은 메시지 내용에 따라 특정 조건이 적용될 수 있습니다. 따라서 기본적으로 프로토콜 간 변환, 구성 요소 연결, 라우팅 규칙 정의, 메시지 콘텐츠 기반 필터링 제공이 필요할 수 있습니다. 이것은 다음 그림에 설명되어 있습니다.
위의 요구 사항을 충족하고 이러한 많은 상황에 적합한 소프트웨어 아키텍처를 설계하기 위해 EIP (Enterprise Integration Patterns )는 2003 년 Gregor Hohpe 및 Bobby Woolf에 의해 문서화되었습니다. Apache Camel은 이러한 패턴의 구현을 제공하며이 튜토리얼의 목적은 다음과 같습니다. 소개에서 설명한 것과 같은 상황에서 Camel을 사용하는 방법.
Apache Camel은 오픈 소스 프레임 워크입니다. 규칙 기반 라우팅 및 중개 엔진을 제공하는 메시지 지향 미들웨어입니다. "우유"주문 인 경우 우유 공급 업체로 리디렉션하고 "오일"주문 인 경우 오일 공급 업체로 리디렉션하는 등의 규칙을 정의 할 수 있습니다. Camel을 사용하면 이러한 규칙을 구현하고 익숙한 Java 코드로 라우팅을 수행 할 수 있습니다. 이는 익숙한 Java IDE를 사용하여 유형이 안전한 환경에서 이러한 규칙을 정의 할 수 있음을 의미합니다. 일반적으로 부피가 큰 경향이있는 XML 구성 파일을 사용할 필요가 없습니다. Camel은 규칙 구성에 XML을 사용하는 것을 선호하는 경우 Spring 프레임 워크를 통해 XML 구성을 지원합니다. Scala 애호가라면 Blueprint XML 구성 파일과 Scala DSL을 사용할 수도 있습니다. 또한 선호하는 Java, Scala IDE 또는 간단한 XML 편집기를 사용하여 규칙을 구성 할 수 있습니다.
이 엔진에 대한 입력은 쉼표로 구분 된 텍스트 파일, POJO (Plain Old Java Object), XML은 Camel에서 지원하는 여러 다른 형식 중 하나 일 수 있습니다. 마찬가지로 엔진의 출력을 파일, 메시지 대기열 또는 모니터 화면으로 리디렉션하여 각 공급 업체에 보낸 주문을 볼 수 있습니다. 이를 엔드 포인트라고하며 Camel은 메시지 엔드 포인트 EIP 패턴을 지원합니다 . Camel 끝점은 끝점 장의 뒷부분에서 설명합니다.
Camel은 일반적으로 서비스 지향 아키텍처를 구현하기 위해 Apache ServiceMix , Apache ActiveMQ 및 Apache CXF 와 함께 사용됩니다 .
Apache Camel의 개요를 살펴 보았으므로 이제 기능을 살펴보고 제공하는 기능을 살펴 보겠습니다. Apache Camel이 기본적으로 다양한 EIP의 구현을 제공하는 오픈 소스 Java 프레임 워크라는 것을 이미 알고 있습니다. Camel은 매우 다양한 전송 및 API에 대한 연결을 제공하여 통합을 더 쉽게 만듭니다. 예를 들어 JMS를 JSON으로, JSON을 JMS로, HTTP를 JMS로, FTP를 JMS로, 심지어 HTTP를 HTTP로, 마이크로 서비스에 대한 연결을 쉽게 라우팅 할 수 있습니다. 양쪽 끝에 적절한 엔드 포인트를 제공하기 만하면됩니다. Camel은 확장 가능하므로 향후 더 많은 엔드 포인트를 프레임 워크에 쉽게 추가 할 수 있습니다.
EIP와 전송을 함께 연결하려면 Java, Scala 및 Groovy와 같은 DSL (Domain Specific Language)을 사용합니다. 일반적인 Java 라우팅 규칙은 다음과 같습니다.
from ("file:/order").to("jms:orderQueue");
이 라우팅 규칙은 order 디렉토리에서 파일 내용이 포함 된 JMS 메시지를 만들고 해당 메시지를 orderQueue.
다음은 Camel 응용 프로그램을 개발할 때 유용하게 사용할 수있는 Camel의 가장 중요한 기능입니다.
Camel은 이러한 메시지 변환을 위해 플러그 형 데이터 형식과 유형 변환기를 지원 하므로 향후 새로운 형식과 변환기를 추가 할 수 있습니다. 현재 널리 사용되는 여러 형식과 변환기를 지원합니다. CSV, EDI, JAXB, JSON, XmlBeans, XStream, Flatpack, Zip.
Camel은 DSL에서 술어를 작성 하기 위해 플러그 가능한 언어 를 지원합니다 . 지원되는 언어에는 JavaScript, Groovy, Python, PHP, Ruby, SQL, XPath, XQuery가 있습니다.
Camel은 POJO 모델을 지원하므로 다양한 지점에서 Javabean을 연결할 수 있습니다.
Camel은 메시징을 사용하여 이러한 대규모 분산 및 비동기 시스템의 테스트를 용이하게합니다.
이제 Camel의 아키텍처를 이해하고 다양한 기능이 어떻게 구현되는지 살펴 보겠습니다.
Camel 아키텍처는 통합 엔진 및 라우터, 프로세서 및 구성 요소의 세 가지 구성 요소로 구성됩니다. 이것은 다음 그림에 설명되어 있습니다.
Camel 코어 자체는 매우 작고 13 개의 필수 구성 요소를 포함합니다. 나머지 80 개 이상의 구성 요소는 코어 외부에 있습니다. 이는 배포 위치에 대한 낮은 종속성을 유지하는 데 도움이되며 향후 확장을 촉진합니다. 그만큼Components 모듈은 Endpoint외부 세계와의 인터페이스. 끝점은 다음과 같은 URI로 지정됩니다.file:/order 과 jms:orderQueue 지난 장에서 보신 것입니다.
그만큼 Processors모듈은 엔드 포인트 간의 메시지를 조작하고 중재하는 데 사용됩니다. 앞서 언급 한 EIP는이 모듈에서 구현됩니다. 현재 EIP 책 및 기타 유용한 처리 장치에 설명 된대로 40 개 이상의 패턴을 지원합니다 .
그만큼 Processors 과 Endpoints 함께 연결되어 있습니다 Integration Engine and RouterDSL을 사용하는 모듈. 이들을 연결하는 동안 필터를 사용하여 사용자 정의 기준에 따라 메시지를 필터링 할 수 있습니다. 앞서 언급했듯이 이러한 규칙을 작성하는 데 몇 가지 옵션이 있습니다. 이를 위해 Java, Scala, Groovy 또는 XML을 사용할 수 있습니다.
이제 우리는 Camel의 가장 중요한 구성 요소에 대해 설명합니다. CamelContext.
CamelContext 다음 그림과 같이 Camel의 다른 모든 서비스에 대한 액세스를 제공합니다.
다양한 서비스를 살펴 보겠습니다. 그만큼Registry모듈은 기본적으로 애플리케이션이 사용하는 다양한 Javabean의 이름을 보유하는 JNDI 레지스트리입니다. Camel을 Spring과 함께 사용한다면 이것이 Spring이 될 것입니다.ApplicationContext. OSGI 컨테이너에서 Camel을 사용하는 경우OSGI registry. 그만큼Type converters이름에서 알 수 있듯이 입력을 한 형식에서 다른 형식으로 변환하는로드 된 다양한 형식 변환기가 포함되어 있습니다. 내장형 변환기를 사용하거나 자체 변환 메커니즘을 제공 할 수 있습니다. 그만큼Components모듈에는 애플리케이션에서 사용하는 구성 요소가 포함됩니다. 구성 요소는 자동 검색에 의해로드됩니다.classpath지정합니다. OSGI 컨테이너의 경우 새 번들이 활성화 될 때마다로드됩니다. 우리는 이미Endpoints 과 Routes이전 장에서. 그만큼Data formats 모듈은로드 된 데이터 형식을 포함하고 마지막으로 Languages 모듈은로드 된 언어를 나타냅니다.
여기에있는 코드 스 니펫을 통해 CamelContext Camel 응용 프로그램에서 생성됩니다-
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
// Configure filters and routes
}
}
);
그만큼 DefaultCamelContext 클래스는 구체적인 구현을 제공합니다 CamelContext. 에addRoutes 메서드의 익명 인스턴스를 만듭니다. RouteBuilder. 여러 개를 만들 수 있습니다.RouteBuilder둘 이상의 라우팅을 정의하는 인스턴스. 동일한 컨텍스트의 각 경로에는 고유 한 ID가 있어야합니다. 런타임에 경로를 동적으로 추가 할 수 있습니다. 이전에 정의한 것과 동일한 ID를 가진 경로가 이전 경로를 대체합니다.
안에 들어가는 것 RouteBuilder 인스턴스는 다음에 설명됩니다.
노선
라우터는 메시지 이동 규칙을 정의합니다. from 에 to위치. 너는 사용한다RouteBuilderJava DSL에서 경로를 정의합니다. 내장 된 경로를 확장하여 경로를 만듭니다.RouteBuilder수업. 경로는from하나 이상의 끝점에서 끝납니다. 둘 사이에서 처리 논리를 구현합니다. 하나의 경로 내에서 원하는 수의 경로를 구성 할 수 있습니다.configure 방법.
다음은 경로가 생성되는 일반적인 예입니다.
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.to("stream:out");
}
}
구성 방법을 재정의합니다. RouteBuilder클래스를 만들고 라우팅 및 필터링 메커니즘을 구현합니다. 현재의 경우 엔드 포인트에서받은 입력을 리디렉션합니다.DistributeOrderDSL 엔드 포인트에서 지정한 콘솔에 stream:out.
언어 선택
다른 언어로 경로를 만들 수 있습니다. 다음은 동일한 경로가 세 가지 언어로 정의되는 방법에 대한 몇 가지 예입니다.
자바 DSL
from ("file:/order").to("jms:orderQueue");
봄 DSL
<route>
<from uri = "file:/order"/>
<to uri = "jms:orderQueue"/>
</route>
스칼라 DSL
from "file:/order" -> "jms:orderQueue"
필터
필터를 사용하여 입력 콘텐츠의 일부를 선택합니다. 필터를 설정하려면 임의의 Predicate 구현 을 사용합니다 . 필터링 된 입력은 원하는 대상 엔드 포인트로 전송됩니다. 이 예에서는 비누 공급 업체에 일괄 적으로 보낼 수 있도록 비누에 대한 모든 주문을 필터링합니다.
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product = 'soaps']/items"))
.to("stream:out");
이 예에서 우리는 xpath필터링을위한 술어. 필터링에 Java 클래스를 사용하려면 다음 코드를 사용하십시오.
from("direct:DistributeOrderDSL")
.filter()
.method(new Order(),"filter")
.to("stream:out");
그만큼 Order 자체 필터링 메커니즘이있는 사용자 정의 Java 클래스입니다.
여기와 같이 단일 라우팅에 여러 술어를 결합 할 수 있습니다.
from("direct:DistributeOrderDSL")
.choice()
.when(header("order").isEqualTo("oil"))
.to("direct:oil")
.when(header("order").isEqualTo("milk"))
.to("direct:milk")
.otherwise()
.to("direct:d");
따라서 이제 모든 "석유"주문은 석유 공급 업체로, "우유"주문은 우유 공급 업체로, 나머지는 공동 풀로 이동합니다.
맞춤형 프로세서
사용자 지정 처리를 사용할 수도 있습니다. 아래 예제는myCustomProcessor 라우트 빌더에서 사용합니다.
Processor myCustomProcessor = new Processor() {
public void process(Exchange exchange) {
// implement your custom processing
}
};
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:DistributeOrderDSL")
.process(myProcessor);
}
};
선택 및 필터링과 함께 사용자 지정 프로세서를 사용하여 중재 및 라우팅을 더 잘 제어 할 수 있습니다.
from("direct:DistributeOrderDSL")
.filter(header("order").isEqualTo("milk"))
.process(myProcessor);
XML 사용
원하는 경우 경로를 더 큰 XML로 정의 할 수 있습니다. 다음 XML 스 니펫은 Spring XML을 통해 일부 필터링과 함께 경로를 생성하는 방법을 보여줍니다.
<camelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "direct:DistributeOrderXML"/>
<log message = "Split by Distribute Order"/>
<split>
<xpath>//order[@product = 'Oil']/items</xpath>
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
</split>
</route>
</camelContext>
경로가 어떻게 구축되는지 살펴 보았으므로 이제 끝점을 만드는 다양한 기술을 살펴 보겠습니다.
통합 코드에서 엔드 포인트가 어떻게 보이는지에 대해 배웠습니다. 지금까지 사용한 표현은file:/order, jms:orderQueue, direct:distributeOrderDSL끝점입니다. 보시다시피 URI 사양 형식을 따릅니다. 이 URI를 평가하는 동안CamelContext 생성 Endpoint예; 인스턴스화에 대해 걱정할 필요가 없습니다.Endpoint DSL에서 구현.
이전 예제를 살펴보면 다음과 같이 Java DSL에서 엔드 포인트를 지정합니다.
from ("file:/order").to("jms:orderQueue");
그리고 여기와 같이 봄에-
<route>
<from uri = "file:/order"/>
<to uri = "jms:orderQueue"/>
</route>
두 경우 모두 끝점은 상수 문자열입니다. 어떤 경우에는 런타임에이 문자열을 빌드 할 수 있습니다. Java를 사용하여 수행 할 수 있습니다.String포맷터 메서드. Camel은 런타임에 이러한 URI 문자열을 생성하는 또 다른 간단한 방법을 제공합니다. 이를 위해 Camel은fromF 과 toF사용자 지정 매개 변수가있는 인수를 허용하는 메소드. 다음 문은toF 방법-
from("direct:distributeOrderDSL”).toF("file://%s?fileName=%s", path, name);
이러한 방법으로 인해 Java 내장 기능을 사용해야합니다. String 포맷터 메서드는 제거됩니다.
Camel은 기본적으로 단순 언어를 사용하여 엔드 포인트 표현식을 계산합니다. 그만큼Simple 언어는 주로 Expressions 과 Predicates복잡함을 신경 쓰지 않고 XPath. 술어를 평가하기 위해 다음과 같은 다른 언어를 결합 할 수 있습니다.xpath 기본값으로 Simple언어. 더하기 기호를 사용하여 다른 언어를 구분하면됩니다. 여기에있는 코드 스 니펫은 연결하는 방법을 보여줍니다.xpath 작성된 표현식에 대한 문자열 Simple.
from("direct:start")
.toD("jms:${orderQueue}+language:xpath:/order/@id");
에 Spring, 당신은 여기와 같은 것을 얻을 수 있습니다-
<route>
<from uri = "direct:start"/>
<toD uri = "jms:${orderQueue}+language:xpath:/order/@id"/>
</route>
원하는만큼의 언어를 연결할 수 있으며 각 언어는 이전 언어와 더하기 기호로 구분됩니다. 지원되는 언어 목록은 여기에서 확인할 수 있습니다 .
Camel은 몇 가지 사전 제작 된 구성 요소를 제공합니다.
이 장에서는 다음과 같은 몇 가지 중요한 구성 요소에 대해 설명합니다. camel-core 기준 치수.
콩
그만큼 Bean컴포넌트는 Bean을 Camel 메시지 교환에 바인딩합니다. 끝점을 만드는 URI는 다음과 같이 지정됩니다.bean:beanID, 어디 beanID 에 지정된 Bean의 이름입니다. Registry.
JndiContext jndiContext = new JndiContext();
jndiContext.bind("MilkOrder", new MilkOrderProcessor());
CamelContext camelContext = new DefaultCamelContext(jndiContext);
camelContext.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:bigBasket")
.to("bean:MilkOrder?method=placeOrder");
}
});
엔드 포인트가 bean:실험 계획안. 호출 될 Bean 메소드를 선택적으로 지정할 수 있습니다. 이 경우 호출 된 메서드placeOrderEndpoint 표현식을 평가하는 동안 호출됩니다. 그만큼MilkOrder JNDI 이름입니다. MilkOrderProcessor코드 조각의 처음 두 줄에 등록 된 Javabean 정의MilkOrderProcessor 여기서는 간결함을 위해 생략했습니다.
곧장
당신은 Direct이전 예에서. 석유 공급 업체에 주문을 보내기 위해direct:oil끝점 사양에서. 사용Direct구성 요소를 사용하면 엔드 포인트를 동 기적으로 호출 할 수 있습니다. 이전 예제의 다음 두 코드 스 니펫은Direct −
.when(header("order").isEqualTo("oil"))
.to("direct:oil")
과,
from("direct:DistributeOrderDSL")
.process(myProcessor);
파일
그만큼 File구성 요소는 컴퓨터의 파일 시스템에 대한 액세스를 제공합니다. 이 구성 요소를 사용하면 다른 구성 요소의 메시지를 로컬 디스크에 저장할 수 있습니다. 또한 다른 Camel 구성 요소가 로컬 파일을 처리 할 수 있습니다. 둘 중 하나를 사용할 수 있습니다.file:directoryName[?options] 또는 file://directoryName[?options]파일 구성 요소를 사용하는 동안 URI 형식으로. 이전에이 구성 요소의 사용을 확인했습니다.
from ("file:/order").to("jms:orderQueue");
참고 File구성 요소는 기본적으로 디렉토리 이름을 사용합니다. 따라서 주문 디렉토리의 내용이 입력 내용으로 사용됩니다. 특정 파일을 지정하려면order 디렉토리에서 다음 문을 사용합니다.
from ("file:/order?fileName = order.xml").to("jms:orderQueue");
로그
그만큼 Log구성 요소를 사용하면 기본 로깅 메커니즘에 메시지를 로깅 할 수 있습니다. Camel은 SLF4J (Simple Logging Facade for Java)를 다양한 로깅 프레임 워크에 대한 추상화로 사용합니다. 당신은 사용할 수 있습니다java.util.logging, logback, log4j로깅을 위해. 이 코드 스 니펫은Log 성분-
from("direct:DistributeOrderDSL")
.to("bean:MilkOrder?method = placeOrder")
.to("log:com.example.com?level = INFO&showBody = true");
SEDA
그만큼 SEDA 구성 요소를 사용하면 동일한 CamelContext. CamelContext 인스턴스를 통해 호출하려면 다음을 사용해야합니다.VM구성 요소. SEDA의 사용은 다음과 같습니다.
from("direct:DistributeOrderDSL")
// send it to the seda queue that is async
.to("seda:nextOrder")
이 경로에서는 단순히 주문을 nextOrder비동기 대기열. 이 큐를 구독 한 클라이언트는이 큐에서 메시지를 선택합니다.
시간제 노동자
그만큼 Timer구성 요소는 정기적으로 메시지를 보내는 데 사용되므로 Camel 응용 프로그램을 테스트하는 동안 매우 유용 할 수 있습니다. 여기 코드 조각은 2 초마다 콘솔에 테스트 메시지를 보냅니다.
from("timer://testTimer?period = 2000")
.setBody()
.simple("This is a test message ${header.timer}")
.to("stream:out");
대부분의 통합 프로젝트는 느슨하게 결합 된 애플리케이션 아키텍처를 만드는 데 도움이되는 메시징을 사용합니다. 메시징은 동기 또는 비동기 일 수 있습니다. JMS는point-to-point 과 publish-subscribe모델. 당신은Queue 지점 간 및 Topic발행-구독 모델의 경우. Java 플랫폼에서 JMS-Java Messaging Service는 메시징 서버에 대한 인터페이스를 제공합니다. Apache activeMQ는 그러한 오픈 소스 JMS 공급자 중 하나입니다. Camel은 JMS 공급자와 함께 제공되지 않습니다. 그러나 activeMQ를 사용하도록 구성 할 수 있습니다. 이 구성 요소를 사용하려면 프로젝트에 다음 jar (activemq, camel-spring 및 camel-jms)를 포함해야합니다.
다음 코드 스 니펫은 activeMQ에 대해 Camel을 구성하는 방법을 보여줍니다.
<bean id = "jms" class = "org.apache.camel.component.jms.JmsComponent">
<property name = "connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name = "orderQueue" value = "tcp://localhost:61000" />
</bean>
</property>
</bean>
여기서 Camel 애플리케이션은 다음과 같은 큐를 듣기 시작합니다. orderQueue. 대기열 자체는 로컬 호스트에서 실행되고 포트 61000에 나열되는 activeMQ 메시징 서버에 설정됩니다.이 작업이 완료되면 응용 프로그램은 응용 프로그램에 정의 된 모든 끝점에서이 대기열로 메시지를 보내거나받을 수 있습니다.
마지막으로, Camel 애플리케이션이 어떻게 생성되는지 더 깊이 이해하기 위해 모든 것을 프로젝트에 통합 할 때입니다.
Maven을 사용하여 Camel 프로젝트를 빌드합니다. 그러나 우리는 개발을 위해 IntelliJ IDE를 선호했습니다. 이 프로젝트에 원하는 IDE를 사용할 수 있습니다.
새 프로젝트 생성
새로 만들기 Maven 프로젝트를 지정하고 다음을 지정하십시오-
GroupId: Basket
ArtifactId: Basket
프로젝트의 기본 위치를 선택하거나 원하는 경우 원하는 디렉토리를 지정하십시오.
종속성 추가
Camel을 사용하려면 몇 가지 종속성을 추가해야합니다. 종속성이 추가되었습니다.pom.xml. 따라서 pom.xml을 열고 다음 두 가지 종속성을 추가하십시오.
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stream</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
Note− 애플리케이션에 대한 최소한의 종속성이 필요합니다. 라이브러리에서 더 많은 Camel 구성 요소를 사용함에 따라이 pom.xml 파일에 해당 종속성을 추가해야합니다.
Java DSL 생성
다음으로 Java DSL에서 필터링 및 라우팅 코드를 작성합니다. 라는 새 Java 클래스를 만듭니다.DistributeOrderDSL. 그것에 다음 코드를 추가하십시오-
public class DistributeOrderDSL {
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product='soaps']/items")).to("stream:out");
// .to("file:src/main/resources/order/");
}
});
context.start();
ProducerTemplate orderProducerTemplate = context.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
orderProducerTemplate.sendBody("direct:DistributeOrderDSL", orderInputStream);
} finally {
context.stop();
}
}
}
에서 main 방법, 먼저 우리는 CamelContext 에 제공된 기본 구현을 인스턴스화하여 DefaultCamelContext 수업.
CamelContext context = new DefaultCamelContext();
다음으로 익명을 생성하여 경로를 추가합니다. RouteBuilder 인스턴스-
context.addRoutes(new RouteBuilder() {
우리는 configure 직접 URI에서 경로를 추가하는 방법 DistributeOrderDSL시스템 콘솔에. xpath 쿼리를 사용하여 일부 필터링을 제공합니다.
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product = 'soaps']/items")).to("stream:out");
// .to("file:src/main/resources/order/");
}
경로를 추가 한 후 컨텍스트를 시작합니다.
context.start();
다음으로 직접 URI를 만들기위한 코드를 추가합니다. DistributeOrderDSL.
ProducerTemplate orderProducerTemplate = context.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
마지막으로 처리를 시작합니다.
orderProducerTemplate.sendBody("direct:DistributeOrderDSL", orderInputStream);
이제 Java DSL 코드가 완성되면 응용 프로그램을 테스트하기 전에 남은 유일한 것은 order.xml프로젝트에 파일을 추가하십시오. 이를 위해 소개 장에 표시된 샘플 XML을 사용할 수 있습니다.
시험 결과
응용 프로그램을 실행하면 다음 출력이 표시됩니다.
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
여기에는 비누 주문 만 나열됩니다. 이것을 로컬 파일에 저장하려면stream.out 다음 줄의 주석 처리를 제거하십시오. configure 방법-
// .to("file:src/main/resources/order/");
다음 섹션에서는 Spring과 함께 Camel을 사용하는 방법을 배웁니다.
이제 Spring을 사용하여 이전 장에서 응용 프로그램을 다시 만들 것입니다. 이것은 DSL이 아닌 XML로 Camel 라우팅을 만드는 방법에 대한 아이디어를 제공합니다.
새 프로젝트 생성
새로 만들기 Maven 프로젝트를 지정하고 다음을 지정하십시오-
GroupId: BasketWithSpring
ArtifactId: BasketWithSpring
프로젝트의 기본 위치를 선택하거나 원하는 경우 원하는 디렉토리를 지정하십시오.
종속성 추가
이전 애플리케이션에서 사용한 핵심 종속성 외에도 Spring을 사용하려면 몇 가지 종속성을 더 추가해야합니다. 종속성은 pom.xml에 추가됩니다. 이제 pom.xml을 열고 다음 종속성을 추가하십시오.
<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.2</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.15.1</version>
</dependency>
</dependencies>
Spring 용 Java DSL 생성
이제 새로운 Java 클래스를 생성하겠습니다. DistributeOrderXML. 그것에 다음 코드를 추가하십시오-
public class DistributeOrderXML {
public static void main(String[] args) throws Exception {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"SpringRouteContext.xml");
CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
try {
camelContext.start();
ProducerTemplate orderProducerTemplate = camelContext.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
orderProducerTemplate.sendBody("direct:DistributeOrderXML", orderInputStream);
} finally {
camelContext.stop();
}
}
}
에서 main 메서드, 먼저 인스턴스를 만듭니다. ApplicationContext, 이는 Spring 애플리케이션 내의 중앙 인터페이스입니다. 생성자에서 라우팅 및 필터링 정보가 포함 된 XML 파일의 이름을 지정합니다.
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"SpringRouteContext.xml");
다음으로 우리는 CamelContext 위에서 만든 지정 ApplicationContext 매개 변수에서.
CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
이 시점에서 라우팅 및 필터링이 설정됩니다. 따라서 우리는CamelContext 그것의 사용 start방법. 이전의 경우와 마찬가지로 order.xml 파일을로드하기위한 Endpoint를 정의하고 처리를 시작합니다. 이제 라우팅이 XML에서 어떻게 정의되는지 이해하겠습니다.
애플리케이션 컨텍스트 생성
프로젝트에 새 XML 파일을 추가하고 호출하십시오. SpringRouteContext.xml. 다음 내용을 잘라내어이 파일에 붙여 넣습니다.
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd ">
<camelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "direct:DistributeOrderXML"/>
<log message = "Split by Distribute Order"/>
<split>
<xpath>//order[@product = 'Oil']/items</xpath>
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
</split>
</route>
</camelContext>
</beans>
여기에서 xpath 쿼리를 다음과 같이 정의합니다. 이제 "oil"에 대한 모든 주문을 선택합니다.
<xpath>//order[@product = 'Oil']/items</xpath>
출력 끝점은 여러 개입니다. 첫 번째 끝점은order 두 번째 폴더는 콘솔을 지정합니다.
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
응용 프로그램을 실행하십시오.
시험 결과
응용 프로그램을 실행하면 화면에 다음 출력이 표시됩니다.
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
확인 order사용자가 지정한 경로의 폴더. 위의 XML 코드를 포함하는 새로 생성 된 파일을 찾을 수 있습니다.
결론
Camel은 통합 프로젝트를 용이하게하기 위해 EIP를 구현하는 즉시 사용 가능한 프레임 워크를 제공합니다. 도메인 별 언어 코딩과 XML 사용을 지원합니다.