Skip to content

Latest commit

 

History

History
137 lines (96 loc) · 10.8 KB

README.md

File metadata and controls

137 lines (96 loc) · 10.8 KB

camel-boot

A seed-project for starting new REST-API Camel/Spring Boot projects

This project can be used to kick-start Spring-Boot-wrapped-Camel projects which expose a REST API. The core use case for this is a microservice. When used in conjunction with camel-boot-cxf-soap (which does the same thing but exposes a SOAP API) you have a good starter for ten for most synchronous microservices architectures you may want to create.

What's Inside?

So what do I get by seeding my project in this way? Well, you'll get a set of code, tests (unit and integration) and config, plus Gradle build, which bootstraps an Apache Camel app that exposes a REST API. All this is handily packaged as a executable Spring Boot fat jar.

You also get:

  • Camel endpoint exposure via Jetty
  • integration tests via RESTassured which run under the integrationTest Gradle target and which start up your Spring Boot app locally in order to run them against it
  • logging via SLF4J/Logback (with a sample config files for STDOUT and Jetty Access logging)
  • REST api docs via Swagger
  • circuit breaking on downstream calls via Hystrix
  • metrics collection and publishing via CodaHale Metrics for JVM, Jetty, and Hystrix as well as your app code (we also had Camel metrics, but we never used them)
  • an embedded Jetty servlet container which exposes the Hystrix metrics-event-stream servlet and the Codahale Metrics servlets

Usage

Quickstart

To use this seed project, fork this repository, and rename it as desired. Then run the following gradle tasks:

  • gradle clean test - runs the example unit tests
  • gradle clean integrationTest - runs the example unit tests
  • gradle bootRun - starts the Spring-Boot app
  • gradle clean test integrationtest install - runs all tests (unit and integration, packages the spring boot fat jar and installs it in your local repo

In Depth

We have a design goal to reduce the amount of code which distracts form your business logic. To this end, we've focussed on removing XML-config, kept the dependencies clean and lean, and provided a structure which should give clear indication where to put your code. It can however result in things looking a little magical. Here are how the various elements are set up:

Properties

Environment-dependent config information is read from a set of .properties files which will be located external to your resulting JAR file. The ones for developent are located in the gradle config directory. These are split up so as to prevent any one file from getting too dense. They are loaded and shared with Spring, Camel, and Hystrix via the archaius-spring-adapter which is configured as a Spring @Bean in the MyAppConfig class. The idea is to build a JAR which will work in all environments, and then configure it with env-specific properties files deployed alongside it.

Files to change

TBC

Further reading

Spring Boot

The core of the Spring Boot app is the Application class. This has the @SpringBootApplication annotation and gets us most of the way towards the fat-jar goodness we desire. Note that the @EnableAutoConfiguration annotation is NOT used. We prefer to do things a little more explicitly which we find helps us avoid many of the Spring-magic problems most people encounter at some point or other.

This aside, you may notice that there seems to be little Spring Boot (or indeed Spring-anything) in evidence. This is intentional. If you want to see what is there in the seed, build.gradle is a good place to start. Note that we have excluded the Tomcat starter (so we get Jetty instead) as well as web-mvc. We don't need them in our projects.

We ended up doing this because Spring Boot loves to look at your classpath and do clever things based on what it finds. While this is definitely a boon in most situations, it is possible that this can give you major headaches. We have found that it is best therefore to add single dependencies to your project and then, before you add any code or config, run your tests and check that gradle bootRun still works. It's amazing the havoc that a stray servlet-api, buried down in your dependency graph can wreak.

We have added a banner.txt file which gives us the ASCII-goodness you see when you run your app. If you change the contents of this file, the contents of your app's Spring Boot banner will change also.

Finally note that we've managed to do away with all that nasty XML Spring config. As mentioned in the Properties section above, when we do need to create a bean, we do by creating a @Bean method it in the @Configuration annotated MyAppConfig class, or we explicitly import is with an explicit @Import at the top of the Application class.

Taking the MyAppConfig class first, you can see there is some boiler-plate which illustrates how to get access to the Spring context (should you need it) and also a Spring bean instance of ArchaiusBridgePropertyPlaceholderConfigurer which loads the properties (into Spring-, Camel- and Netflix-scopes) from the files listed in the Properties section above. See github for more info on the Archaius-Spring-Adapter (which provides this class).

With the @Import, we're using Spring here to explicitly bring into config-scope another class which is again annotated @Configuration. One of these beans comes from one of our dependencies - springboot-camel-metrics-publisher in this case - and simply starts up and registers the servlets which publish the Hystrix metrics stream, the Codahale metrics, and allows thread dumps. (For more information on all of these, see the relevant sections below.) The other configuration beans are local to your project - look in the config package to see them. Note: we'll probably move these to dependencies too in the future.

Also note that this indicates a convention. If we want to add more configuration @Beans for our app alone, we add them to MyAppConfig. If we are bringing them in from a dependency, explicitly declare them in Application via an @Import.

Finally note that we are starting up a Jetty container which is used to register all our monitoring servlets, as well as the camel "servlet" provider which provides HTTP access to your REST routes and Swagger API docs.

Files to change

TBC

Further reading

Camel

The first thing to note with the Camel elements are the dependencies. There should be very few surprises here if you've used Camel before.

The Second thing to look at again is src/main/java/...Application.java. This extends Camel's FatJarRouter, and as already mentioned is annotated @SpringBootApplication thereby removing the need for us to have any Camel XML config at all. This tiny piece of typing means that when we do gradle bootRun (or java -jar YourApp.jar) you will see your Camel context starting up inside a Spring context with next to no effort on your part.

The rest (no pun intended) is up to you. We typically create our Camel routes in the route package. There is an example REST one in there for you already. We have also added an example RESTassured integration test which runs when you run gradle integrationTest.

As mentioned above, the Camel REST DSL routes map to the Jetty Servlet container provided by Spring Boot. TBC - where is this configured?

Files to change

TBC

Further reading

Swagger

The example REST DSL route class generates and publishes Swagger files at http://localhost:xx/xxxxxxxxx. To view these in the Swagger broswer you need to ..... TBC.

Logging

We use SLF4J and Logback for our logging. In addition to the expected STDOUT logging which goes by default to file and console, there is also HTTP access logging (also to file).

Files to change

TBC

Further reading

Metrics

Its always nice to have an idea what your app is doing. We make heavy use of CodaHale Metrics to give us this information. As already mentioned, instrumented aspects of the seed project are:

Files to change

TBC

Further reading

Hystrix

TBC

Files to change

TBC

Further reading

TBC

Acknowledgements

The idea for these projects was pretty much stolen from Netflix's Karyon. It then evolved as we built more and more Microservice-based solutions at Capgemini.

There is little original thought in all that has been pulled together here - we're just sharing our glue code, and the build files, and some examples which illustrate some nice ways to do things. The core is based on:

  1. Apache Camel
  2. Spring-Boot
  3. Netflix's Archaius and Hystrix
  4. CodaHale's Metrics
  5. Swagger
  6. Logback
  7. Jetty

Contributors

If you submit a PR, please add your name to this list.