Apache Camel med Spring Boot

1. Oversigt

Apache Camel er i sin kerne en integrationsmotor, som - enkelt sagt - kan bruges til at lette interaktioner mellem en bred og varieret vifte af teknologier.

Disse broer mellem tjenester og teknologier kaldes ruter. Ruter implementeres på en motor (den CamelContext), og de kommunikerer med såkaldte “udveksle beskeder”.

2. Maven-afhængigheder

For at starte skal vi medtage afhængigheder for Spring Boot, Camel, Rest API med Swagger og 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} 

De nyeste versioner af Apache Camel-afhængigheder kan findes her.

3. Hovedklassen

Lad os først oprette en Spring Boot Ansøgning:

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

4. Kamelkonfigurationer til fjederstøvle

Lad os nu konfigurere vores applikation med Spring, startende med konfigurationsfilerne (egenskaber).

Lad os f.eks. Konfigurere en log til vores applikation på en application.properties fil i src / main / ressourcer:

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

Dette eksempel viser en application.properties fil, der også angiver stien til en Logback-konfiguration. Ved at indstille IP til "0.0.0.0" begrænser vi fuldt ud admin og ledelse adgang på webserveren leveret af Spring Boot. Vi aktiverer også den nødvendige netværksadgang til vores applikationsendepunkter såvel som sundhedstjekendepunkterne.

En anden konfigurationsfil er ansøgning.yml. I det tilføjer vi nogle egenskaber, der hjælper os med at indsætte værdier i vores applikationsruter:

server: port: 8080 kamel: springboot: navn: Services Rest management: port: 8081 slutpunkter: aktiveret: falsk helbred: aktiveret: sand hurtigstart: genererOrderPeriod: 10s procesOrderPeriod: 30s

5. Opsætning af kamel servlet

En måde at begynde at bruge Camel på er at registrere den som en servlet, så den kan opfange HTTP-anmodningerne og omdirigere dem til vores applikation.

Som nævnt før kan vi, når vi stirrer på Camels version 2.18 og nedenfor, drage fordel af vores ansøgning.yml - ved at oprette en parameter til vores endelige URL. Senere indsprøjtes den i vores Java-kode:

baeldung: api: sti: '/ kamel'

Tilbage til vores Ansøgning klasse, er vi nødt til at registrere Camel servlet ved roden af ​​vores kontekststi, som skal injiceres fra referencen baeldung.api.sti i ansøgning.yml når ansøgningen starter:

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

Fra og med Camels version 2.19 er denne konfiguration blevet droppet som CamelServlet er som standard indstillet til "/kamel".

6. Opbygning af en rute

Lad os begynde at lave en rute ved at udvide RouteBuilder klasse fra Camel, og indstille den som en @Komponent så komponentscanningsrutinen kan finde den under initialisering af webserveren:

@Komponent klasse RestApi udvider RouteBuilder {@ Override public void configure () {CamelContext context = new DefaultCamelContext (); restConfiguration () ... rest ("/ api /") ... fra ("direct: remoteService") ...}}

I denne klasse tilsidesætter vi konfigurer () metode fra Camel's RouteBuilder klasse.

Kamel har altid brug for en CamelContext eksempel - kernekomponenten, hvor de indgående og udgående meddelelser opbevares.

I dette enkle eksempel StandardCamelContext er tilstrækkeligt, da det bare binder beskeder og ruter ind i det, som den REST-tjeneste, som vi skal oprette.

6.1. Det restConfiguration () Rute

Dernæst opretter vi en REST-erklæring for de slutpunkter, vi planlægger at oprette i restConfiguration () metode:

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

Her registrerer vi kontekststien med vores injicerede attribut fra YAML-filen. Den samme logik blev anvendt i havnen i vores applikation. CORS er aktiveret, hvilket muliggør brug af denne webservice på tværs af websteder. Bindingstilstanden tillader og konverterer argumenter til vores API.

Dernæst tilføjer vi Swagger-dokumentation til URI, titel og version, vi tidligere har indstillet. Når vi opretter metoder / slutpunkter til vores REST-webservice, opdateres Swagger-dokumentationen automatisk.

Denne Swagger-kontekst er i sig selv en kamelrute, og vi kan se nogle tekniske oplysninger om det i serverloggen under opstartsprocessen. Vores eksempler på dokumentation serveres som standard på // localhost: 8080 / kamel / api-doc.

6.2. Det hvile() Rute

Lad os nu implementere hvile() metodeopkald fra konfigurer () ovennævnte metode:

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

Denne metode er ret ligetil for dem, der er fortrolige med API'er. Det id er identifikationen af ​​ruten inde i CamelContext. Den næste linje definerer MIME-typen. Bindingstilstanden er defineret her for at vise, at vi kan indstille en tilstand til restConfiguration ().

Det stolpe() metode tilføjer en operation til API'en og genererer en “POST / bønne”Slutpunkt, mens MyBean (en almindelig Java-bønne med en Heltal-id og Strengnavn) definerer de forventede parametre.

Tilsvarende er HTTP-handlinger som GET, PUT og DELETE alle tilgængelige også i form af få(), sætte(), slet ().

Endelig blev til() metoden opretter en bro til en anden rute. Her fortæller det Camel at søge inden i sin kontekst / motor til en anden rute, som vi skal oprette - som er navngivet og detekteret af værdien / id “direkte:…“, Der matcher den rute, der er defineret i fra() metode.

6.3. Det fra() Rute med transformer ()

Når du arbejder med Camel, modtager en rute parametre og konverterer, transformerer og behandler disse parametre. Derefter sender den disse parametre til en anden rute, der videresender resultatet til det ønskede output (en fil, en database, en SMTP-server eller et REST API-svar).

I denne artikel opretter vi kun en anden rute inde i konfigurer () metode, som vi tilsidesætter. Det vil være destinationsruten for vores sidste til() rute:

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

Det fra() metoden følger de samme principper og har mange af de samme metoder som hvile() metode, bortset fra at den bruger fra Camel-kontekstmeddelelser. Dette er grunden til parameteren “direkte rute“, Der skaber et link til den førnævnte metode hvile (). til ().

Mange andre konverteringer er tilgængelige, herunder udvinding som Java-primitive (eller objekter) og sende den ned til et persistenslag. Bemærk, at ruterne altid læser fra indgående beskeder, så kædede ruter ignorerer udgående meddelelser.

Vores eksempel er klar, og vi kan prøve det:

  • Kør kommandoen prompt: mvn spring-boot: løb
  • Foretag en POST-anmodning til // localhost: 8080 / kamel / api / bønne med headerparametre: Indholdstype: applikation / jsonog en nyttelast {“Id”: 1, ”name”: “Verden”}
  • Vi skal modtage en returkode på 201 og svaret: Hej Verden

6.4. SIMPLE Scripting Language

Eksemplet udfører logning ved hjælp af sporing () metode. Bemærk, at vi har brugt ${} pladsholdere disse er en del af et skriptsprog, der tilhører Camel, kaldet SIMPLE. Det anvendes på meddelelser, der udveksles over ruten, ligesom kroppen i in-meddelelsen.

I vores eksempel bruger vi SIMPLE til at udføre bønneegenskaberne i kamelbeskedkroppen til loggen.

Vi kan også bruge det til at udføre enkle transformationer, som det blev vist med transformer () metode.

6.5. Det fra() Rute med behandle()

Lad os gøre noget mere meningsfuldt, såsom at kalde et servicelag for at returnere behandlede data. SIMPLE er ikke beregnet til tung databehandling, så lad os erstatte transformer () med en behandle() metode:

fra ("direct: remoteService") .routeId ("direct-route") .tracing () .log (">>> $ {body.id}") .log (">>> $ {body.name}" ) .proces (ny processor () {@ Overstyr offentlig ugyldig proces (Exchange-udveksling) kaster undtagelse {MyBean bodyIn = (MyBean) exchange.getIn (). getBody (); ExampleServices.example (bodyIn); exchange.getIn (). setBody (bodyIn);}}) .setHeader (Exchange.HTTP_RESPONSE_CODE, konstant (200));

Dette giver os mulighed for at udtrække dataene i en bønne, den samme som tidligere defineret på type() metode og behandle den i vores EksempelTjenester lag.

Da vi indstiller bindingMode () til JSON tidligere er svaret allerede i et korrekt JSON-format, genereret baseret på vores POJO. Dette indebærer, at for en EksempelTjenester klasse:

offentlig klasse ExampleServices {offentligt statisk ugyldigt eksempel (MyBean bodyIn) {bodyIn.setName ("Hej" + bodyIn.getName ()); bodyIn.setId (bodyIn.getId () * 10); }}

Den samme HTTP-anmodning vender nu tilbage med en svarkode 201 og body: {“Id”: 10, ”name”: “Hej, verden”}.

7. Konklusion

Med et par kodelinjer lykkedes det os at oprette en relativt komplet applikation. Alle afhængigheder bygges, administreres og køres automatisk med en enkelt kommando. Desuden kan vi oprette API'er, der binder sammen alle mulige teknologier.

Denne tilgang er også meget containervenlig, hvilket resulterer i et meget magert servermiljø, der let kan replikeres efter behov. De ekstra konfigurationsmuligheder kan nemt integreres i en container skabelon konfigurationsfil.

Dette REST-eksempel kan findes på GitHub.

Endelig ud over filter(), behandle(), transformer ()og marshall () API'er, mange andre integrationsmønstre og datamanipulationer er tilgængelige i Camel:

  • Kamelintegrationsmønstre
  • Camel Brugervejledning
  • Camel SIMPLE Language