295장. Camel SCR(더 이상 사용되지 않음)
Camel 2.15부터 사용 가능
SCR은 Service Component Runtime의 약자이며 OSGi 선언 서비스 사양의 구현입니다. SCR을 사용하면 일반 이전 Java 오브젝트가 상용구 코드 없이 OSGi 서비스를 노출하고 사용할 수 있습니다.
OSGi 프레임워크는 번들의 SCR 설명자 파일을 확인하여 일반적으로 org.apache.fe Cryostat:maven-scr-plugin
과 같은 플러그인을 통해 Java 주석에서 생성되는 SCR 설명자 파일을 확인하여 오브젝트를 알고 있습니다.
SCR 번들에서 Camel을 실행하는 것은 귀하와 OSGi 프레임워크 간에 코드 라인이 크게 적을 수 있는 Spring DM 및 블루프린트 기반 솔루션에 대한 좋은 대안입니다. SCR을 사용하면 번들이 완전히 Java 세계에서 유지될 수 있습니다. XML 또는 속성 파일을 편집할 필요가 없습니다. 이를 통해 모든 것을 완벽하게 제어 할 수 있으며 선택한 IDE가 프로젝트에서 어떤 일이 진행되고 있는지 정확히 알고 있음을 의미합니다.
295.1. Camel SCR 지원
Camel-scr 번은 Apache Camel 버전 2.15.0 이전에는 포함되어 있지 않지만 2.12.0 이후의 Camel 버전과 함께 아티팩트 자체를 사용할 수 있습니다.
org.apache.camel/camel-scr
번들은 기본 클래스를 제공합니다. AbstractCamelRunner
에서는 유닛 테스트에서 SCR 속성을 사용하기 위한 Camel 컨텍스트와 도우미 클래스인 ScrHelper
를 관리합니다. Apache Karaf의 Camel-scr 기능은 SCR 번들에서 Camel을 실행하는 데 필요한 모든 기능과 번들을 정의합니다.
AbstractCamelRunner
클래스는 CamelContext의 라이프사이클을 Service Component의 라이프사이클에 연결하고 Camel의 PropertiesComponent를 통해 구성을 처리합니다. Java 클래스에서 서비스 구성 요소를 만들기 위해 수행해야 하는 것은 AbstractCamelRunner
에서 확장한 후 클래스 수준에서 다음 org.apache.fe Cryostat.scr.annotations
를 추가하는 것입니다.
필요한 주석 추가
@Component @References({ @Reference(name = "camelComponent",referenceInterface = ComponentResolver.class, cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, bind = "gotCamelComponent", unbind = "lostCamelComponent") })
그런 다음 실행할 Camel 경로를 반환하는 getRouteBuilders()
메서드를 구현합니다.
getRouteBuilders() 구현
@Override protected List<RoutesBuilder> getRouteBuilders() { List<RoutesBuilder> routesBuilders = new ArrayList<>(); routesBuilders.add(new YourRouteBuilderHere(registry)); routesBuilders.add(new AnotherRouteBuilderHere(registry)); return routesBuilders; }
마지막으로 다음과 같은 기본 구성을 제공합니다.
주석의 기본 구성
@Properties({ @Property(name = "camelContextId", value = "my-test"), @Property(name = "active", value = "true"), @Property(name = "...", value = "..."), ... })
모든 것입니다. 그리고 camel-archetype-scr
을 사용하여 프로젝트를 생성하는 경우 이 모든 것이 이미 처리되어 있습니다.
다음은 camel-archetype-scr
에 의해 생성된 완전한 Service Component 클래스의 예입니다.
CamelScrExample.java
// This file was generated from org.apache.camel.archetypes/camel-archetype-scr/2.15-SNAPSHOT package example; import java.util.ArrayList; import java.util.List; import org.apache.camel.scr.AbstractCamelRunner; import example.internal.CamelScrExampleRoute; import org.apache.camel.RoutesBuilder; import org.apache.camel.spi.ComponentResolver; import org.apache.felix.scr.annotations.*; @Component(label = CamelScrExample.COMPONENT_LABEL, description = CamelScrExample.COMPONENT_DESCRIPTION, immediate = true, metatype = true) @Properties({ @Property(name = "camelContextId", value = "camel-scr-example"), @Property(name = "camelRouteId", value = "foo/timer-log"), @Property(name = "active", value = "true"), @Property(name = "from", value = "timer:foo?period=5000"), @Property(name = "to", value = "log:foo?showHeaders=true"), @Property(name = "messageOk", value = "Success: {{from}} -> {{to}}"), @Property(name = "messageError", value = "Failure: {{from}} -> {{to}}"), @Property(name = "maximumRedeliveries", value = "0"), @Property(name = "redeliveryDelay", value = "5000"), @Property(name = "backOffMultiplier", value = "2"), @Property(name = "maximumRedeliveryDelay", value = "60000") }) @References({ @Reference(name = "camelComponent",referenceInterface = ComponentResolver.class, cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, bind = "gotCamelComponent", unbind = "lostCamelComponent") }) public class CamelScrExample extends AbstractCamelRunner { public static final String COMPONENT_LABEL = "example.CamelScrExample"; public static final String COMPONENT_DESCRIPTION = "This is the description for camel-scr-example."; @Override protected List<RoutesBuilder> getRouteBuilders() { List<RoutesBuilder> routesBuilders = new ArrayList<>(); routesBuilders.add(new CamelScrExampleRoute(registry)); return routesBuilders; } }
CamelContextId
및 활성
속성은 CamelContext의 이름(기본값: "camel-runner-default")과 시작 여부를 각각 제어합니다(기본값: "false"). 이러한 속성 외에도 원하는 만큼의 속성을 추가하고 사용할 수 있습니다.In addition to these you can add and use as many properties as you like. Camel의 PropertiesComponent는 재귀 속성을 처리하고 문제가 없는 대체 속성을 접두사로 지정합니다.
AbstractCamelRunner
는 Camel의 PropertiesComponent를 통해 RouteBuilders에서 이러한 속성을 사용할 수 있도록 하며 이름이 일치하는 경우 서비스 구성 요소 및 RouteBuilder 필드에 이러한 값을 삽입합니다. 필드는 가시성 수준을 사용하여 선언할 수 있으며 많은 유형이 지원됩니다(문자열, int, boolean, URL, …).
다음은 camel-archetype-scr
에 의해 생성된 RouteBuilder 클래스의 예입니다.
CamelScrExampleRoute.java
// This file was generated from org.apache.camel.archetypes/camel-archetype-scr/2.15-SNAPSHOT package example.internal; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.SimpleRegistry; import org.apache.commons.lang.Validate; public class CamelScrExampleRoute extends RouteBuilder { SimpleRegistry registry; // Configured fields private String camelRouteId; private Integer maximumRedeliveries; private Long redeliveryDelay; private Double backOffMultiplier; private Long maximumRedeliveryDelay; public CamelScrExampleRoute(final SimpleRegistry registry) { this.registry = registry; } @Override public void configure() throws Exception { checkProperties(); // Add a bean to Camel context registry registry.put("test", "bean"); errorHandler(defaultErrorHandler() .retryAttemptedLogLevel(LoggingLevel.WARN) .maximumRedeliveries(maximumRedeliveries) .redeliveryDelay(redeliveryDelay) .backOffMultiplier(backOffMultiplier) .maximumRedeliveryDelay(maximumRedeliveryDelay)); from("{{from}}") .startupOrder(2) .routeId(camelRouteId) .onCompletion() .to("direct:processCompletion") .end() .removeHeaders("CamelHttp*") .to("{{to}}"); from("direct:processCompletion") .startupOrder(1) .routeId(camelRouteId + ".completion") .choice() .when(simple("${exception} == null")) .log("{{messageOk}}") .otherwise() .log(LoggingLevel.ERROR, "{{messageError}}") .end(); } } public void checkProperties() { Validate.notNull(camelRouteId, "camelRouteId property is not set"); Validate.notNull(maximumRedeliveries, "maximumRedeliveries property is not set"); Validate.notNull(redeliveryDelay, "redeliveryDelay property is not set"); Validate.notNull(backOffMultiplier, "backOffMultiplier property is not set"); Validate.notNull(maximumRedeliveryDelay, "maximumRedeliveryDelay property is not set"); } }
CamelScrExampleRoute
에 대해 자세히 살펴보겠습니다.
// Configured fields private String camelRouteId; private Integer maximumRedeliveries; private Long redeliveryDelay; private Double backOffMultiplier; private Long maximumRedeliveryDelay;
이러한 필드의 값은 해당 이름과 일치하여 속성의 값으로 설정됩니다.
// Add a bean to Camel context registry registry.put("test", "bean");
CamelContext의 경로에 일부 빈을 추가해야 하는 경우 다음과 같이 수행할 수 있습니다.
public void checkProperties() { Validate.notNull(camelRouteId, "camelRouteId property is not set"); Validate.notNull(maximumRedeliveries, "maximumRedeliveries property is not set"); Validate.notNull(redeliveryDelay, "redeliveryDelay property is not set"); Validate.notNull(backOffMultiplier, "backOffMultiplier property is not set"); Validate.notNull(maximumRedeliveryDelay, "maximumRedeliveryDelay property is not set"); }
필요한 매개변수가 설정되었는지 확인하고 경로를 시작하기 전에 의미 있는 값이 있는지 확인하는 것이 좋습니다.
from("{{from}}") .startupOrder(2) .routeId(camelRouteId) .onCompletion() .to("direct:processCompletion") .end() .removeHeaders("CamelHttp*") .to("{{to}}"); from("direct:processCompletion") .startupOrder(1) .routeId(camelRouteId + ".completion") .choice() .when(simple("${exception} == null")) .log("{{messageOk}}") .otherwise() .log(LoggingLevel.ERROR, "{{messageError}}") .end();
경로의 거의 모든 항목은 속성으로 구성됩니다. 이는 기본적으로 RouteBuilder를 템플릿으로 만듭니다. SCR을 사용하면 대체 구성을 제공하여 경로 인스턴스를 추가로 생성할 수 있습니다. Camel SCR 번들을 템플릿으로 사용하는 섹션에서 자세히 설명합니다.