Apache Camel dengan Spring Boot

1. Gambaran keseluruhan

Inti utamanya, Apache Camel adalah mesin integrasi, yang - secara sederhana - dapat digunakan untuk memfasilitasi interaksi antara berbagai teknologi yang luas dan beragam.

Jambatan antara perkhidmatan dan teknologi ini disebut laluan. Laluan dilaksanakan pada mesin ( CamelContext ), dan mereka berkomunikasi dengan apa yang disebut "pertukaran mesej".

2. Pergantungan Maven

Untuk memulakan, kita perlu memasukkan kebergantungan untuk Spring Boot, Camel, Rest API dengan Swagger dan JSON:

  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}  

Versi terbaru dari pergantungan Apache Camel boleh didapati di sini.

3. Kelas Utama

Mari kita mula-mula buat Boot Spring Permohonan :

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

4. Konfigurasi Unta untuk Spring Boot

Mari sekarang konfigurasikan aplikasi kita dengan Spring, bermula dengan fail konfigurasi (sifat).

Sebagai contoh, mari kita konfigurasikan log untuk aplikasi kita pada file application.properties di src / main / resources :

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

Contoh ini menunjukkan fail application.properties yang juga menetapkan jalan ke konfigurasi Logback. Dengan menetapkan IP ke "0.0.0.0", kami sepenuhnya membatasi akses admin dan pengurusan di pelayan web yang disediakan oleh Spring Boot. Juga, kami membolehkan akses rangkaian yang diperlukan ke titik akhir aplikasi kami dan juga titik akhir pemeriksaan kesihatan.

Fail konfigurasi lain ialah application.yml . Di dalamnya, kami akan menambahkan beberapa sifat untuk membantu kami memasukkan nilai ke dalam laluan aplikasi kami:

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

5 . Menyiapkan Servlet Camel

Salah satu cara untuk mulai menggunakan Camel adalah dengan mendaftarkannya sebagai servlet, sehingga dapat mencegat permintaan HTTP dan mengalihkannya ke aplikasi kami.

Seperti disebutkan sebelumnya, menatap Camel versi 2.18 ke bawah, kita dapat memanfaatkan aplikasi kita.yml - dengan membuat parameter untuk URL akhir kita. Nanti akan disuntikkan ke dalam kod Java kami:

baeldung: api: path: '/camel'

Kembali ke kelas Aplikasi kami , kami perlu mendaftarkan servlet Camel di akar jalan konteks kami, yang akan disuntik dari baeldung.api.path rujukan di application.yml ketika aplikasi dimulakan:

@Value("${baeldung.api.path}") String contextPath; @Bean ServletRegistrationBean servletRegistrationBean() { ServletRegistrationBean servlet = new ServletRegistrationBean (new CamelHttpTransportServlet(), contextPath+"/*"); servlet.setName("CamelServlet"); return servlet; }

Pada versi 2.19 Camel, konfigurasi ini telah dijatuhkan kerana CamelServlet secara default ditetapkan ke "/ unta" .

6. Membina Laluan

Mari mula membuat laluan dengan memperluas kelas RouteBuilder dari Camel, dan menetapkannya sebagai @Component supaya rutin imbasan komponen dapat mencarinya semasa permulaan pelayan web:

@Component class RestApi extends RouteBuilder { @Override public void configure() { CamelContext context = new DefaultCamelContext(); restConfiguration()... rest("/api/")... from("direct:remoteService")... } }

Di kelas ini, kami mengatasi kaedah configure () dari kelas Camel's RouteBuilder .

Camel selalu memerlukan contoh CamelContext - komponen inti di mana mesej masuk dan keluar disimpan.

Dalam contoh mudah ini, DefaultCamelContext cukup kerana ia hanya mengikat mesej dan laluan ke dalamnya, seperti perkhidmatan REST yang akan kita buat.

6.1. The restConfiguration () Route

Seterusnya, kami membuat deklarasi REST untuk titik akhir yang kami rencanakan untuk dibuat dalam kaedah restConfiguration () :

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)

Di sini, kami mendaftarkan jalan konteks dengan atribut yang disuntikkan dari fail YAML. Logik yang sama diterapkan ke port aplikasi kami. CORS diaktifkan, yang memungkinkan untuk menggunakan perkhidmatan web ini dari laman web. Mod pengikat membolehkan dan menukar argumen ke API kami.

Seterusnya, kami menambahkan dokumentasi Swagger ke URI, tajuk, dan versi yang kami tetapkan sebelumnya. Semasa kami membuat kaedah / titik akhir untuk perkhidmatan web REST kami, dokumentasi Swagger akan dikemas kini secara automatik.

Konteks Swagger ini sendiri merupakan laluan Camel, dan kita dapat melihat beberapa maklumat teknikal mengenainya di log pelayan semasa proses permulaan. Dokumentasi contoh kami secara lalai disajikan di // localhost: 8080 / unta / api-doc.

6.2. Yang lain () Route

Sekarang, mari kita laksanakan panggilan kaedah selebihnya () dari kaedah konfigurasi () yang disenaraikan di atas:

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

Kaedah ini cukup mudah bagi mereka yang biasa dengan API. The id ialah pengenalpastian laluan di dalam CamelContext . Baris seterusnya menentukan jenis MIME. Mod pengikat didefinisikan di sini untuk menunjukkan bahawa kita dapat menetapkan mod pada restConfiguration () .

Kaedah post () menambah operasi ke API, menghasilkan titik akhir " POST / bean ", sementara MyBean (kacang Java biasa dengan id Integer dan nama String ) menentukan parameter yang diharapkan.

Begitu juga, tindakan HTTP seperti GET, PUT dan DELETE semuanya tersedia juga dalam bentuk get () , put () , delete () .

Akhirnya, kaedah to () membuat jambatan ke laluan lain. Di sini ia memberitahu Camel untuk mencari di dalam konteks / mesinnya ke rute lain yang akan kita buat - yang diberi nama dan dikesan oleh nilai / id " langsung: ... ", sesuai dengan rute yang ditentukan dalam metode dari () .

6.3. Laluan dari () Dengan transformasi ()

Semasa bekerja dengan Camel, laluan menerima parameter dan kemudian menukar, mengubah dan memproses parameter ini. Setelah itu, ia mengirimkan parameter ini ke rute lain yang meneruskan hasilnya ke output yang diinginkan (file, pangkalan data, pelayan SMTP atau respons REST API).

Dalam artikel ini, kita hanya membuat laluan lain di dalam metode configure () yang kita ganti. Ini akan menjadi laluan tujuan untuk laluan terakhir ke () kami :

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

Kaedah dari () mengikuti prinsip yang sama dan mempunyai banyak kaedah yang sama dengan kaedah selebihnya () , kecuali bahawa ia menggunakan mesej konteks Camel. Ini adalah alasan untuk parameter " direct-route ", yang membuat pautan ke metode rehat yang disebutkan di atas (). Ke () .

Banyak penukaran lain tersedia , termasuk pengekstrakan sebagai primitif Java (atau objek) dan mengirimkannya ke lapisan kegigihan. Perhatikan bahawa laluan selalu dibaca dari mesej masuk, sehingga laluan yang dirantai akan mengabaikan mesej keluar.

Contoh kami sudah siap, dan kami boleh mencubanya:

  • Jalankan arahan prompt: mvn spring-boot: run
  • Do a POST request to //localhost:8080/camel/api/bean with header parameters: Content-Type: application/json, and a payload {“id”: 1,”name”: “World”}
  • We should receive a return code of 201 and the response: Hello, World

6.4. The SIMPLE Scripting Language

The example outputs logging using the tracing() method. Notice that we've used the ${} placeholders; these are part of a scripting language that belongs to Camel called SIMPLE. It is applied to messages that are exchanged over the route, like the body of the in-message.

In our example, we are using SIMPLE to output to the log the bean attributes that are inside the Camel message body.

We can also use it to do simple transformations as well, as was shown with the transform() method.

6.5. The from() Route With process()

Let's do something more meaningful, such as calling a service layer to return processed data. SIMPLE isn't meant for heavy data processing, so let's replace the transform() with a process() method:

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

This allows us to extract the data into a bean, the same one previously defined on the type() method, and process it in our ExampleServices layer.

Since we set the bindingMode() to JSON previously, the response already is in a proper JSON format, generated based on our POJO. This implies that for an ExampleServices class:

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

The same HTTP request now returns with a response code 201 and body: {“id”: 10,”name”: “Hello, World”}.

7. Conclusion

With a few lines of code, we managed to create a relatively complete application. All dependencies are built, managed and run automatically with a single command. Moreover, we can create APIs that tie together all sorts of technologies.

This approach is also very container friendly, resulting in a very lean server environment that can be easily replicated on demand. The extra configuration possibilities can easily be incorporated into a container template configuration file.

Contoh REST ini boleh didapati di GitHub.

Akhirnya, di luar API penapis () , proses () , transform () , dan marshall () , banyak corak integrasi dan manipulasi data lain terdapat di Camel:

  • Corak Integrasi Unta
  • Panduan Pengguna Unta
  • Bahasa SEDERHANA unta