Teil 2

Im zweiten Teil unserer Reihe stellen wir nun den ersten Teil unserer Anwendung vor, dies entspricht dem rot umrahmten Fenster unserer Architektur in Abbildung 1.

Abbildung 1 Aufbau der Architektur

Dieser beinhaltet eine Beispielanwendung mit Spring Boot und Apache Camel. Wir stellen dabei zwei verschiedene Routing Mechanismen von Camel vor.

Vollständiger Code verfügbar unter:

https://git.opitz-consulting.de/scm/oclab/blue-335-api-gw-camel-integration.git

Aufbau der Spring Boot Anwendung mit Camel Integration

Unsere Spring Boot Anwendung wird als Maven Projekt angelegt, hierfür benötigen wir folgende Dependencies in unserer pom.xml:


		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
		
			org.apache.camel
			camel-core
			${camel.version}
		
		
			org.apache.camel.springboot
			camel-bean-starter
			${camel.version}
		
		
			org.apache.camel
			camel-servlet
			${camel.version}
		
		
			org.apache.camel.springboot
			camel-rest-starter
			${camel.version}
		
		
			org.apache.camel
			camel-rest
			${camel.version}
		
		
			org.apache.camel
			camel-http
			${camel.version}
		
		
			org.apache.camel
			camel-jackson
			${camel.version}
		
		
			org.apache.camel
			camel-swagger-java
			${camel.version}
		
	

Diese beinhaltet den Spring Boot Web Starter, sowie die für unsere Camel Integration notwendigen Dependencies.

Wir werden in dieser Beispiel Anwendung Camel Routen auf zwei verschiedene Arten implementieren:

  1. Mit Hilfe eines Producer Templates der durch eine Spring Boot Rest Controller aufgerufen wird
  2. Über ein Servlet, welches einen HTTP Endpoint zur Verfügung stellt und intern die Camel Rest Schnittstelle verwendet

Die ersten Variante ist prinzipiell flexibler und erlaubt somit mehr Kontrolle über den Prozess. Bei der zweiten Variante ist hingegen weniger manuelle Konfiguration notwendig.

Unsere Spring Boot Anwendung hat die folgende Struktur:

Abbildung 2 Verzeichnisstruktur Spring Boot Anwendung

Die einzelnen Dateien unserer Anwendung werden nun hier mit ihren jeweiligen Funktionen beschrieben:

GatewayApplication:

@SpringBootApplication
@Configuration
@ComponentScan("com.opitzconsulting.demo.kongcamel")
public class GatewayApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        ServletRegistrationBean registration = new ServletRegistrationBean(new CamelHttpTransportServlet(), "/camel/*");
        registration.setName("CamelServlet");
        return registration;
    }

}

In der GatewayApplication wird unsere Anwendung gestartet. Hier wird außerdem unser Camel Servlet erstellt, welches dann einen HTTP Endpoint unter der URL „/camel/*“ zur Verfügung stellt.

CamelConfig:

@Configuration
public class CamelConfig {

    @Bean
    public CamelContext createContext() throws Exception {
        // create and return the camel context
        CamelContext context = new DefaultCamelContext();
        context.addRoutes(new MyRouter());
        context.start();
        return context;
    }
}

Die CamelConfig ist eine Konfigurationsdatei, in der ein CamelContext erstellt wird. Dieser ist vergleichbar mit dem Spring ApplicationContext, der die zentralen Konfigurationseinheit einer Spring Boot Anwendung ist.

MyRouter:

@Component
public class MyRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        // route via rest controller + producerTemplate
        from("direct:start").bean(new MyBean(), "saySomething");

        // Route via servlet from rest: to endpoint with producer
        restConfiguration()
                .component("servlet")
                .bindingMode(RestBindingMode.json);
        rest().get("/hello")
                .to("direct:hello");
        from("direct:hello")
                .log(LoggingLevel.INFO, "Hello World")
                .transform().simple("Hello World");
    }

}

Die Klasse MyRouter implementiert die Camel Routen, die dann im dazugehörigen CamelContext registriert werden. Wir stellen in unserem Setup zwei Routen zur Verfügung.

  1. Die erste Route leitet Daten welche an den Endpoint „direct:start“ gesendet werden weiter an die Bean MyBean und ruft dort die Methode „saySomething“ auf.
  2. Die zweite Route hingegen leitet Anfragen die an die URL „camel/hello“ gesendet werden an den Endpoint „direct:hello“ weiter. Die URL setzt sich hierbei aus der Servlet URL und der in „rest“ definierten Route zusammen. Der Endpoint „direct:hello“ gibt wiederum einen einfach String mit „Hello World“ zurück.

ApiController + MyBean:

@RestController
public class ApiController {

    @Autowired
    CamelContext camelContext;

    @GetMapping("/greeting")
    public String greeting(@RequestParam(value = "name", defaultValue = "World") String name) throws Exception {
        ProducerTemplate template = camelContext.createProducerTemplate();
        String result = (String) template.sendBody("direct:start", ExchangePattern.InOut, "Hi!");
        return result;
    }
}
@Component("myBean")
public class MyBean {

    private int counter;

    public String saySomething(String body) {
        return String.format("%s I am invoked %d times", body, counter++);
    }

}

Die registrierten Routen werden bislang nicht aufgerufen. Wir werden dies nun über einen einfachen Spring Boot Rest Controller ermöglichen. Dafür legen wir eine Schnittstelle unter dem Pfad „/greeting“ an, bei deren Aufruf ein Producer Template erstellt wird. Mit Hilfe dieses Producer Templates kann man nun einen vordefinierten Camel Endpoint, in unserem Fall „direct:start“ ansteuern und diesem ein Exchange Pattern und einen Message Body mitgeben. Das Exchange Pattern signalisiert die Richtung des Nachrichtenflusses. „InOut“ ermöglicht es in unserem Beispiel eine Nachricht zu senden und im Anschluss wieder eine Antwort zu empfangen. Am Ende geben wir den hier erhaltenen String unter der Rest Schnittstelle aus.

Die MyBean Klasse gibt lediglich einen einfachen String mit einem Counter zurück und wird über den Endpoint „direct:start“ unserer Route aufgerufen.

Zu guter Letzt verwenden wir in unserer pom.xml noch das jib-maven-plugin. Dies ermöglicht es ein Docker Image unserer Anwendung zu erstellen.

Die hier gezeigt Anwendung zeigt lediglich zwei sehr einfache Anwendungsfälle für Camel. Bei beiden Varianten ist es zum Beispiel möglich während des Nachrichtentransport gesendete Daten über sogenannte Processor Klassen beliebig zu transformieren.

Im nächsten und letzten Beitrag werden wir nun das Kong API Gateway für unsere Spring Boot Anwendung integrieren und hierfür verfügbare Konfigurationsmöglichkeiten vorstellen.

Zum nächsten Teil gehts hier: https://thecattlecrew.net/?p=32586

 

Alle Beiträge von Maximilian Vogel

Schreibe einen Kommentar