Apache Camel met Spring Boot

1. Overzicht

In wezen is Apache Camel een integratie-engine die - simpel gezegd - kan worden gebruikt om interacties tussen een breed en gevarieerd scala aan technologieën mogelijk te maken.

Deze bruggen tussen diensten en technologieën worden genoemd routes. Routes worden geïmplementeerd op een engine (de CamelContext), en ze communiceren met zogenaamde "uitwisselingsberichten".

2. Maven afhankelijkheden

Om te beginnen moeten we afhankelijkheden opnemen voor Spring Boot, Camel, Rest API met Swagger en 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 nieuwste versies van Apache Camel-afhankelijkheden zijn hier te vinden.

3. De hoofdklasse

Laten we eerst een Spring Boot maken Toepassing:

@SpringBootApplication @ComponentScan (basePackages = "com.baeldung.camel") openbare klasse Toepassing {openbare statische leegte hoofd (String [] args) {SpringApplication.run (Application.class, args); }}

4. Camel configuraties voor Spring Boot

Laten we nu onze applicatie configureren met Spring, te beginnen met de configuratiebestanden (eigenschappen).

Laten we bijvoorbeeld een logboek configureren voor onze applicatie op een application.properties bestand in 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

Dit voorbeeld toont een application.properties bestand dat ook het pad naar een Logback-configuratie instelt. Door het IP-adres in te stellen op "0.0.0.0", beperken we volledig beheerder en beheer toegang op de webserver van Spring Boot. We maken ook de benodigde netwerktoegang tot onze applicatie-eindpunten en de gezondheidscontrole-eindpunten mogelijk.

Een ander configuratiebestand is het application.yml. Hierin zullen we enkele eigenschappen toevoegen om ons te helpen waarden in onze applicatieroutes te injecteren:

server: poort: 8080 camel: springboot: naam: Services Restbeheer: poort: 8081 endpoints: enabled: false health: enabled: true quickstart: generationOrderPeriod: 10s processOrderPeriod: 30s

5. De Camel Servlet opzetten

Een manier om Camel te gaan gebruiken, is door het als een servlet te registreren, zodat het de HTTP-verzoeken kan onderscheppen en deze naar onze applicatie kan omleiden.

Zoals eerder vermeld, kunnen we staren met Camel's versie 2.18 en lager profiteren van onze application.yml - door een parameter te maken voor onze uiteindelijke URL. Later zal het in onze Java-code worden geïnjecteerd:

baeldung: api: path: '/ camel'

Terug naar onze Toepassing klasse, moeten we de Camel-servlet registreren in de root van ons contextpad, dat wordt geïnjecteerd vanuit de referentie baeldung.api.path in de application.yml wanneer de applicatie start:

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

Vanaf versie 2.19 van Camel is deze configuratie verwijderd als het CamelServlet is standaard ingesteld op "/kameel".

6. Een route bouwen

Laten we beginnen met het maken van een route door de extensie RouteBuilder klasse van Camel, en het instellen als een @Component zodat de componentscanroutine het kan lokaliseren tijdens de initialisatie van de webserver:

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

In deze klasse overschrijven we de configureren () methode van Camel's RouteBuilder klasse.

Camel heeft altijd een CamelContext voorbeeld - de kerncomponent waar de inkomende en uitgaande berichten worden bewaard.

In dit eenvoudige voorbeeld DefaultCamelContext is voldoende omdat het alleen berichten en routes erin bindt, zoals de REST-service die we gaan maken.

6.1. De restConfiguration () Route

Vervolgens maken we een REST-declaratie voor de eindpunten die we willen maken in het restConfiguration () methode:

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)

Hier registreren we het contextpad met ons geïnjecteerde attribuut uit het YAML-bestand. Dezelfde logica werd toegepast op de poort van onze applicatie. CORS is ingeschakeld, waardoor cross-site gebruik van deze webservice mogelijk is. De bindingsmodus staat argumenten toe en converteert deze naar onze API.

Vervolgens voegen we Swagger-documentatie toe aan de URI, titel en versie die we eerder hebben ingesteld. Terwijl we methoden / eindpunten maken voor onze REST-webservice, wordt de Swagger-documentatie automatisch bijgewerkt.

Deze Swagger-context is zelf een Camel-route en we kunnen er wat technische informatie over zien in het serverlogboek tijdens het opstartproces. Onze voorbeelddocumentatie wordt standaard geserveerd op // localhost: 8080 / camel / api-doc.

6.2. De rust uit() Route

Laten we nu het rust uit() method aanroep van de configureren () methode hierboven vermeld:

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

Deze methode is vrij eenvoudig voor degenen die bekend zijn met API's. De ID kaart is de identificatie van de route binnen de CamelContext. De volgende regel definieert het MIME-type. De bindmodus wordt hier gedefinieerd om te laten zien dat we een modus kunnen instellen op het restConfiguration ().

De post() methode voegt een bewerking toe aan de API en genereert een "POST / boon”Eindpunt, terwijl de MyBean (een gewone Java-boon met een Geheel getal id en String naam) definieert de verwachte parameters.

Evenzo zijn HTTP-acties zoals GET, PUT en DELETE allemaal beschikbaar in de vorm van krijgen(), leggen(), verwijderen ().

eindelijk, de naar() methode creëert een brug naar een andere route. Hier vertelt het Camel om in zijn context / engine te zoeken naar een andere route die we gaan maken - die wordt genoemd en gedetecteerd door de waarde / id "direct:…“, Overeenkomend met de route die is gedefinieerd in het van() methode.

6.3. De van() Route met transformeren()

Wanneer u met Camel werkt, ontvangt een route parameters en converteert, transformeert en verwerkt deze parameters vervolgens. Daarna stuurt het deze parameters naar een andere route die het resultaat doorstuurt naar de gewenste output (een bestand, een database, een SMTP-server of een REST API-antwoord).

In dit artikel maken we alleen een andere route binnen het configureren () methode die we overschrijven. Het wordt de bestemmingsroute voor onze laatste naar() route:

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

De van() methode volgt dezelfde principes en heeft veel van dezelfde methoden als de rust uit() methode, behalve dat het verbruikt uit de Camel-contextberichten. Dit is de reden voor de parameter "directe route“, Dat zorgt voor een link naar de eerder genoemde methode rest (). tot ().

Er zijn veel andere conversies beschikbaar, inclusief extractie als Java-primitieven (of objecten) en het verzenden naar een persistentielaag. Merk op dat de routes altijd lezen van inkomende berichten, zodat gekoppelde routes uitgaande berichten negeren.

Ons voorbeeld is klaar en we kunnen het proberen:

  • Voer de promptopdracht uit: mvn spring-boot: run
  • Doe een POST-verzoek aan // localhost: 8080 / camel / api / bean met headerparameters: Inhoudstype: application / json, en een lading {"Id": 1, "name": "Wereld"}
  • We zouden een retourcode van 201 moeten ontvangen en het antwoord: Hallo Wereld

6.4. De EENVOUDIGE scripttaal

Het voorbeeld voert logboekregistratie uit met behulp van de traceren () methode. Merk op dat we de ${} tijdelijke aanduidingen; deze maken deel uit van een scripttaal die toebehoort aan Camel, genaamd SIMPLE. Het wordt toegepast op berichten die via de route worden uitgewisseld, zoals de hoofdtekst van het in-bericht.

In ons voorbeeld gebruiken we SIMPLE om de bean-attributen in het Camel-bericht naar het logboek te sturen.

We kunnen het ook gebruiken om eenvoudige transformaties uit te voeren, zoals werd getoond met de transformeren() methode.

6.5. De van() Route met werkwijze()

Laten we iets zinvollers doen, zoals een servicelaag aanroepen om verwerkte gegevens te retourneren. SIMPLE is niet bedoeld voor zware gegevensverwerking, dus laten we de transformeren() met een werkwijze() methode:

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

Hierdoor kunnen we de gegevens extraheren in een bean, dezelfde die eerder is gedefinieerd op de type() methode, en verwerk het in onze Voorbeelddiensten laag.

Omdat we de bindingMode () naar JSON eerder, het antwoord is al in een correct JSON-formaat, gegenereerd op basis van onze POJO. Dit houdt in dat voor een Voorbeelddiensten klasse:

openbare klasse ExampleServices {openbare statische leegte voorbeeld (MyBean bodyIn) {bodyIn.setName ("Hallo," + bodyIn.getName ()); bodyIn.setId (bodyIn.getId () * 10); }}

Hetzelfde HTTP-verzoek keert nu terug met een antwoordcode 201 en hoofdtekst: {"Id": 10, "name": "Hallo wereld"}.

7. Conclusie

Met een paar regels code zijn we erin geslaagd om een ​​relatief complete applicatie te maken. Alle afhankelijkheden worden gebouwd, beheerd en automatisch uitgevoerd met een enkele opdracht. Bovendien kunnen we API's maken die allerlei technologieën met elkaar verbinden.

Deze aanpak is ook erg containervriendelijk, wat resulteert in een zeer slanke serveromgeving die eenvoudig op aanvraag kan worden gerepliceerd. De extra configuratiemogelijkheden kunnen eenvoudig worden opgenomen in een container-sjabloonconfiguratiebestand.

Dit REST-voorbeeld is te vinden op GitHub.

Eindelijk, voorbij de filter(), werkwijze(), transformeren(), en maarschalk () API's, vele andere integratiepatronen en datamanipulaties zijn beschikbaar in Camel:

  • Camel-integratiepatronen
  • Camel Gebruikershandleiding
  • Camel EENVOUDIGE Taal