Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Focus on Your Features - Dropwizard takes care of the REST

Felix
October 28, 2015

Focus on Your Features - Dropwizard takes care of the REST

Dropwizard kombiniert ausgereifte Standardkomponenten wie Jetty, Jersey, Jackson und Java Validation und fügt noch einige smarte Metrics- und Operations-Frameworks hinzu. Dadurch kann in wenigen Minuten ein RESTful Service in "production-quality" erstellt werden. Ein Traum für die DevOps Bewegung: deployed wird die Komponente als einzelnes jar-File. Healthchecks und Metriken sind standardmäßig aktiviert.

Dropwizard ist dabei so schlank, dass kaum Lernaufwand anfällt und man sich nicht zu stark an dieses Framework bindet.

Der Talk wird eine Einführung in Dropwizard geben und dann die Erfahrungen mit Dropwizard während der Entwicklung einer cloud-basierten, hoch-skalierbaren Anwendung schildern.

Felix

October 28, 2015
Tweet

Other Decks in Technology

Transcript

  1. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 1 von 47 29.10.2015 20:35
  2. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 2 von 47 29.10.2015 20:35
  3. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 3 von 47 29.10.2015 20:35
  4. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 4 von 47 29.10.2015 20:35
  5. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 5 von 47 29.10.2015 20:35
  6. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 6 von 47 29.10.2015 20:35
  7. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 7 von 47 29.10.2015 20:35
  8. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 8 von 47 29.10.2015 20:35
  9. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 9 von 47 29.10.2015 20:35
  10. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 10 von 47 29.10.2015 20:35
  11. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 11 von 47 29.10.2015 20:35
  12. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 12 von 47 29.10.2015 20:35
  13. pom.xml 1. MyApplication.java 2. MyConfiguration.java & config.yml 3. MyResource.java 4.

    Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 13 von 47 29.10.2015 20:35
  14. <project> <groupId>com.acrolinx.demo</groupId> <artifactId>hipster-o-mat</artifactId> <version>0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-core</artifactId> <version>0.9.0-rc5</version> </dependency>

    </dependencies> ... </project> Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 14 von 47 29.10.2015 20:35
  15. public class HipsterApplication extends Application<HipsterConfiguration> { public static void main(final

    String[] args) { new HipsterApplication().run(args); } @Override public void run(final HipsterConfiguration conf, final Environment env) throws Exception { env.jersey().register(new HipsterResource()); } } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 15 von 47 29.10.2015 20:35
  16. @Path("/hipsters") public class HipsterResource { @GET @Path("ping") public Pong foobar()

    { return new Pong(); } } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 16 von 47 29.10.2015 20:35
  17. conferenceName: JUGF 2016 server: type: simple applicationContextPath: / adminContextPath: /admin

    connector: type: http port: 12345 public class HipsterConfiguration extends Configuration { private String conferenceName; public String getConferenceName() { return conferenceName; } } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 17 von 47 29.10.2015 20:35
  18. java -jar hipster-o-mat-0.1-SNAPSHOT.jar server hipster.yml Hello JUGF 2016 INFO [15:52:13,998]

    io.d.s.ServerFactory: Starting HipsterApplication INFO [15:52:14,058] org.e.j.SetUIDListener: Opened HipsterApplication@200234 INFO [15:52:14,728] io.d.j.DropwizardResourceConfig: The following paths wer GET /hipsters/ping (com.ax.demo.resource.HipsterResource) INFO [15:52:14,828] o.e.jetty.s.Server: Started @1734ms >curl "http://localhost:12345/hipsters/ping" {"msg":"Pong"} Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 18 von 47 29.10.2015 20:35
  19. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 19 von 47 29.10.2015 20:35
  20. public class HipsterServiceHealthCheck extends HealthCheck protected Result check() { if

    (store.isRunning()) { return Result.healthy("I'm fine. Store is running."); } else { return Result.unhealthy("Oho, no storage for hipsters." } } } public void run(final HipsterConfiguration conf, final Environment environment) throws Exception { environment.healthChecks().register("hipsterHealth", new HipsterServiceHealthCheck(store)); ... Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 20 von 47 29.10.2015 20:35
  21. @Timed @GET @Path("ping") public Pong foobar() { return new Pong();

    } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 21 von 47 29.10.2015 20:35
  22. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 22 von 47 29.10.2015 20:35
  23. bootstrap.addBundle(new ViewBundle<HipsterConfiguration>(){...} public class HipsterView extends View { public HipsterView(Hipster

    hipster) { super("hipster.mustache"); this.hipster = hipster; } public Hipster getHipster() { return hipster; }} @GET @Path("{name}/view") @Produces({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) public HipsterView getHipsterView(@PathParam("name") String name) return new HipsterView(getHipster(name)); } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 23 von 47 29.10.2015 20:35
  24. <body> {{#hipster}} <div id="layout" class="pure-g"> <div class="sidebar pure-u-1 pure-u-med-1-4"> <div

    class="header"> <hgroup> <h1 class="brand-title">Sample Hipster #{{id}}</h1> <h2 class="brand-tagline">All about '{{name}}'</h2> </hgroup> </div> </div> </div> {{/hipster}} ... Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 24 von 47 29.10.2015 20:35
  25. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 25 von 47 29.10.2015 20:35
  26. curl -X GET -H "Accept: application/json" http://localhost:12345/hipsters/Foo/view STATUS 200 OK

    {"hipster": {"id":0, "name":"Foo", "jeans":"SKINNY", "hornRimmedGlasses":true, "imagePath":null} } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 26 von 47 29.10.2015 20:35
  27. @ClassRule DropwizardAppRule<HipsterConfiguration> RULE = new DropwizardAppRule<HipsterConfiguration>( HipsterApplication.class, resourceFilePath("hipster.yml")); @Test public

    void testHipsterGetCreateRoundtrip() { Client client = ClientBuilder.newClient(); Response response = client.target("http://localhost:" + RULE.getLocalPort()) .path("hipsters").request(APPLICATION_JSON) .post(Entity.json(getHipster("foo"))); assertEquals(201, response.getStatus()); Hipster hipReceived = client.target(String.format( "http://localhost:%d/hipsters/foo", RULE.getLocalPort())) .request(MediaType.APPLICATION_JSON).get(Hipster.class); assertEquals(getHipster("foo"), hipReceived); } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 27 von 47 29.10.2015 20:35
  28. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 28 von 47 29.10.2015 20:35
  29. environment.lifecycle().manage(store); public class HipsterStore implements Managed { @Override public void

    start() throws Exception {...} @Override public void stop() throws Exception {...} } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 29 von 47 29.10.2015 20:35
  30. public class Hipster { @Min(value = 0, message = "Id

    must be positive") private int id; ... } @POST public Response addHipster(@Valid final Hipster hipster){ ... Status 422 - {"errors":["id Id must be positive (was -2)"]} Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 30 von 47 29.10.2015 20:35
  31. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 31 von 47 29.10.2015 20:35
  32. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 32 von 47 29.10.2015 20:35
  33. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 33 von 47 29.10.2015 20:35
  34. public void initialize(Bootstrap<SampleConfiguration> bs) bootstrap.addBundle(new AssetsBundle( "/imgFolder", "/hipster-images", "index.html", "images"

    bootstrap.addBundle(new AssetsBundle( "/apidocs", "/doc", "service.json", "js")); } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 34 von 47 29.10.2015 20:35
  35. discovery: serviceName: hello-world public void initialize(Bootstrap<HipsterConfiguration> bootstrap) bootstrap.addBundle(dBundle); } private

    final DiscoveryBundle<Conf> dBundle = new DiscoveryBundle<Conf>(){ @Override public DiscoveryFactory getDiscoveryFactory(Conf conf) return conf.getDiscovery(); } }); Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 35 von 47 29.10.2015 20:35
  36. final DiscoveryClient client = discoveryBundle.newDiscoveryClient("other-service"); environment.lifecycle().manage( new DiscoveryClientManager(client)); Focus on

    your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 36 von 47 29.10.2015 20:35
  37. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 37 von 47 29.10.2015 20:35
  38. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 38 von 47 29.10.2015 20:35
  39. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 39 von 47 29.10.2015 20:35
  40. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 40 von 47 29.10.2015 20:35
  41. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 41 von 47 29.10.2015 20:35
  42. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 42 von 47 29.10.2015 20:35
  43. Focus on your Features - Dropwizard takes care of the

    REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 43 von 47 29.10.2015 20:35
  44. environment.admin().addTask(new HelloTask("Hello")); curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'logger=org.eclipse.jetty.server.Server&level=DEBUG'

    http://localhost:56789/admin/tasks/log-level Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 44 von 47 29.10.2015 20:35
  45. @GET @Timed(name = "get-requests") @CacheControl(maxAge = 1, maxAgeUnit = TimeUnit.DAYS)

    public Saying hello(@QueryParam("name") Optional<String> nm) return new Saying(counter.incrementAndGet() , template.render(nm)); } Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 45 von 47 29.10.2015 20:35
  46. @GET public SecretPlan getSecretPlan(@Auth User user) { return dao.findPlanForUser(user); }

    public class SimpleAuthenticator implements Authenticator< @Override public Optional<user> authenticate(BasicCredentials credentials if ("secret".equals(credentials.getPassword())) { return Optional.of(new User(credentials.getUsername())) } return Optional.absent(); } }</user></basiccredentials,> @Override public void run(ExampleConfiguration configuration, Environment environment) { environment.jersey().register(AuthFactory.binder( new OAuthFactory<User>(new ExampleAuthenticator(), Focus on your Features - Dropwizard takes care of the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 46 von 47 29.10.2015 20:35
  47. } Focus on your Features - Dropwizard takes care of

    the REST file:///C:/Users/Felix.Braun/Google Drive/Dropwizard-Javaland-Talk/dw-short-version-codecentric.h... 47 von 47 29.10.2015 20:35