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

Introduction to DropWizard

Introduction to DropWizard

Introduction to DropWizard

What is Dropwizard?

Dropwizard is a bunch of frameworks each of which is also part of a full profile application server, glued together to allow one build REST API packaged as a fat jar. A lot of information in a single sentence, let’s elaborate.

First, the Dropwizard team carried out some research and selected the software stack for you saving a lot of time, which is valuable because picking the frameworks to include can engulf one to the extent of being completely unable to do other work.

Second, everything is connected together and thoroughly tested for you which is also valuable. Those who are in the business of app server creation can attest that it takes a lot of work to roll out something like DropWizard.

Finally, DropWizard also offers something more than a number of frameworks that are a part of Java EE specification. It offers a lot of code that is unique to the DropWizard and helps to speed up the development as it provides some conveniences to you.

For example, DropWizard includes Metrics library which allows one to monitor the application in production. However, currently metrics can be used with Spring Boot and Vert.x, but at the time DropWizard was released for the first time metrics offered a huge advantage to DropWizard. Also, there is some code to facilitate testing, connect to the database and to expedite the development of resource methods. I hope I’ve drummed up your interest, we’ll talk about some of these features soon.

Why choose DropWizard?

A lot of companies refactor their monolith into microservices, so it is necessary to keep up to speed with modern trends. Does one need to learn something radically new to write Java microservices? (You don’t)

Several years ago things were simpler and one had to choose DropWizard vs Spring Boot. If you like me had a Java EE background it was easier to go with DropWizard as it includes frameworks that are part of Glassfish and everyone who wrote applications based on a full profile application server could easily pick up Dropwizard. Those with Spring experience can go with Spring Boot.

Currently, there are more JavaEE microservices frameworks including WildFly Swarm whereby one can add a snippet of XML to the pom file to get a fat jar from the WildFly application or Payara Micro. I try to keep the list of Java Microservices frameworks in https://www.reddit.com/r/javamicroservices subreddit. Not all of them are actually Java EE frameworks, but there are a lot.

The advantage of DropWizard is that it is not in an early stage but is ready for production, has great documentation and the team answers questions on a Google group. It is high time to introduce Dropwizard.

The site of the project http://www.dropwizard.io/
The git repo https://github.com/dropwizard/dropwizard
Google Group https://groups.google.com/forum/#!forum/dropwizard-user
The subreddit not associated with the team https://www.reddit.com/r/dropwizard

Example project DropWizard v1.0.2 https://github.com/javaeeeee/DropBookmarks
Example project DropWizard v0.8.2 https://bitbucket.org/dnoranovich/dropbookmarks
Some code used in today’s presentation https://bitbucket.org/dnoranovich/dropwizard-getting-started

What’s in the example application?

Let’s jump into the future and imagine that we have already created some application code that store bookmarks. We’ve built the application and the jar file is in the target/ folder. To launch the application one needs to supply a configuration file. Actually, there could be versions of configuration for development, testing, production etc. Here is an example of such a file.

There is such a notion of a Dropwizard command, that is one can supply some command-line arguments to the executable. There are built-in commands and also one can create her own commands. Let’s see some examples.

First of all, let’s check if our Configuration file is Okay.
java -jar target/DWGettingStarted-1.0-SNAPSHOT.jar check config.yml

Let’s work with migrations.
java -jar target/DropBookmarks-1.0-SNAPSHOT.jar db status config.yml checks what is a state of the database.
java -jar target/DropBookmarks-1.0-SNAPSHOT.jar db migrate -i TEST config.yml applies migrations.
java -jar target/DropBookmarks-1.0-SNAPSHOT.jar db drop-all --confirm-delete-everything config.yml deletes everything from the database.

How to create REST API

DropWizard Maven archetype

Let’s learn how to create a Dropwizard project. Actually, there is a lot of boilerplate code that one has to create when initiating a Java project, so it’s a good idea to rely on a Maven archetype. There are about 6 different archetypes to create a DropWizard project; the official one is called java-simple and was included to the project since version 0.8.

Here is a string to generate a project.

mvn archetype:generate -DgroupId=com.javaeeeee -DartifactId=DWGettingStarted -Dname=DWGettingStarted -Dpackage=com.javaeeeee.dwstart -DarchetypeGroupId=io.dropwizard.archetypes -DarchetypeArtifactId=java-simple -DarchetypeVersion=1.0.2 -DinteractiveMode=false

And here what it offers. The boring work of the generation of the folder structure is done for us, also application and configuration classes which use the name we added earlier are created for us. In addition, all the necessary XML to generate a fat jar was also added. Now, we have to add our code and necessary DropWizard dependencies.

\---DWGettingStarted
| config.yml
| pom.xml
|
\---src
+---main
| +---java
| | \---com
| | \---javaeeeee
| | \---com.javaeeeee.dwstart
| | | DWGettingStartedApplication.java
| | | DWGettingStartedConfiguration.java
| | |
| | +---api
| | +---cli
| | +---client
| | +---core
| | +---db
| | +---health
| | \---resources

As a next step let’s take a look how to add a simple resource that prints “hello world”. Everyone who worked with a full profile application will recognize the code of the resource class. DropWizard contains Jersey as a part and the 1.0.2 version relies on 2.23.1.

We have to register the resource in the Application class.

To see how it works we can use cURL.

curl localhost:8080/hello 2>/dev/null -H '{Content-Type: text/plain}'

How to Test DropWizard Applications?

Let’s test it. And this is a part where DropWizard shines; it offers a test rule that spins up in-memory Jersey and allows one to test resource methods. More elaborate tests include Mockito which is part of DropWizard testing package. By the way, it is not necessary to add an explicit jUnit dependency to the pom file.

Basic Authentication

Let’s protect the resource with Basic Authentication. In addition to Basic Authentication, DropWizard offers OAuth2. We rely here on credentials saved in the configuration file. In a more elaborate example, one can use a database to store credentials or store them in LDAP; there is a custom module for this.

We implement the Authenticator interface and in particular its authenticate method. When a user provides credentials, DropWizard extracts them and provide the method with them. The User class should implement javax.security.Principal interface.

The authenticator is registered in the application class.

To instruct Dropwizard to ask a user for credentials it is necessary to add @Auth annotation to the method parameter.

Integration testing

We’ve used several DropWizard modules so far, namely configuration, authentication, and resources and it’s high time to add an integration test which checks how the various parts of our application work together. And there is a special rule which spins up the whole application based on special test configuration files stored in src/test/resources. And here DropWizard offers a special utility class to access files in the resource folder.

Additional features provided by DropWizard:
LongParam, IntParam, BooleanParam, DateTimeParam, NonEmptyStringParam that check the correctness of the supplied parameters type; 400 Bad Request
Return Optional method, returns 404 not found if an empty optional was returned;
Correct processing of exceptions from the resource methods.

How to connect to a database?

DropWizard offers integration with JDBI and Hibernate out of the box and as I had prior Java Persistence API experience, I selected to go with Hibernate. One has to create JPA entities which map to database tables. Both named queries and Criteria API can be used to access entities. To streamline development DropWizard offers special Abstract DAO class which implements methods.

In order to enable database access, one has to add Hibernate bundle and create DAOs and pass them to the resource classes which use database access.

Migrations with Liquibase

The schema of the database of the project may be in a flux state. Also, various environments such as development and testing should have their own datasets. In order to have control over the state of the database, it’s a good idea to use database migrations. DropWizard has built-in support for Liquibase and can use FlyWay as a third-party module.

Liquibase file containing migrations should be named migrations.xml and stored in the src/main/resources folder. While Liquibase can use JSON and YAML, XML dialect was chosen as it is possible to validate XML using schema. Liquibase attempts to offer database independent DSL to generate SQL; that provides some database provider independence.

After adding the Liquibase module to pom.xml and registering migrations bundle, one can use Liquibase functionality using the generated fat jar. It is very convenient in the production environment but not very much so on a developer’s machine, so it’s more convenient to add Liquibase Maven plugin for development.

We’ve just scratched the surface, DropWizard offers much more. In particular, we didn’t explore how to test DAOs using an in-memory database and resources using mocks. Also, we left out the topic of enabling HTTPs and testing secured resources. The examples of these can be found in the example projects. In addition, such topics as metrics were not explored, as well as the problem of using a dependency injection frameworks with DropWizard. In short, one can use HK2, a DI framework provided by Jersey, which is sufficient for small projects. Also, there are several third-party modules which offer integration with Google Guice.

Conclusion

The bottom line is that DropWizard is a production-ready framework which relies on well-known to Java EE developers parts and offers some goodies that can expedite REST API development and testing.

Dmitry Noranovich

October 27, 2016
Tweet

Other Decks in Programming

Transcript

  1. What is DropWizard • Includes well-known frameworks like Jersey, Jackson,

    Hibernate, embedded Jetty HTTP server; • All parts selected for you - saves time and effort; • Parts are glued together and tested - tremendous effort; • Offers some additional code to process HTTP requests, connect to the database, testing; • Metrics; • Packaged as a fat jar.
  2. Why DropWizard • Microservices are hot; • Do we need

    to abandon what we know and learn something radically new to write microservices? • Dropwizard relies on the same frameworks that are part of a full profile application server like Glassfish; • Benefits: production-ready, greate documentation, support via a Google Group; • Rivals: WildFly Swarm, Payara Micro, KumuluzEE, RestExpress.
  3. Getting to know DropWizard • The site of the project

    http://www.dropwizard.io/ • The Git repo https://github.com/dropwizard/dropwizard • The Google Group for users https://groups.google.com/forum/#!forum/dropwizard-u ser • The reddit not associated with the team https://www.reddit.com/r/dropwizard • An Unofficial initializer https://dropwizard-archetype.herokuapp.com/
  4. Projects Used for this Demo • Example project DropWizard 1.0.2

    https://github.com/javaeeeee/DropBookmarks • Example project DropWizard 0.8.2 https://bitbucket.org/dnoranovich/dropbookmarks • Some code used in today’s presentation https://bitbucket.org/dnoranovich/dropwizard-getting-s tarted
  5. Let’s try it • Build: mvn clean package • Check

    configuration: java -jar target/DropBookmarks-1.0-SNAPSHOT.jar check config.yml • Check DB status: java -jar target/DropBookmarks-1.0-SNAPSHOT.jar db status config.yml • Migrate: java -jar target/DropBookmarks-1.0-SNAPSHOT.jar db migrate -i TEST config.yml • Clean DB: java -jar target/DropBookmarks-1.0-SNAPSHOT.jar db drop-all --confirm-delete-everything config.yml
  6. Let’s run it • Run: java -jar target/DropBookmarks-1.0-SNAPSHOT.jar server config.yml

    • CURL it: curl -w "\n" 2>/dev/null -k https://localhost:8443/bookmarks -u javaeeeee:p@ssw0rd • The takeaway: ◦ Built a fat jar; ◦ Exposed REST API; ◦ Used MySQL as DBMS; ◦ Used Hibernate to access DB, may use JDBI; ◦ The API relies on Hibernate validator; ◦ The solution includes tests.
  7. Let’s create a project mvn archetype:generate -DgroupId=com.javaeeeee -DartifactId=DWGettingStarted -Dname=DWGettingStarted -Dpackage=com.javaeeeee.dwstart

    -DarchetypeGroupId=io.dropwizard.archetypes -DarchetypeArtifactId=java-simple -DarchetypeVersion=1.0.2 -DinteractiveMode=false
  8. Generated Project Folder \---com.javaeeeee.dwstart | | | DWGettingStartedApplication.java | |

    | DWGettingStartedConfiguration.java | | | | | +---api | | +---cli | | +---client | | +---core | | +---db | | +---health | | \---resources
  9. Register Resource in Application public class DWGettingStartedApplication extends Application<DWGettingStartedConfiguration> {

    @Override public void run(final DWGettingStartedConfiguration configuration, final Environment environment) { environment.jersey().register(new HelloResource());
  10. Run • Build • Start the Application: java -jar target/DWGettingStarted-1.0-SNAPSHOT.jar

    server config.yml • Check that it’s running: http://localhost:8081/ • CURL it: curl localhost:8080/hello 2>/dev/null -H '{Content-Type: text/plain}' • Or use browser, Postman
  11. Test public class HelloResourceTest { @Rule public ResourceTestRule resource =

    ResourceTestRule.builder() .addResource(new HelloResource()).build(); @Test public void testGetGreeting() { actual = resource.client() .target("http://localhost:8080/hello") .request(MediaType.TEXT_PLAIN) .get(String.class); assertEquals(expected, actual);
  12. Basic Authentication public class GreetingAuthenticator implements Authenticator<BasicCredentials, User> { @Override

    public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException { if (password.equals(credentials.getPassword()) && login.equals(credentials.getUsername())) { return Optional.of(new User()); } else { return Optional.empty(); }
  13. Register in Application class @Override public void run( … )

    { environment.jersey().register(new AuthDynamicFeature( new BasicCredentialAuthFilter.Builder<User>() .setAuthenticator(new GreetingAuthenticator(configuration.getLogin(), configuration.getPassword())) .setRealm("SECURITY REALM") .buildAuthFilter()));
  14. Integration testing public class IntegrationTest { @ClassRule public static final

    DropwizardAppRule<DWGettingStartedConfiguration> RULE = new DropwizardAppRule<>(DWGettingStartedApplication.class, "config.yml"); @Test public void testGetGreeting() { String actual = client .target("http://localhost:8080/secured_hello") .request(MediaType.TEXT_PLAIN) .get(String.class); assertEquals(expected, actual);
  15. Connect to DB (Hibernate) • Create JPA @Entity(s) (and JPQL

    queries); • Class io.dropwizard.hibernate.AbstractDAO • Methods: ◦ Query namedQuery(String queryName); ◦ E uniqueResult(Query query); ◦ List<E> list(Query query); ◦ E get(Serializable id); ◦ E persist(E entity); ◦ Overloaded for Criteria.
  16. Create your DAOs public class EmployeeDAO extends AbstractDAO<Employee> { public

    List<Employee> findAll() { return list(namedQuery("Employee.findAll")); } ….
  17. Boilerplate • Add Hibernate module and DB driver to pom.xml;

    • Create and register Hibernate bundle in the Application class; Pass comma-separated list of entity classes; • Create DAOs in the Application class; • Pass them to the resource classes; • More in the code of the example applications.
  18. Use DAOs in Resource Classes @GET @Path("/{id}") @UnitOfWork public Optional<Employee>

    findById(@PathParam("id") LongParam id) { return employeeDAO.findById(id.get()); }
  19. Database Migrations • Liquibase included; • FlyWay possible as a

    third-party module; • Necessary to add migrations module to the pom.xml file; • Necessary to create and register migrations bundle in the Application class; • Can be used by supplying arguments to the jar file; • For development purposes it’s better to add migrations Maven plugin.
  20. Database Migrations (Liquibase) <changeSet id="2" author="javaeeeee"> <comment>A script to create

    a bookmarks table</comment> <createTable tableName="bookmarks"> <column name="id" type="bigint" autoIncrement="true"> <constraints primaryKey="true" nullable="false"/> </column> <column name="url" type="varchar(1024)" > <constraints nullable="false"/> </column>
  21. More in the example projects • Testing resources using Mockito;

    • Testing DAOs using an in-memory DB; • Enabling HTTPS; • Integration testing of password protected resources and HTTPS; • Authentication using DB; • Password encryption.
  22. Not covered and TODOs... • Authorization; • Metrics; • Dependency

    Injection Frameworks; • HTML Representations; • LDAP Authentication.
  23. Conclusion and Thanks The bottom line is that DropWizard is

    a production-ready framework which relies on well-known to Java EE developers parts and offer some goodies that can expedite REST API development and testing. Thank you for listening! :)