Create a Dropwizard configuration class. This is used to store any meta-information or resource information that your application will need during runtime, such as DB connection, Jetty server, logging, and metrics configurations. These configurations are ideally stored in a YAML file, which will then be mapped to your Configuration
class using Jackson. In this application, we are not going to use the YAML configuration as it is out of scope for this book.
Let's create an empty Configuration
class called GeoLocationConfiguration.java
:
package com.packt.microservices.geolocation;
import io.dropwizard.Configuration;
public class GeoLocationConfiguration extends Configuration {
}
The YAML configuration file has a lot to offer. Take a look at a sample YAML file from Dropwizard's Getting Started documentation page to learn more. The name of the YAML file is usually derived from the name of your microservice. The microservice name is usually identified by the return value of the overridden method public String getName()
in your Application
class. Now let's create the GeoLocationApplication.java
application class:
package com.packt.microservices.geolocation;
import io.dropwizard.Application;
import io.dropwizard.setup.Environment;
public class GeoLocationApplication extends
Application<GeoLocationConfiguration> {
public static void main(String[] args) throws Exception {
new GeoLocationApplication().run(args);
}
@Override
public void run(GeoLocationConfiguration config, Environment
env) throws Exception {
env.jersey().register(new GeoLocationResource());
}
}
There are a lot of things going on here. Let's look at them one by one. Firstly, this class extends Application
with the GeoLocationConfiguration
generic. This clearly makes an instance of your GeoLocationConfiguraiton.java
class available so that you have access to all the properties you have defined in your YAML
file at the same time mapped in the Configuration
class. The next one is the run
method. The run
method takes two arguments: your configuration
and environment
. The Environment
instance is a wrapper to other library-specific objects such as MetricsRegistry
, HealthCheckRegistry
, and JerseyEnvironment
. For example, we could register our Jersey resources using the JerseyEnvironment
instance. The env.jersey().register(new GeoLocationResource())
line does exactly that. The main
method is pretty straight-forward. All it does is call the run
method.
Before we can start the microservice, we have to configure this project to create a runnable uber JAR. Uber JARs are just fat JARs that bundle their dependencies in themselves. For this purpose, we will be using the maven-shade-plugin
. Add the following snippet to the build
section of the pom.xml
file. If this is your first plugin, you might want to wrap it in a <plugins>
element under <build>
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.packt.microservices.geolocation.GeoLocationApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
The previous snippet does the following:
It creates a runnable uber JAR that has a reduced pom.xml
file that does not include the dependencies that are added to the uber JAR. To learn more about this property, take a look at the documentation of maven-shade-plugin
.
It utilizes com.packt.microservices.geolocation.GeoLocationApplication
as the class whose main
method will be invoked when this JAR is executed. This is done by updating the MANIFEST
file.
It excludes all signatures from signed JARs. This is required to avoid security errors.
Now that our project is properly configured, let's try to build and run it from the command line. To build the project, execute mvn clean package
from the project's root directory in your terminal. This will create your final JAR in the target directory. Execute the following command to start your microservice:
java -jar target/geolocation-dropwizard-0.0.1-SNAPSHOT.jar server
The server
argument instructs Dropwizard to start the Jetty server. After you issue the command, you should be able to see that Dropwizard has started the in-memory Jetty server on port 8080. If you see any warnings about health checks, ignore them. Your console logs should look something like this:
We are now ready to test our application. Let's try to create two geolocations using the POST
API and later try to retrieve them using the GET
method. Execute the following cURL commands in your terminal one by one:
curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 41.803488, "longitude": -88.144040}' http://localhost:8080/geolocation
This should give you an output similar to the following (pretty-printed for readability):
{
"latitude": 41.803488,
"longitude": -88.14404,
"userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
"timestamp": 1468203975
}
curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 9.568012, "longitude": 77.962444}' http://localhost:8080/geolocation
This should give you an output like this (pretty-printed for readability):
{
"latitude": 9.568012,
"longitude": 77.962444,
"userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
"timestamp": 1468203975
}
To verify whether your entities were stored correctly, execute the following cURL command:
curl http://localhost:8080/geolocation
It should give you an output similar to the following (pretty-printed for readability):
[
{
"latitude": 41.803488,
"longitude": -88.14404,
"userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
"timestamp": 1468203975
},
{
"latitude": 9.568012,
"longitude": 77.962444,
"userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
"timestamp": 1468203975
}
]