Spring Boot付きApacheキャメル

Spring Bootを使用したApache Camel

1. 概要

その中心にあるApache Camelは統合エンジンであり、簡単に言えば、多種多様なテクノロジーの相互作用を促進するために使用できます。

サービスとテクノロジーの間のこれらのブリッジはroutes.と呼ばれます。ルートはエンジン(CamelContext)に実装され、いわゆる「交換メッセージ」と通信します。

2. Mavenの依存関係

まず、Spring Boot、Camel、SwaggerとJSONを使用したRestAPIの依存関係を含める必要があります。


    
        org.apache.camel
        camel-servlet-starter
        ${camel.version}
    
    
        org.apache.camel
        camel-jackson-starter
        ${camel.version}
    
    
        org.apache.camel
        camel-swagger-java-starter
        ${camel.version}
    
    
        org.apache.camel
        camel-spring-boot-starter
        ${camel.version}
    
    
        org.springframework.boot
        spring-boot-starter-web
        ${spring-boot-starter.version}
    

Apache Camelの依存関係の最新バージョンはhereにあります。

3. メインクラス

まず、Spring BootApplicationを作成しましょう。

@SpringBootApplication
@ComponentScan(basePackages="com.example.camel")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

4. SpringBootのCamel構成

それでは、構成ファイル(プロパティ)から始めて、Springを使用してアプリケーションを構成しましょう。

たとえば、src/main/resourcesapplication.propertiesファイルにアプリケーションのログを構成しましょう。

logging.config=classpath:logback.xml
camel.springboot.name=MyCamel
server.address=0.0.0.0
management.address=0.0.0.0
management.port=8081
endpoints.enabled = true
endpoints.health.enabled = true

この例は、ログバック構成へのパスも設定するapplication.propertiesファイルを示しています。 IPを「0.0.0.0」に設定することにより、Spring Bootが提供するWebサーバーでのadminおよびmanagementアクセスを完全に制限します。 また、アプリケーションエンドポイントおよびヘルスチェックエンドポイントへの必要なネットワークアクセスを有効にします。

別の構成ファイルはapplication.ymlです。 その中に、アプリケーションルートに値を挿入するのに役立ついくつかのプロパティを追加します。

server:
  port: 8080
camel:
  springboot:
    name: ServicesRest
management:
  port: 8081
endpoints:
  enabled: false
  health:
    enabled: true
quickstart:
  generateOrderPeriod: 10s
  processOrderPeriod: 30s

5. Setting up the Camel Servlet

Camelの使用を開始する1つの方法は、Camelをサーブレットとして登録し、HTTP要求をインターセプトしてアプリケーションにリダイレクトできるようにすることです。

前述のように、Camelのバージョン2.18以下を使用すると、最終的なURLのパラメーターを作成することで、application.ymlを利用できます。 その後、Javaコードに挿入されます。

example:
  api:
    path: '/camel'

Applicationクラスに戻ると、コンテキストパスのルートにCamelサーブレットを登録する必要があります。これは、アプリケーションの起動時にapplication.ymlの参照example.api.pathから挿入されます。 :

@Value("${example.api.path}")
String contextPath;

@Bean
ServletRegistrationBean servletRegistrationBean() {
    ServletRegistrationBean servlet = new ServletRegistrationBean
      (new CamelHttpTransportServlet(), contextPath+"/*");
    servlet.setName("CamelServlet");
    return servlet;
}

Camelのバージョン2.19の時点で、CamelServletはデフォルトで“/camel”に設定されているため、この構成は削除されました。

6. ルートの構築

CamelからRouteBuilderクラスを拡張し、それを@Componentとして設定してルートの作成を開始し、コンポーネントスキャンルーチンがWebサーバーの初期化中にルートを見つけられるようにします。

@Component
class RestApi extends RouteBuilder {
    @Override
    public void configure() {
        CamelContext context = new DefaultCamelContext();

        restConfiguration()...
        rest("/api/")...
        from("direct:remoteService")...
    }
}

このクラスでは、CamelのRouteBuilderクラスのconfigure()メソッドをオーバーライドします。

Camel always needs a CamelContext instance –着信メッセージと発信メッセージが保持されるコアコンポーネント。

この簡単な例では、作成するRESTサービスのように、メッセージをバインドしてメッセージにルーティングするだけなので、DefaultCamelContextで十分です。

6.1. restConfiguration()ルート

次に、restConfiguration()メソッドで作成する予定のエンドポイントのREST宣言を作成します。

restConfiguration()
  .contextPath(contextPath)
  .port(serverPort)
  .enableCORS(true)
  .apiContextPath("/api-doc")
  .apiProperty("api.title", "Test REST API")
  .apiProperty("api.version", "v1")
  .apiContextRouteId("doc-api")
  .component("servlet")
  .bindingMode(RestBindingMode.json)

ここでは、YAMLファイルから挿入された属性でコンテキストパスを登録します。 同じロジックがアプリケーションのポートに適用されました。 CORSが有効になり、このWebサービスのクロスサイト使用が可能になります。 バインディングモードは、APIへの引数を許可および変換します。

次に、以前に設定したURI、タイトル、およびバージョンにSwaggerドキュメントを追加します。 REST Webサービスのメソッド/エンドポイントを作成すると、Swaggerドキュメントが自動的に更新されます。

このSwaggerコンテキストはそれ自体がCamelルートであり、起動プロセス中にサーバーログでそれに関するいくつかの技術情報を確認できます。 サンプルドキュメントはデフォルトでhttp://localhost:8080/camel/api-doc.で提供されます

6.2. rest()ルート

次に、上記のconfigure()メソッドからのrest()メソッド呼び出しを実装しましょう。

rest("/api/")
  .id("api-route")
  .consumes("application/json")
  .post("/bean")
  .bindingMode(RestBindingMode.json_xml)
  .type(MyBean.class)
  .to("direct:remoteService");

この方法は、APIに精通している人にとっては非常に簡単です。 idは、CamelContext内のルートのIDです。 次の行は、MIMEタイプを定義します。 バインディングモードは、restConfiguration()にモードを設定できることを示すためにここで定義されています。

post()メソッドはAPIに操作を追加し、「POST /bean」エンドポイントを生成しますが、MyBeanInteger idString nameを持つ通常のJava Bean )期待されるパラメータを定義します。

同様に、GET、PUT、DELETEなどのHTTPアクションもすべて、get()put()delete()の形式で使用できます。

最後に、to()メソッドは別のルートへのブリッジを作成します。 ここでは、コンテキスト/エンジン内で、作成する別のルートを検索するようにCamelに指示します。このルートは、from()で定義されたルートと一致する、値/ ID「direct: …」によって名前が付けられて検出されます。 sメソッド。

6.3. transform()を使用したfrom()ルート

Camelを使用する場合、ルートはパラメーターを受け取り、これらのパラメーターを変換、変換、および処理します。 その後、これらのパラメーターを別のルートに送信し、結果を目的の出力(ファイル、データベース、SMTPサーバー、またはREST API応答)に転送します。

この記事では、オーバーライドしているconfigure()メソッド内に別のルートのみを作成します。 これは、最後のto()ルートの宛先ルートになります。

from("direct:remoteService")
  .routeId("direct-route")
  .tracing()
  .log(">>> ${body.id}")
  .log(">>> ${body.name}")
  .transform().simple("Hello ${in.body.name}")
  .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200));

from()メソッドは、Camelコンテキストメッセージから消費することを除いて、rest()メソッドと同じ原則に従い、同じメソッドの多くを備えています。 これが、前述のメソッドrest().to()へのリンクを作成するパラメータ「direct-route」の理由です。

Many other conversions are available。これには、Javaプリミティブ(またはオブジェクト)としての抽出と、それを永続層に送信することが含まれます。 ルートは常に着信メッセージから読み取るため、チェーンルートは発信メッセージを無視します。

この例は準備ができており、試してみることができます。

  • プロンプトコマンドを実行します:mvn spring-boot:run

  • ヘッダーパラメータContent-Type: application/jsonとペイロード\{“id”: 1,”name”: “World”}を使用してhttp://localhost:8080/camel/api/beanにPOSTリクエストを実行します

  • 201の戻りコードと応答を受け取るはずです:Hello, World

6.4. シンプルなスクリプト言語

この例では、tracing()メソッドを使用してログを出力します。 $\{}プレースホルダーを使用していることに注意してください。これらは、SIMPLEと呼ばれるCamelに属するスクリプト言語の一部です。 インメッセージの本文のように、ルートを介して交換されるメッセージに適用されます。

この例では、SIMPLEを使用して、Camelメッセージ本文内のBean属性をログに出力しています。

transform()メソッドで示したように、これを使用して単純な変換を行うこともできます。

6.5. process()を使用したfrom()ルート

処理されたデータを返すためにサービスレイヤーを呼び出すなど、もっと意味のあることをしましょう。 SIMPLEは大量のデータ処理を目的としていないため、transform()process()メソッドに置き換えましょう。

from("direct:remoteService")
  .routeId("direct-route")
  .tracing()
  .log(">>> ${body.id}")
  .log(">>> ${body.name}")
  .process(new Processor() {
      @Override
      public void process(Exchange exchange) throws Exception {
          MyBean bodyIn = (MyBean) exchange.getIn().getBody();
          ExampleServices.example(bodyIn);
          exchange.getIn().setBody(bodyIn);
      }
  })
  .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200));

これにより、以前にtype()メソッドで定義されたものと同じBeanにデータを抽出し、ExampleServicesレイヤーで処理することができます。

以前にbindingMode()をJSONに設定したため、応答はすでに適切なJSON形式であり、POJOに基づいて生成されています。 これは、ExampleServicesクラスの場合:

public class ExampleServices {
    public static void example(MyBean bodyIn) {
        bodyIn.setName( "Hello, " + bodyIn.getName() );
        bodyIn.setId(bodyIn.getId() * 10);
    }
}

同じHTTPリクエストが、応答コード201と本文\{“id”: 10,”name”: “Hello, World”}で返されるようになりました。

7. 結論

数行のコードで、比較的完全なアプリケーションを作成できました。 すべての依存関係は、単一のコマンドで自動的に構築、管理、実行されます。 さらに、あらゆる種類のテクノロジーを結び付けるAPIを作成できます。

また、このアプローチは非常にコンテナに優しいため、必要に応じて簡単に複製できる非常に無駄のないサーバー環境が実現します。 追加の構成の可能性は、コンテナーテンプレート構成ファイルに簡単に組み込むことができます。

このRESTの例は、over on GitHubにあります。

最後に、filter()process()transform()、およびmarshall() API以外にも、Camelでは他の多くの統合パターンとデータ操作を利用できます。