Apache Camel dengan Spring Boot

1. Ikhtisar

Pada intinya, Apache Camel adalah mesin integrasi, yang - sederhananya - dapat digunakan untuk memfasilitasi interaksi antara beragam teknologi.

Jembatan antara layanan dan teknologi ini disebut rute. Rute diimplementasikan pada mesin ( CamelContext ), dan mereka berkomunikasi dengan apa yang disebut "pertukaran pesan".

2. Ketergantungan Maven

Untuk memulai, kita perlu menyertakan dependensi 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 dependensi Apache Camel dapat ditemukan di sini.

3. Kelas Utama

Mari pertama-tama buat Aplikasi Spring Boot :

@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

Sekarang mari kita konfigurasikan aplikasi kita dengan Spring, dimulai dengan file konfigurasi (properti).

Misalnya, 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 file application.properties yang juga menyetel jalur ke konfigurasi Logback. Dengan menyetel IP ke "0.0.0.0", kami sepenuhnya membatasi akses admin dan manajemen di server web yang disediakan oleh Spring Boot. Selain itu, kami mengaktifkan akses jaringan yang diperlukan ke titik akhir aplikasi kami serta titik akhir pemeriksaan kesehatan.

File konfigurasi lainnya adalah application.yml . Di dalamnya, kami akan menambahkan beberapa properti untuk membantu kami memasukkan nilai ke dalam rute 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 Camel Servlet

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

Seperti yang disebutkan sebelumnya, dengan Camel versi 2.18 dan yang lebih lama, kita dapat memanfaatkan application.yml kita - dengan membuat parameter untuk URL final kita. Nanti akan disuntikkan ke kode Java kita:

baeldung: api: path: '/camel'

Kembali ke kelas Aplikasi kita, kita perlu mendaftarkan servlet Camel di root jalur konteks kita, yang akan disuntikkan dari referensi baeldung.api.path di application.yml ketika aplikasi dimulai:

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

Sejak Camel versi 2.19, konfigurasi ini telah dihapus karena CamelServlet secara default disetel ke "/ camel" .

6. Membangun Rute

Mari mulai membuat rute dengan memperluas kelas RouteBuilder dari Camel, dan menyetelnya sebagai @Component sehingga rutinitas pemindaian komponen dapat menemukannya selama inisialisasi server web:

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

Di kelas ini, kami mengganti metode configure () dari kelas RouteBuilder Camel .

Camel selalu membutuhkan instance CamelContext - komponen inti tempat menyimpan pesan masuk dan keluar.

Dalam contoh sederhana ini, DefaultCamelContext sudah cukup karena hanya mengikat pesan dan merutekan ke dalamnya, seperti layanan REST yang akan kita buat.

6.1. The restConfiguration () Route

Selanjutnya, kami membuat deklarasi REST untuk titik akhir yang kami rencanakan untuk dibuat di metode 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 jalur konteks dengan atribut yang disuntikkan kami dari file YAML. Logika yang sama diterapkan pada port aplikasi kita. CORS diaktifkan, memungkinkan penggunaan lintas situs dari layanan web ini. Mode mengikat memungkinkan dan mengubah argumen ke API kami.

Selanjutnya, kami menambahkan dokumentasi Swagger ke URI, judul, dan versi yang sebelumnya kami setel. Saat kami membuat metode / titik akhir untuk layanan web REST kami, dokumentasi Swagger akan diperbarui secara otomatis.

Konteks Kesombongan ini sendiri merupakan rute Unta, dan kita dapat melihat beberapa informasi teknis tentang hal itu di log server selama proses permulaan. Dokumentasi contoh kami secara default disajikan di // localhost: 8080 / camel / api-doc.

6.2. The sisanya () Route

Sekarang, mari kita implementasikan pemanggilan metode rest () dari metode configure () yang tercantum di atas:

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

Metode ini sangat mudah bagi mereka yang akrab dengan API. The id adalah identifikasi dari rute dalam CamelContext . Baris berikutnya mendefinisikan tipe MIME. Mode penjilidan didefinisikan di sini untuk menunjukkan bahwa kita dapat menyetel mode pada restConfiguration () .

Metode post () menambahkan operasi ke API, menghasilkan titik akhir " POST / kacang ", sedangkan MyBean (kacang Java biasa dengan id Integer dan nama String ) mendefinisikan parameter yang diharapkan.

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

Terakhir, metode to () membuat jembatan ke rute lain. Di sini ia memberitahu Camel untuk mencari di dalam konteks / mesinnya ke rute lain yang akan kita buat - yang dinamai dan dideteksi oleh nilai / id " direct: ... ", mencocokkan rute yang ditentukan dalam metode from () .

6.3. The from() Route With transform()

When working with Camel, a route receives parameters and then converts, transforms and process these parameters. After that, it sends these parameters to another route that forwards the result to the desired output (a file, a database, an SMTP server or a REST API response).

In this article, we only create another route inside the configure() method that we are overriding. It will be the destination route for our last to() route:

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

The from() method follows the same principles and has many of the same methods as the rest() method, except that it consumes from the Camel context messages. This is the reason for the parameter “direct-route“, that creates a link to the aforementioned method rest().to().

Many other conversions are available, including extraction as Java primitives (or objects) and sending it down to a persistence layer. Notice that the routes always read from incoming messages, so that chained routes will ignore outgoing messages.

Our example is ready, and we can try it:

  • Run the prompt command: 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 dapat ditemukan di GitHub.

Terakhir, di luar API filter () , process () , transform () , dan marshall () , banyak pola integrasi dan manipulasi data lainnya tersedia di Camel:

  • Pola Integrasi Unta
  • Panduan Pengguna Unta
  • Unta SEDERHANA Bahasa